* Re: [PATCH] PnP BIOS -- bugfix; update devlist on setpnp
@ 2001-10-17 3:14 Thomas Hood
2001-10-17 8:10 ` Steven A. DuChene
0 siblings, 1 reply; 14+ messages in thread
From: Thomas Hood @ 2001-10-17 3:14 UTC (permalink / raw)
To: linux-kernel; +Cc: sduchene
> Thomas:
> Just to let you know I still have the same problem with a resource
> conflict between the PnPBIOS code and the i2c/lm_sensors stuff at
> 1040 with this latest patch.
Yep, I know. I haven't addressed this bug in any of the
patches I've submitted to l-k. I'd like to fix it, but
I don't know how yet: I have only a partial understanding of
how resource allocation works.
Thanks for testing yesterday's PnP BIOS patch.
--
Thomas
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH] PnP BIOS -- bugfix; update devlist on setpnp
2001-10-17 3:14 [PATCH] PnP BIOS -- bugfix; update devlist on setpnp Thomas Hood
@ 2001-10-17 8:10 ` Steven A. DuChene
2001-10-17 13:35 ` Thomas Hood
2001-10-17 16:04 ` Gunther Mayer
0 siblings, 2 replies; 14+ messages in thread
From: Steven A. DuChene @ 2001-10-17 8:10 UTC (permalink / raw)
To: Thomas Hood; +Cc: linux-kernel, sduchene
OK, I tried this with the Intel STL2 motherboard I also have and I got
a similar error when trying to load the correct i2c bus module when the
PnPBIOS stuff is compiled into the kernel.
modprobe i2c-piix4
/lib/modules/2.4.10-ac12pnp/kernel/drivers/i2c/i2c-piix4.o: init_module: No such device
Hint: insmod errors can be caused by incorrect module parameters, including invalid IO or IRQ parameters
/lib/modules/2.4.10-ac12pnp/kernel/drivers/i2c/i2c-piix4.o: insmod /lib/modules/2.4.10-ac12pnp/kernel/drivers/i2c/i2c-piix4.o failed
/lib/modules/2.4.10-ac12pnp/kernel/drivers/i2c/i2c-piix4.o: insmod i2c-piix4 failed
dmesg
.
.
.
i2c-piix4.o version 2.6.1 (20010830)
i2c-piix4.o: Found OSB4 device
i2c-piix4.o: SMB region 0x580 already in use!
i2c-piix4.o: Device not detected, module not inserted.
cat /proc/ioports
.
.
.
04d0-04d1 : PnPBIOS PNP0c02
0580-058f : PnPBIOS PNP0c02
0840-084f : ServerWorks OSB4 IDE Controller
0840-0847 : ide0
0848-084f : ide1
0cd6-0cd7 : PnPBIOS PNP0c02
0cf8-0cff : PCI conf1
5000-50ff : ATI Technologies Inc 3D Rage IIC 215IIC [Mach64 GT IIC]
5400-543f : Intel Corporation 82557 [Ethernet Pro 100]
5400-543f : eepro100
5440-547f : Intel Corporation 82557 [Ethernet Pro 100] (#2)
5440-547f : eepro100
5800-58ff : Adaptec 7899P
6000-60ff : Adaptec 7899P (#2)
fe00-fe3f : PnPBIOS PNP0c02
So this is a problem on more than just those old Intel Lancewood L440GX
motherboards. The STL2 is a fairly recent dual processor motherboard
--
Steven A. DuChene sad@ale.org
linux-clusters@mindspring.com
sduchene@mindspring.com
http://www.mindspring.com/~sduchene/
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH] PnP BIOS -- bugfix; update devlist on setpnp
2001-10-17 8:10 ` Steven A. DuChene
@ 2001-10-17 13:35 ` Thomas Hood
2001-10-17 16:08 ` Steven A. DuChene
2001-10-17 16:04 ` Gunther Mayer
1 sibling, 1 reply; 14+ messages in thread
From: Thomas Hood @ 2001-10-17 13:35 UTC (permalink / raw)
To: Steven A. DuChene; +Cc: linux-kernel
On Wed, 2001-10-17 at 04:10, Steven A. DuChene wrote:
> OK, I tried this with the Intel STL2 motherboard I also have and I got
> a similar error when trying to load the correct i2c bus module when the
> PnPBIOS stuff is compiled into the kernel.
Understood.
I'd just like to reiterate that my patch isn't the cause
of your problem. It's just that my patch doesn't address
your problem. IIUC.
I provided a "workaround patch" before. Can you continue
to use that for the time being?
I'd like to make a promise that I'll submit a new patch
soon that will address your problem; however I don't yet know
exactly how to go about addressing it.
--
Thomas
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH] PnP BIOS -- bugfix; update devlist on setpnp
2001-10-17 13:35 ` Thomas Hood
@ 2001-10-17 16:08 ` Steven A. DuChene
0 siblings, 0 replies; 14+ messages in thread
From: Steven A. DuChene @ 2001-10-17 16:08 UTC (permalink / raw)
To: Thomas Hood; +Cc: Steven A. DuChene, linux-kernel
On Wed, Oct 17, 2001 at 09:35:34AM -0400, Thomas Hood wrote:
> On Wed, 2001-10-17 at 04:10, Steven A. DuChene wrote:
> > OK, I tried this with the Intel STL2 motherboard I also have and I got
> > a similar error when trying to load the correct i2c bus module when the
> > PnPBIOS stuff is compiled into the kernel.
>
> Understood.
>
> I'd just like to reiterate that my patch isn't the cause
> of your problem. It's just that my patch doesn't address
> your problem. IIUC.
Yes, I understood that from the start of all of this but you seemed to be
be the only person messing with the PnPBIOS code so I thought you might be
interested in this annomoly. I appreciate the info/help you have provided
so far.
>
> I provided a "workaround patch" before. Can you continue
> to use that for the time being?
>
Yes, but according to these latest results that work around of skipping a
particular ioport would have to be different for each motherboard with this
problem. There must be a better way to do this.
> I'd like to make a promise that I'll submit a new patch
> soon that will address your problem; however I don't yet know
> exactly how to go about addressing it.
>
Perhaps someone else can provide us a hint or two as to where to start. :-)
--
Steven A. DuChene sad@ale.org
linux-clusters@mindspring.com
sduchene@mindspring.com
http://www.mindspring.com/~sduchene/
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH] PnP BIOS -- bugfix; update devlist on setpnp
2001-10-17 8:10 ` Steven A. DuChene
2001-10-17 13:35 ` Thomas Hood
@ 2001-10-17 16:04 ` Gunther Mayer
2001-10-17 20:58 ` Thomas Hood
1 sibling, 1 reply; 14+ messages in thread
From: Gunther Mayer @ 2001-10-17 16:04 UTC (permalink / raw)
To: Steven A. DuChene; +Cc: Thomas Hood, linux-kernel
"Steven A. DuChene" wrote:
>
> OK, I tried this with the Intel STL2 motherboard I also have and I got
> a similar error when trying to load the correct i2c bus module when the
> PnPBIOS stuff is compiled into the kernel.
>
> modprobe i2c-piix4
> /lib/modules/2.4.10-ac12pnp/kernel/drivers/i2c/i2c-piix4.o: init_module: No such device
> Hint: insmod errors can be caused by incorrect module parameters, including invalid IO or IRQ >parameters
i2c-piix4 has to be taught to ignore PNP0c0x reservations.
PNP0C02 means "mainboard resource" and obviously i2c-piix4
would like to use it, so it should make use of it's knowledge.
As "mainboard resouce" is very generic we must reserve it
to protect against mapping other addresses over it.
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH] PnP BIOS -- bugfix; update devlist on setpnp
2001-10-17 16:04 ` Gunther Mayer
@ 2001-10-17 20:58 ` Thomas Hood
0 siblings, 0 replies; 14+ messages in thread
From: Thomas Hood @ 2001-10-17 20:58 UTC (permalink / raw)
To: Gunther Mayer; +Cc: Steven A. DuChene, linux-kernel
On Wed, 2001-10-17 at 12:04, Gunther Mayer wrote:
> i2c-piix4 has to be taught to ignore PNP0c0x reservations.
>
> PNP0C02 means "mainboard resource" and obviously i2c-piix4
> would like to use it, so it should make use of it's knowledge.
>
> As "mainboard resouce" is very generic we must reserve it
> to protect against mapping other addresses over it.
Your approach would work. But ...
Alan has said that the thing to do is mark these resources
as extant but unused. I presume one does this by calling
request_resource with appropriate flags [un]set.
Thomas
^ permalink raw reply [flat|nested] 14+ messages in thread
* [PATCH] PnP BIOS -- bugfix; update devlist on setpnp
@ 2001-10-13 15:40 Thomas Hood
2001-10-15 6:37 ` Jurgen Botz
` (2 more replies)
0 siblings, 3 replies; 14+ messages in thread
From: Thomas Hood @ 2001-10-13 15:40 UTC (permalink / raw)
To: linux-kernel; +Cc: stelian.pop, ion, sduchene, jurgen
Okay, here's a new major patch to the PnP BIOS driver
which needs some testing before it's integrated.
Applies against 2.4.10-ac12, perhaps also against 2.4.11-ac1,
though I haven't tried.
Please test and let me know whether there are any problems.
Vaio users: Please make sure that this doesn't oops.
Others: Try using setpnp to change the current configuration.
Unload and reload the parport drivers to check that they
reinitialize with the updated resource information provided
by the PnP BIOS driver.
1) Fix bugs in resource reservation:
- end of reserved range too large by 1
- didn't reserve all system board resources
2) Change code so that set_dev_node updates the devlist, so
drivers loaded after a setpnp will get up-to-date resource
information. Because I haven't protected devlist update
code with locks, this feature isn't SMP safe yet. I'd like
some advice about how to do the locking. If you're worried,
don't use setpnp.
3) Miscellaneous code cleanups. Use "pnpbios" more consistently.
Improve printk output. Etc.
The patch:
--- linux-2.4.10-ac12/init/main.c Wed Oct 10 22:09:58 2001
+++ linux-2.4.10-ac12-fix/init/main.c Fri Oct 12 22:41:30 2001
@@ -824,7 +824,7 @@
isapnp_init();
#endif
#ifdef CONFIG_PNPBIOS
- pnp_bios_init();
+ pnpbios_init();
#endif
#ifdef CONFIG_TC
--- linux-2.4.10-ac12/include/linux/pnp_bios.h Wed Oct 10 22:09:57 2001
+++ linux-2.4.10-ac12-fix/include/linux/pnp_bios.h Sat Oct 13 09:57:24 2001
@@ -132,30 +132,35 @@
return (struct pnpbios_driver *)dev->driver;
}
-extern void pnp_bios_init (void);
-extern int pnp_bios_dev_node_info (struct pnp_dev_node_info *data);
-extern int pnp_bios_get_dev_node (u8 *nodenum, char config, struct pnp_bios_node *data);
-extern int pnp_bios_set_dev_node (u8 nodenum, char config, struct pnp_bios_node *data);
-extern int pnp_bios_get_event (u16 *message);
-extern int pnp_bios_send_message (u16 message);
-extern int pnp_bios_set_stat_res (char *info);
-extern int pnp_bios_get_stat_res (char *info);
-extern int pnp_bios_apm_id_table (char *table, u16 *size);
-extern int pnp_bios_isapnp_config (struct pnp_isa_config_struc *data);
-extern int pnp_bios_escd_info (struct escd_info_struc *data);
-extern int pnp_bios_read_escd (char *data, u32 nvram_base);
-extern int pnp_bios_write_escd (char *data, u32 nvram_base);
-
-extern void pnp_proc_init ( int dont_use_current );
-
#ifdef CONFIG_PNPBIOS
#define pnpbios_for_each_dev(dev) \
for(dev = pnpbios_dev_g(pnpbios_devices.next); dev != pnpbios_dev_g(&pnpbios_devices); dev = pnpbios_dev_g(dev->global_list.next))
-extern int pnp_bios_present (void);
+
+
+extern int pnpbios_dont_use_current_config;
+void *pnpbios_kmalloc(size_t size, int f);
+extern void pnpbios_init (void);
+extern void pnpbios_proc_init (void);
+
extern struct pci_dev *pnpbios_find_device(char *pnpid, struct pci_dev *dev);
-extern int pnpbios_register_driver(struct pnpbios_driver *drv);
+extern int pnpbios_register_driver(struct pnpbios_driver *drv);
extern void pnpbios_unregister_driver(struct pnpbios_driver *drv);
+extern int pnpbios_dev_node_info (struct pnp_dev_node_info *data);
+extern int pnpbios_get_dev_node (u8 *nodenum, char config, struct pnp_bios_node *data);
+extern int pnpbios_set_dev_node (u8 nodenum, char config, struct pnp_bios_node *data);
+#if needed
+extern int pnpbios_get_event (u16 *message);
+extern int pnpbios_send_message (u16 message);
+extern int pnpbios_set_stat_res (char *info);
+extern int pnpbios_get_stat_res (char *info);
+extern int pnpbios_apm_id_table (char *table, u16 *size);
+extern int pnpbios_isapnp_config (struct pnp_isa_config_struc *data);
+extern int pnpbios_escd_info (struct escd_info_struc *data);
+extern int pnpbios_read_escd (char *data, u32 nvram_base);
+extern int pnpbios_write_escd (char *data, u32 nvram_base);
+#endif
+
/*
* a helper function which helps ensure correct pnpbios_driver
* setup and cleanup for commonly-encountered hotplug/modular cases
@@ -189,24 +194,14 @@
return rc;
}
-#else
+#else /* CONFIG_PNPBIOS */
#define pnpbios_for_each_dev(dev) for(dev = NULL; 0; )
-static __inline__ int pnp_bios_present (void)
-{
- return 0;
-}
-
static __inline__ struct pci_dev *pnpbios_find_device(char *pnpid, struct pci_dev *dev)
{
return NULL;
}
-static __inline__ int pnpbios_module_init(struct pnpbios_driver *drv)
-{
- return -ENODEV;
-}
-
static __inline__ int pnpbios_register_driver(struct pnpbios_driver *drv)
{
return 0;
@@ -217,7 +212,12 @@
return;
}
-#endif
+static __inline__ int pnpbios_module_init(struct pnpbios_driver *drv)
+{
+ return -ENODEV;
+}
+
+#endif /* CONFIG_PNPBIOS */
#endif /* __KERNEL__ */
#endif /* _LINUX_PNP_BIOS_H */
--- linux-2.4.10-ac12/drivers/pnp/pnp_bios.c Wed Oct 10 22:09:19 2001
+++ linux-2.4.10-ac12-fix/drivers/pnp/pnp_bios.c Sat Oct 13 11:27:45 2001
@@ -50,11 +50,17 @@
#define PNP_SIGNATURE (('$' << 0) + ('P' << 8) + ('n' << 16) + ('P' << 24))
/*
+ * Forward declarations
+ */
+
+static void pnpbios_update_devlist( u8 nodenum, struct pnp_bios_node *data );
+
+/*
* This is the standard structure used to identify the entry point
* to the Plug and Play bios
*/
#pragma pack(1)
-union pnpbios {
+union pnp_bios_expansion_header {
struct {
u32 signature; /* "$PnP" */
u8 version; /* in BCD */
@@ -83,7 +89,7 @@
u16 segment;
} pnp_bios_callpoint;
-static union pnpbios * pnp_bios_inst_struc = NULL;
+static union pnp_bios_expansion_header * pnp_bios_hdr = NULL;
/* The PnP entries in the GDT */
#define PNP_GDT 0x0060
@@ -214,12 +220,16 @@
printk(KERN_ERR "PnPBIOS: Check with your vendor for an updated BIOS\n");
}
-// if ( status ) printk(KERN_WARNING "PnPBIOS: BIOS returned error 0x%x from function 0x%x.\n", status, func);
-
return status;
}
-static void *pnp_bios_kmalloc(size_t size, int f)
+/*
+ *
+ * UTILITY FUNCTIONS
+ *
+ */
+
+void *pnpbios_kmalloc(size_t size, int f)
{
void *p = kmalloc( size, f );
if ( p == NULL )
@@ -228,18 +238,29 @@
}
/*
+ * Call this only after init time
+ */
+static int pnp_bios_is_present(void)
+{
+ return (pnp_bios_hdr != NULL);
+}
+
+/*
*
* PnP BIOS ACCESS FUNCTIONS
*
+ * pnp_bios_* are local functions used to call the BIOS
+ * pnpbios_* are the public interface to these functions
+ *
*/
/*
* Call PnP BIOS with function 0x00, "get number of system device nodes"
*/
-static int pnp_bios_dev_node_info_silently(struct pnp_dev_node_info *data)
+static int pnp_bios_dev_node_info(struct pnp_dev_node_info *data)
{
u16 status;
- if (!pnp_bios_present ())
+ if (!pnp_bios_is_present ())
return PNP_FUNCTION_NOT_SUPPORTED;
Q2_SET_SEL(PNP_TS1, data, sizeof(struct pnp_dev_node_info));
status = call_pnp_bios(PNP_GET_NUM_SYS_DEV_NODES, 0, PNP_TS1, 2, PNP_TS1, PNP_DS, 0, 0);
@@ -247,11 +268,11 @@
return status;
}
-int pnp_bios_dev_node_info(struct pnp_dev_node_info *data)
+int pnpbios_dev_node_info(struct pnp_dev_node_info *data)
{
- u16 status = pnp_bios_dev_node_info_silently( data );
+ int status = pnp_bios_dev_node_info( data );
if ( status )
- printk(KERN_WARNING "PnPBIOS: PnP BIOS dev_node_info function returned error status 0x%x\n", status);
+ printk(KERN_WARNING "PnPBIOS: dev_node_info: Unexpected status 0x%x\n", status);
return status;
}
@@ -269,22 +290,25 @@
* or volatile current (0) config
* Output: *nodenum=next node or 0xff if no more nodes
*/
-static int pnp_bios_get_dev_node_silently(u8 *nodenum, char boot, struct pnp_bios_node *data)
+static int pnp_bios_get_dev_node(u8 *nodenum, char boot, struct pnp_bios_node *data)
{
u16 status;
- if (!pnp_bios_present ())
- return PNP_FUNCTION_NOT_SUPPORTED;
Q2_SET_SEL(PNP_TS1, nodenum, sizeof(char));
Q2_SET_SEL(PNP_TS2, data, 64 * 1024);
status = call_pnp_bios(PNP_GET_SYS_DEV_NODE, 0, PNP_TS1, 0, PNP_TS2, boot ? 2 : 1, PNP_DS, 0);
return status;
}
-int pnp_bios_get_dev_node(u8 *nodenum, char boot, struct pnp_bios_node *data)
+int pnpbios_get_dev_node(u8 *nodenum, char boot, struct pnp_bios_node *data)
{
- u16 status = pnp_bios_get_dev_node_silently( nodenum, boot, data );
+ int status;
+ if (!pnp_bios_is_present ())
+ return PNP_FUNCTION_NOT_SUPPORTED;
+ if ( !boot & pnpbios_dont_use_current_config )
+ return PNP_FUNCTION_NOT_SUPPORTED;
+ status = pnp_bios_get_dev_node( nodenum, boot, data );
if ( status )
- printk(KERN_WARNING "PnPBIOS: PnP BIOS get_dev_node function returned error status 0x%x\n", status);
+ printk(KERN_WARNING "PnPBIOS: get_dev_node: Unexpected 0x%x\n", status);
return status;
}
@@ -294,21 +318,35 @@
* boot = whether to set nonvolatile boot (!=0)
* or volatile current (0) config
*/
-static int pnp_bios_set_dev_node_silently(u8 nodenum, char boot, struct pnp_bios_node *data)
+static int pnp_bios_set_dev_node(u8 nodenum, char boot, struct pnp_bios_node *data)
{
u16 status;
- if (!pnp_bios_present ())
- return PNP_FUNCTION_NOT_SUPPORTED;
Q2_SET_SEL(PNP_TS1, data, /* *((u16 *) data)*/ 65536);
status = call_pnp_bios(PNP_SET_SYS_DEV_NODE, nodenum, 0, PNP_TS1, boot ? 2 : 1, PNP_DS, 0, 0);
return status;
}
-int pnp_bios_set_dev_node(u8 nodenum, char boot, struct pnp_bios_node *data)
+int pnpbios_set_dev_node(u8 nodenum, char boot, struct pnp_bios_node *data)
{
- u16 status = pnp_bios_set_dev_node_silently( nodenum, boot, data );
- if ( status )
- printk(KERN_WARNING "PnPBIOS: PnP BIOS set_dev_node function returned error status 0x%x\n", status);
+ int status;
+ if (!pnp_bios_is_present ())
+ return PNP_FUNCTION_NOT_SUPPORTED;
+ if ( !boot & pnpbios_dont_use_current_config )
+ return PNP_FUNCTION_NOT_SUPPORTED;
+ status = pnp_bios_set_dev_node( nodenum, boot, data );
+ if ( status ) {
+ printk(KERN_WARNING "PnPBIOS: set_dev_node: Unexpected set_dev_node status 0x%x\n", status);
+ return status;
+ }
+ if ( !boot ) { /* Update devlist */
+ u8 thisnodenum = nodenum;
+ status = pnp_bios_get_dev_node( &nodenum, boot, data );
+ if ( status ) {
+ printk(KERN_WARNING "PnPBIOS: set_dev_node: Unexpected get_dev_node status 0x%x\n", status);
+ return status;
+ }
+ pnpbios_update_devlist( thisnodenum, data );
+ }
return status;
}
@@ -319,7 +357,7 @@
static int pnp_bios_get_event(u16 *event)
{
u16 status;
- if (!pnp_bios_present ())
+ if (!pnp_bios_is_present ())
return PNP_FUNCTION_NOT_SUPPORTED;
Q2_SET_SEL(PNP_TS1, event, sizeof(u16));
status = call_pnp_bios(PNP_GET_EVENT, 0, PNP_TS1, PNP_DS, 0, 0 ,0 ,0);
@@ -334,7 +372,7 @@
static int pnp_bios_send_message(u16 message)
{
u16 status;
- if (!pnp_bios_present ())
+ if (!pnp_bios_is_present ())
return PNP_FUNCTION_NOT_SUPPORTED;
status = call_pnp_bios(PNP_SEND_MESSAGE, message, PNP_DS, 0, 0, 0, 0, 0);
return status;
@@ -348,7 +386,7 @@
static int pnp_bios_dock_station_info(struct pnp_docking_station_info *data)
{
u16 status;
- if (!pnp_bios_present ())
+ if (!pnp_bios_is_present ())
return PNP_FUNCTION_NOT_SUPPORTED;
Q2_SET_SEL(PNP_TS1, data, sizeof(struct pnp_docking_station_info));
status = call_pnp_bios(PNP_GET_DOCKING_STATION_INFORMATION, 0, PNP_TS1, PNP_DS, 0, 0, 0, 0);
@@ -364,7 +402,7 @@
static int pnp_bios_set_stat_res(char *info)
{
u16 status;
- if (!pnp_bios_present ())
+ if (!pnp_bios_is_present ())
return PNP_FUNCTION_NOT_SUPPORTED;
Q2_SET_SEL(PNP_TS1, info, *((u16 *) info));
status = call_pnp_bios(PNP_SET_STATIC_ALLOCED_RES_INFO, 0, PNP_TS1, PNP_DS, 0, 0, 0, 0);
@@ -380,7 +418,7 @@
static int pnp_bios_get_stat_res(char *info)
{
u16 status;
- if (!pnp_bios_present ())
+ if (!pnp_bios_is_present ())
return PNP_FUNCTION_NOT_SUPPORTED;
Q2_SET_SEL(PNP_TS1, info, 64 * 1024);
status = call_pnp_bios(PNP_GET_STATIC_ALLOCED_RES_INFO, 0, PNP_TS1, PNP_DS, 0, 0, 0, 0);
@@ -395,7 +433,7 @@
static int pnp_bios_apm_id_table(char *table, u16 *size)
{
u16 status;
- if (!pnp_bios_present ())
+ if (!pnp_bios_is_present ())
return PNP_FUNCTION_NOT_SUPPORTED;
Q2_SET_SEL(PNP_TS1, table, *size);
Q2_SET_SEL(PNP_TS2, size, sizeof(u16));
@@ -411,7 +449,7 @@
static int pnp_bios_isapnp_config(struct pnp_isa_config_struc *data)
{
u16 status;
- if (!pnp_bios_present ())
+ if (!pnp_bios_is_present ())
return PNP_FUNCTION_NOT_SUPPORTED;
Q2_SET_SEL(PNP_TS1, data, sizeof(struct pnp_isa_config_struc));
status = call_pnp_bios(PNP_GET_PNP_ISA_CONFIG_STRUC, 0, PNP_TS1, PNP_DS, 0, 0, 0, 0);
@@ -426,7 +464,7 @@
static int pnp_bios_escd_info(struct escd_info_struc *data)
{
u16 status;
- if (!pnp_bios_present ())
+ if (!pnp_bios_is_present ())
return ESCD_FUNCTION_NOT_SUPPORTED;
Q2_SET_SEL(PNP_TS1, data, sizeof(struct escd_info_struc));
status = call_pnp_bios(PNP_GET_ESCD_INFO, 0, PNP_TS1, 2, PNP_TS1, 4, PNP_TS1, PNP_DS);
@@ -442,7 +480,7 @@
static int pnp_bios_read_escd(char *data, u32 nvram_base)
{
u16 status;
- if (!pnp_bios_present ())
+ if (!pnp_bios_is_present ())
return ESCD_FUNCTION_NOT_SUPPORTED;
Q2_SET_SEL(PNP_TS1, data, 64 * 1024);
set_base(gdt[PNP_TS2 >> 3], nvram_base);
@@ -459,7 +497,7 @@
static int pnp_bios_write_escd(char *data, u32 nvram_base)
{
u16 status;
- if (!pnp_bios_present ())
+ if (!pnp_bios_is_present ())
return ESCD_FUNCTION_NOT_SUPPORTED;
Q2_SET_SEL(PNP_TS1, data, 64 * 1024);
set_base(gdt[PNP_TS2 >> 3], nvram_base);
@@ -469,10 +507,6 @@
}
#endif
-EXPORT_SYMBOL(pnp_bios_dev_node_info);
-EXPORT_SYMBOL(pnp_bios_get_dev_node);
-EXPORT_SYMBOL(pnp_bios_set_dev_node);
-
/*
*
* PnP DOCKING FUNCTIONS
@@ -482,7 +516,6 @@
#ifdef CONFIG_HOTPLUG
static int unloading = 0;
-
static struct completion unload_sem;
/*
@@ -499,10 +532,10 @@
if (!current->fs->root) {
return -EAGAIN;
}
- if (!(envp = (char **) pnp_bios_kmalloc (20 * sizeof (char *), GFP_KERNEL))) {
+ if (!(envp = (char **) pnpbios_kmalloc (20 * sizeof (char *), GFP_KERNEL))) {
return -ENOMEM;
}
- if (!(buf = pnp_bios_kmalloc (256, GFP_KERNEL))) {
+ if (!(buf = pnpbios_kmalloc (256, GFP_KERNEL))) {
kfree (envp);
return -ENOMEM;
}
@@ -579,7 +612,7 @@
d = 1;
break;
default:
- printk(KERN_WARNING "PnPBIOS: Unexpected error 0x%x returned by BIOS.\n", err);
+ printk(KERN_WARNING "PnPBIOS: pnp_dock_thread: Unexpected status 0x%x returned by BIOS.\n", err);
continue;
}
if(d != docked)
@@ -587,7 +620,9 @@
if(pnp_dock_event(d, &now)==0)
{
docked = d;
-// printk(KERN_INFO "PnPBIOS: Docking station %stached.\n", docked?"at":"de");
+#if 0
+ printk(KERN_INFO "PnPBIOS: Docking station %stached.\n", docked?"at":"de");
+#endif
}
}
}
@@ -598,147 +633,62 @@
/*
*
- * NODE DATA HANDLING FUNCTIONS
+ * NODE DATA PARSING FUNCTIONS
*
*/
-static void inline pnpbios_add_irqresource(struct pci_dev *dev, int irq)
+static void pnpbios_add_irqresource(struct pci_dev *dev, int irq)
{
- // Permit irq==-1 which signifies "disabled"
int i = 0;
while (!(dev->irq_resource[i].flags & IORESOURCE_UNSET) && i < DEVICE_COUNT_IRQ) i++;
if (i < DEVICE_COUNT_IRQ) {
- dev->irq_resource[i].start = irq;
+ dev->irq_resource[i].start = (unsigned long) irq;
dev->irq_resource[i].flags = IORESOURCE_IRQ; // Also clears _UNSET flag
}
}
-static void inline pnpbios_add_dmaresource(struct pci_dev *dev, int dma)
+static void pnpbios_add_dmaresource(struct pci_dev *dev, int dma)
{
- // Permit dma==-1 which signifies "disabled"
int i = 0;
while (!(dev->dma_resource[i].flags & IORESOURCE_UNSET) && i < DEVICE_COUNT_DMA) i++;
if (i < DEVICE_COUNT_DMA) {
- dev->dma_resource[i].start = dma;
+ dev->dma_resource[i].start = (unsigned long) dma;
dev->dma_resource[i].flags = IORESOURCE_DMA; // Also clears _UNSET flag
}
}
-static void inline pnpbios_add_ioresource(struct pci_dev *dev, int io, int len)
+static void pnpbios_add_ioresource(struct pci_dev *dev, int io, int len)
{
int i = 0;
while (!(dev->resource[i].flags & IORESOURCE_UNSET) && i < DEVICE_COUNT_RESOURCE) i++;
if (i < DEVICE_COUNT_RESOURCE) {
- dev->resource[i].start = io;
- dev->resource[i].end = io + len;
+ dev->resource[i].start = (unsigned long) io;
+ dev->resource[i].end = (unsigned long)(io + len - 1);
dev->resource[i].flags = IORESOURCE_IO; // Also clears _UNSET flag
}
}
-static void inline pnpbios_add_memresource(struct pci_dev *dev, int mem, int len)
+static void pnpbios_add_memresource(struct pci_dev *dev, int mem, int len)
{
int i = 0;
while (!(dev->resource[i].flags & IORESOURCE_UNSET) && i < DEVICE_COUNT_RESOURCE) i++;
if (i < DEVICE_COUNT_RESOURCE) {
- dev->resource[i].start = mem;
- dev->resource[i].end = mem + len;
+ dev->resource[i].start = (unsigned long) mem;
+ dev->resource[i].end = (unsigned long)(mem + len - 1);
dev->resource[i].flags = IORESOURCE_MEM; // Also clears _UNSET flag
}
}
-/*
- * request I/O ports which are used according to the PnP BIOS
- * to avoid I/O conflicts.
- */
-static void mboard_request(char *pnpid, int io, int len)
-{
- struct resource *res;
- char *regionid;
-
- if (
- 0 != strcmp(pnpid,"PNP0c01") && /* memory controller */
- 0 != strcmp(pnpid,"PNP0c02") /* system peripheral: other */
- ) {
- return;
- }
-
- if (io < 0x100) {
- /*
- * Below 0x100 is only standard PC hardware
- * (pics, kbd, timer, dma, ...)
- *
- * We should not get resource conflicts there,
- * and the kernel reserves these anyway
- * (see arch/i386/kernel/setup.c).
- */
- return;
- }
-
- /*
- * Anything else we'll try reserve to avoid these ranges are
- * assigned to someone (CardBus bridges for example) and thus are
- * triggering resource conflicts.
- *
- * Failures at this point are usually harmless. pci quirks for
- * example do reserve stuff they know about too, so we might have
- * double reservations here.
- *
- * We really shouldn't just reserve these regions, though, since
- * that prevents the device drivers from claiming them.
- */
- regionid = pnp_bios_kmalloc(16, GFP_KERNEL);
- if ( regionid == NULL )
- return;
- sprintf(regionid, "PnPBIOS %s", pnpid);
- res = request_region(io,len,regionid);
- if ( res == NULL )
- kfree( regionid );
- printk(
- "PnPBIOS: %s: 0x%x-0x%x %s reserved\n",
- pnpid, io, io+len-1,
- NULL != res ? "has been" : "was already"
- );
-
- return;
-}
-
-
-#define HEX(id,a) hex[((id)>>a) & 15]
-#define CHAR(id,a) (0x40 + (((id)>>a) & 31))
-
-static char * __init pnpid32_to_pnpid(u32 id)
-{
- const char *hex = "0123456789abcdef";
- static char str[8];
- id = be32_to_cpu(id);
- str[0] = CHAR(id, 26);
- str[1] = CHAR(id, 21);
- str[2] = CHAR(id,16);
- str[3] = HEX(id, 12);
- str[4] = HEX(id, 8);
- str[5] = HEX(id, 4);
- str[6] = HEX(id, 0);
- str[7] = '\0';
- return str;
-}
-
-#undef CHAR
-#undef HEX
-
-/*
- * parse PNPBIOS "Allocated Resources Block" and fill IO,IRQ,DMA into pci_dev
- */
-static void __init pnpbios_rawdata_2_pci_dev(struct pnp_bios_node *node, struct pci_dev *dev)
+static void pnpbios_node_resource_data_to_dev(struct pnp_bios_node *node, struct pci_dev *dev)
{
unsigned char *p = node->data, *lastp=NULL;
int i;
/*
- * First, set dev contents to default values
+ * First, set resource info to default values
*/
- memset(dev,0,sizeof(struct pci_dev));
for (i=0;i<DEVICE_COUNT_RESOURCE;i++) {
- /* dev->resource[i].start = 0; */
+ dev->resource[i].start = 0; // "disabled"
dev->resource[i].flags = IORESOURCE_UNSET;
}
for (i=0;i<DEVICE_COUNT_IRQ;i++) {
@@ -751,7 +701,7 @@
}
/*
- * Fill in dev info
+ * Fill in dev resource info
*/
while ( (char *)p < ((char *)node->data + node->size )) {
if(p==lastp) break;
@@ -795,7 +745,7 @@
switch (p[0]>>3) {
case 0x04: // irq
{
- int i, mask, irq = -1; // "disabled"
+ int i, mask, irq = -1;
mask= p[1] + p[2]*256;
for (i=0;i<16;i++, mask=mask>>1)
if(mask & 0x01) irq=i;
@@ -804,7 +754,7 @@
}
case 0x05: // dma
{
- int i, mask, dma = -1; // "disabled"
+ int i, mask, dma = -1;
mask = p[1];
for (i=0;i<8;i++, mask = mask>>1)
if(mask & 0x01) dma=i;
@@ -816,7 +766,6 @@
int io= p[2] + p[3] *256;
int len = p[7];
pnpbios_add_ioresource(dev, io, len);
- mboard_request(pnpid32_to_pnpid(node->eisa_id),io,len);
break;
}
case 0x09: // fixed location io
@@ -843,42 +792,53 @@
static LIST_HEAD(pnpbios_devices);
-int pnp_bios_present(void)
-{
- return (pnp_bios_inst_struc != NULL);
-}
-
-EXPORT_SYMBOL(pnp_bios_present);
-
-static int __init pnpbios_insert_device(struct pci_dev *dev)
+static int inline pnpbios_insert_device(struct pci_dev *dev)
{
/* FIXME: Need to check for re-add of existing node */
list_add_tail(&dev->global_list, &pnpbios_devices);
return 0;
}
-/*
- * Build the list of pci_dev objects from the PnP table
- */
-
+#define HEX(id,a) hex[((id)>>a) & 15]
+#define CHAR(id,a) (0x40 + (((id)>>a) & 31))
+//
+static void inline pnpid32_to_pnpid(u32 id, char *str)
+{
+ const char *hex = "0123456789abcdef";
+
+ id = be32_to_cpu(id);
+ str[0] = CHAR(id, 26);
+ str[1] = CHAR(id, 21);
+ str[2] = CHAR(id,16);
+ str[3] = HEX(id, 12);
+ str[4] = HEX(id, 8);
+ str[5] = HEX(id, 4);
+ str[6] = HEX(id, 0);
+ str[7] = '\0';
+
+ return;
+}
+//
+#undef CHAR
+#undef HEX
+
static void __init pnpbios_build_devlist(void)
{
int i;
int nodenum;
int nodes_got = 0;
+ int devs = 0;
struct pnp_bios_node *node;
struct pnp_dev_node_info node_info;
struct pci_dev *dev;
- char *pnpid;
-
- if (!pnp_bios_present ())
+ if (!pnp_bios_is_present ())
return;
if (pnp_bios_dev_node_info(&node_info) != 0)
return;
- node = pnp_bios_kmalloc(node_info.max_node_size, GFP_KERNEL);
+ node = pnpbios_kmalloc(node_info.max_node_size, GFP_KERNEL);
if (!node)
return;
@@ -891,22 +851,45 @@
if (pnp_bios_get_dev_node((u8 *)&nodenum, (char )1 , node))
break;
nodes_got++;
- dev = pnp_bios_kmalloc(sizeof (struct pci_dev), GFP_KERNEL);
+ dev = pnpbios_kmalloc(sizeof (struct pci_dev), GFP_KERNEL);
if (!dev)
break;
- pnpbios_rawdata_2_pci_dev(node,dev);
+ memset(dev,0,sizeof(struct pci_dev));
dev->devfn=thisnodenum;
- pnpid = pnpid32_to_pnpid(node->eisa_id);
memcpy(dev->name,"PNPBIOS",8);
- memcpy(dev->slot_name,pnpid,8);
+ pnpid32_to_pnpid(node->eisa_id,dev->slot_name);
+ pnpbios_node_resource_data_to_dev(node,dev);
if(pnpbios_insert_device(dev)<0)
kfree(dev);
+ devs++;
}
kfree(node);
- printk(KERN_INFO "PnPBIOS: %i node%s reported by PnP BIOS\n", nodes_got, nodes_got != 1 ? "s" : "");
+ printk(KERN_INFO "PnPBIOS: %i node%s reported by PnP BIOS; %i recorded by driver.\n",
+ nodes_got, nodes_got != 1 ? "s" : "", devs);
}
+static struct pci_dev *pnpbios_find_device_by_nodenum( u8 nodenum )
+{
+ struct pci_dev *dev;
+
+ pnpbios_for_each_dev(dev) {
+ if(dev->devfn == nodenum)
+ return dev;
+ }
+
+ return NULL;
+}
+
+static void pnpbios_update_devlist( u8 nodenum, struct pnp_bios_node *data )
+{
+ struct pci_dev *dev = pnpbios_find_device_by_nodenum( nodenum );
+ if ( dev ) {
+ pnpbios_node_resource_data_to_dev(data,dev);
+ }
+
+ return;
+}
/*
*
@@ -920,22 +903,19 @@
struct pci_dev *pnpbios_find_device(char *pnpid, struct pci_dev *prev)
{
struct pci_dev *dev;
- int num;
-
- if(prev==NULL)
- num=0; /* Start from beginning */
- else
- num=prev->devfn + 1; /* Encode node number here */
+ int nodenum;
+ nodenum = 0;
+ if(prev)
+ nodenum=prev->devfn + 1; /* Encode node number here */
- pnpbios_for_each_dev(dev)
- {
- if(dev->devfn >= num)
- {
+ pnpbios_for_each_dev(dev) {
+ if(dev->devfn >= nodenum) {
if(memcmp(dev->slot_name, pnpid, 7)==0)
return dev;
}
}
+
return NULL;
}
@@ -1049,54 +1029,145 @@
EXPORT_SYMBOL(pnpbios_unregister_driver);
+/*
+ *
+ * RESOURCE RESERVATION FUNCTIONS
+ *
+ */
+
+static void __init pnpbios_reserve_resource_range(char *pnpid, int start, int end)
+{
+ struct resource *res;
+ char *regionid;
+
+ regionid = pnpbios_kmalloc(16, GFP_KERNEL);
+ if ( regionid == NULL )
+ return;
+ sprintf(regionid, "PnPBIOS %s", pnpid);
+ res = request_region(start,end-start+1,regionid);
+ if ( res == NULL )
+ kfree( regionid );
+ /*
+ * Failures at this point are usually harmless. pci quirks for
+ * example do reserve stuff they know about too, so we may well
+ * have double reservations.
+ */
+ printk(
+ "PnPBIOS: %s: 0x%x-0x%x %s reserved\n",
+ pnpid, start, end,
+ NULL != res ? "has been" : "was already"
+ );
+
+ return;
+}
+
+static void __init pnpbios_reserve_resources_of_dev( struct pci_dev *dev )
+{
+ int i;
+
+ for (i=0;i<DEVICE_COUNT_RESOURCE;i++) {
+ if ( dev->resource[i].flags & IORESOURCE_UNSET )
+ /* resource record not used */
+ break;
+ if ( dev->resource[i].start == 0 )
+ /* resource disabled */
+ continue;
+ if ( dev->resource[i].start < 0x100 )
+ /*
+ * Below 0x100 is only standard PC hardware
+ * (pics, kbd, timer, dma, ...)
+ *
+ * We should not get resource conflicts there,
+ * and the kernel reserves these anyway
+ * (see arch/i386/kernel/setup.c).
+ */
+ continue;
+ if ( dev->resource[i].end < dev->resource[i].start )
+ /* insane */
+ continue;
+ pnpbios_reserve_resource_range(
+ dev->slot_name,
+ dev->resource[i].start,
+ dev->resource[i].end
+ );
+ }
+
+ return;
+}
+
+/*
+ * Reserve resources used by system board devices
+ *
+ * We really shouldn't just _reserve_ these regions since
+ * that prevents the device drivers from claiming them.
+ */
+static void __init pnpbios_reserve_resources( void )
+{
+ struct pci_dev *dev;
+
+ pnpbios_for_each_dev(dev) {
+ if (
+ 0 != strcmp(dev->slot_name,"PNP0c01") && /* memory controller */
+ 0 != strcmp(dev->slot_name,"PNP0c02") /* system peripheral: other */
+ ) {
+ continue;
+ }
+ pnpbios_reserve_resources_of_dev(dev);
+ }
+
+ return;
+}
+
/*
*
* INIT AND EXIT
*
*
- * Search the defined area (0xf0000-0xffff0) for a valid PnP BIOS
- * structure and, if one is found, sets up the selectors and
- * entry points
*/
extern int is_sony_vaio_laptop;
-static int pnp_bios_disabled;
-static int pnp_bios_dont_use_current_config;
+static int pnpbios_disabled;
+int pnpbios_dont_use_current_config;
-static int disable_pnp_bios(char *str)
+static int __init pnpbios_disable_pnp_bios(char *str)
{
- pnp_bios_disabled=1;
+ pnpbios_disabled=1;
return 0;
}
-static int disable_use_of_current_config(char *str)
+static int __init pnpbios_disable_use_of_current_config(char *str)
{
- pnp_bios_dont_use_current_config=1;
+ pnpbios_dont_use_current_config=1;
return 0;
}
-__setup("nobiospnp", disable_pnp_bios);
-__setup("nobioscurrpnp", disable_use_of_current_config);
+__setup("nobiospnp", pnpbios_disable_pnp_bios);
+__setup("nobioscurrpnp", pnpbios_disable_use_of_current_config);
-void pnp_bios_init(void)
+void __init pnpbios_init(void)
{
- union pnpbios *check;
+ union pnp_bios_expansion_header *check;
u8 sum;
int i, length;
spin_lock_init(&pnp_bios_lock);
- if(pnp_bios_disabled) {
+ if(pnpbios_disabled) {
printk(KERN_INFO "PnPBIOS: Disabled.\n");
return;
}
if ( is_sony_vaio_laptop )
- pnp_bios_dont_use_current_config = 1;
+ pnpbios_dont_use_current_config = 1;
- for (check = (union pnpbios *) __va(0xf0000);
- check < (union pnpbios *) __va(0xffff0);
+ /*
+ * Search the defined area (0xf0000-0xffff0) for a valid PnP BIOS
+ * structure and, if one is found, sets up the selectors and
+ * entry points
+ */
+ for (check = (union pnp_bios_expansion_header *) __va(0xf0000);
+ check < (union pnp_bios_expansion_header *) __va(0xffff0);
((void *) (check)) += 16) {
if (check->fields.signature != PNP_SIGNATURE)
continue;
@@ -1123,12 +1194,14 @@
Q_SET_SEL(PNP_DS, check->fields.pm16dseg, 64 * 1024);
pnp_bios_callpoint.offset = check->fields.pm16offset;
pnp_bios_callpoint.segment = PNP_CS16;
- pnp_bios_inst_struc = check;
+ pnp_bios_hdr = check;
break;
}
+
pnpbios_build_devlist();
+ pnpbios_reserve_resources();
#ifdef CONFIG_PROC_FS
- pnp_proc_init( pnp_bios_dont_use_current_config );
+ pnpbios_proc_init();
#endif
#ifdef CONFIG_HOTPLUG
init_completion(&unload_sem);
@@ -1142,16 +1215,18 @@
MODULE_LICENSE("GPL");
/* We have to run it early and specifically in non modular.. */
-module_init(pnp_bios_init);
+module_init(pnpbios_init);
#ifdef CONFIG_HOTPLUG
-static void pnp_bios_exit(void)
+static void pnpbios_exit(void)
{
+ /* free_resources() ought to go here */
+ /* pnpbios_proc_done() */
unloading = 1;
wait_for_completion(&unload_sem);
}
-module_exit(pnp_bios_exit);
+module_exit(pnpbios_exit);
#endif
#endif
--- linux-2.4.10-ac12/drivers/pnp/pnp_proc.c Wed Oct 10 22:09:19 2001
+++ linux-2.4.10-ac12-fix/drivers/pnp/pnp_proc.c Sat Oct 13 08:42:05 2001
@@ -31,10 +31,10 @@
*eof = 1;
return 0;
}
- node = kmalloc(node_info.max_node_size, GFP_KERNEL);
+ node = pnpbios_kmalloc(node_info.max_node_size, GFP_KERNEL);
if (!node) return -ENOMEM;
for (i=0,nodenum=0;i<0xff && nodenum!=0xff; i++) {
- if ( pnp_bios_get_dev_node(&nodenum, 1, node) )
+ if ( pnpbios_get_dev_node(&nodenum, 1, node) )
break;
p += sprintf(p, "%02x\t%08x\t%02x:%02x:%02x\t%04x\n",
node->handle, node->eisa_id,
@@ -57,9 +57,9 @@
*eof = 1;
return 0;
}
- node = kmalloc(node_info.max_node_size, GFP_KERNEL);
+ node = pnpbios_kmalloc(node_info.max_node_size, GFP_KERNEL);
if (!node) return -ENOMEM;
- if ( pnp_bios_get_dev_node(&nodenum, boot, node) )
+ if ( pnpbios_get_dev_node(&nodenum, boot, node) )
return -EIO;
len = node->size - sizeof(struct pnp_bios_node);
memcpy(buf, node->data, len);
@@ -74,22 +74,25 @@
int boot = (long)data >> 8;
u8 nodenum = (long)data;
- node = kmalloc(node_info.max_node_size, GFP_KERNEL);
+ node = pnpbios_kmalloc(node_info.max_node_size, GFP_KERNEL);
if (!node) return -ENOMEM;
- if ( pnp_bios_get_dev_node(&nodenum, boot, node) )
+ if ( pnpbios_get_dev_node(&nodenum, boot, node) )
return -EIO;
if (count != node->size - sizeof(struct pnp_bios_node))
return -EINVAL;
memcpy(node->data, buf, count);
- if (pnp_bios_set_dev_node(node->handle, boot, node) != 0)
+ if (pnpbios_set_dev_node(node->handle, boot, node) != 0)
return -EINVAL;
kfree(node);
return count;
}
-static int pnp_proc_dont_use_current_config;
-
-void pnp_proc_init( int dont_use_current )
+/*
+ * When this is called, pnpbios functions are assumed to
+ * work and the pnpbios_dont_use_current_config flag
+ * should already have been set to the appropriate value
+ */
+void pnpbios_proc_init( void )
{
struct pnp_bios_node *node;
struct proc_dir_entry *ent;
@@ -97,10 +100,7 @@
int i;
u8 nodenum;
- pnp_proc_dont_use_current_config = dont_use_current;
-
- if (!pnp_bios_present()) return;
- if (pnp_bios_dev_node_info(&node_info) != 0) return;
+ if (pnpbios_dev_node_info(&node_info) != 0) return;
proc_pnp = proc_mkdir("pnp", proc_bus);
if (!proc_pnp) return;
@@ -108,13 +108,13 @@
if (!proc_pnp_boot) return;
create_proc_read_entry("devices", 0, proc_pnp, proc_read_devices, NULL);
- node = kmalloc(node_info.max_node_size, GFP_KERNEL);
+ node = pnpbios_kmalloc(node_info.max_node_size, GFP_KERNEL);
if (!node) return;
for (i=0,nodenum = 0; i<0xff && nodenum != 0xff; i++) {
- if (pnp_bios_get_dev_node(&nodenum, 1, node) != 0)
+ if (pnpbios_get_dev_node(&nodenum, 1, node) != 0)
break;
sprintf(name, "%02x", node->handle);
- if ( !pnp_proc_dont_use_current_config ) {
+ if ( !pnpbios_dont_use_current_config ) {
ent = create_proc_entry(name, 0, proc_pnp);
if (ent) {
ent->read_proc = proc_read_node;
@@ -132,7 +132,7 @@
kfree(node);
}
-void pnp_proc_done(void)
+void pnpbios_proc_done(void)
{
int i;
char name[3];
@@ -141,7 +141,7 @@
for (i=0; i<0xff; i++) {
sprintf(name, "%02x", i);
- if ( !pnp_proc_dont_use_current_config )
+ if ( !pnpbios_dont_use_current_config )
remove_proc_entry(name, proc_pnp);
remove_proc_entry(name, proc_pnp_boot);
}
^ permalink raw reply [flat|nested] 14+ messages in thread* Re: [PATCH] PnP BIOS -- bugfix; update devlist on setpnp
2001-10-13 15:40 Thomas Hood
@ 2001-10-15 6:37 ` Jurgen Botz
2001-10-15 9:45 ` Stelian Pop
2001-10-15 14:15 ` Ion Badulescu
2001-10-17 2:48 ` Steven A. DuChene
2 siblings, 1 reply; 14+ messages in thread
From: Jurgen Botz @ 2001-10-15 6:37 UTC (permalink / raw)
To: Thomas Hood; +Cc: linux-kernel, stelian.pop, ion, sduchene, jurgen
Thomas Hood wrote:
> Okay, here's a new major patch to the PnP BIOS driver
> which needs some testing before it's integrated.
>[...]
> Vaio users: Please make sure that this doesn't oops.
Patched against 2.4.12-ac1, it works and doesn't oops my
VAIO PCG-N505VE.
-j
--
Jürgen Botz | While differing widely in the various
jurgen@botz.org | little bits we know, in our infinite
| ignorance we are all equal. -Karl Popper
^ permalink raw reply [flat|nested] 14+ messages in thread* Re: [PATCH] PnP BIOS -- bugfix; update devlist on setpnp
2001-10-15 6:37 ` Jurgen Botz
@ 2001-10-15 9:45 ` Stelian Pop
2001-10-15 12:01 ` Andrey Panin
0 siblings, 1 reply; 14+ messages in thread
From: Stelian Pop @ 2001-10-15 9:45 UTC (permalink / raw)
To: Jurgen Botz; +Cc: Thomas Hood, linux-kernel, ion, sduchene
On Sun, Oct 14, 2001 at 11:37:39PM -0700, Jurgen Botz wrote:
> Thomas Hood wrote:
> > Okay, here's a new major patch to the PnP BIOS driver
> > which needs some testing before it's integrated.
> >[...]
> > Vaio users: Please make sure that this doesn't oops.
>
> Patched against 2.4.12-ac1, it works and doesn't oops my
> VAIO PCG-N505VE.
Same for me (against a 2.4.10-ac12), on a VAIO PCG-C1VE.
Relevant (maybe) output:
...
Sony Vaio laptop detected.
BIOS strings suggest APM reports battery life in minutes and wrong byte order.
PCI: PCI BIOS revision 2.10 entry at 0xfd98e, last bus=0
PCI: Using configuration type 1
PCI: Probing PCI hardware
PCI: Using IRQ router PIIX [8086/7110] at 00:07.0
PCI: Found IRQ 9 for device 00:08.0
PCI: Sharing IRQ 9 with 00:07.2
isapnp: Scanning for PnP cards...
isapnp: No Plug & Play device found
PnPBIOS: Found PnP BIOS installation structure at 0xc00f8120.
PnPBIOS: PnP BIOS version 1.0, entry 0xf0000:0xb25f, dseg 0x400.
PnPBIOS: 14 nodes reported by PnP BIOS; 14 recorded by driver.
PnPBIOS: PNP0c02: 0xfff80000-0xffffffff was already reserved
PnPBIOS: PNP0c02: 0xfff7f600-0xfff7ffff was already reserved
PnPBIOS: PNP0c02: 0x398-0x399 has been reserved
PnPBIOS: PNP0c02: 0x4d0-0x4d1 has been reserved
PnPBIOS: PNP0c02: 0x8000-0x804f was already reserved
PnPBIOS: PNP0c02: 0x1040-0x104f has been reserved
PnPBIOS: PNP0c01: 0xe8000-0xfffff was already reserved
PnPBIOS: PNP0c01: 0x100000-0x70ffbff was already reserved
PnPBIOS: PNP0c02: 0xdc000-0xdffff was already reserved
PnPBIOS: PNP0c02: 0xd1000-0xd3fff was already reserved
Linux NET4.0 for Linux 2.4
...
Stelian.
--
Stelian Pop <stelian.pop@fr.alcove.com>
|---------------- Free Software Engineer -----------------|
| Alcôve - http://www.alcove.com - Tel: +33 1 49 22 68 00 |
|------------- Alcôve, liberating software ---------------|
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH] PnP BIOS -- bugfix; update devlist on setpnp
2001-10-15 9:45 ` Stelian Pop
@ 2001-10-15 12:01 ` Andrey Panin
2001-10-15 12:25 ` Alan Cox
0 siblings, 1 reply; 14+ messages in thread
From: Andrey Panin @ 2001-10-15 12:01 UTC (permalink / raw)
To: linux-kernel; +Cc: Thomas Hood
[-- Attachment #1.1: Type: text/plain, Size: 2090 bytes --]
On Mon, Oct 15, 2001 at 11:45:56AM +0200, Stelian Pop wrote:
> On Sun, Oct 14, 2001 at 11:37:39PM -0700, Jurgen Botz wrote:
>
> > Thomas Hood wrote:
> > > Okay, here's a new major patch to the PnP BIOS driver
> > > which needs some testing before it's integrated.
> > >[...]
> > > Vaio users: Please make sure that this doesn't oops.
> >
> > Patched against 2.4.12-ac1, it works and doesn't oops my
> > VAIO PCG-N505VE.
>
> Same for me (against a 2.4.10-ac12), on a VAIO PCG-C1VE.
>
> Relevant (maybe) output:
>
> ...
> Sony Vaio laptop detected.
> BIOS strings suggest APM reports battery life in minutes and wrong byte order.
> PCI: PCI BIOS revision 2.10 entry at 0xfd98e, last bus=0
> PCI: Using configuration type 1
> PCI: Probing PCI hardware
> PCI: Using IRQ router PIIX [8086/7110] at 00:07.0
> PCI: Found IRQ 9 for device 00:08.0
> PCI: Sharing IRQ 9 with 00:07.2
> isapnp: Scanning for PnP cards...
> isapnp: No Plug & Play device found
> PnPBIOS: Found PnP BIOS installation structure at 0xc00f8120.
> PnPBIOS: PnP BIOS version 1.0, entry 0xf0000:0xb25f, dseg 0x400.
> PnPBIOS: 14 nodes reported by PnP BIOS; 14 recorded by driver.
> PnPBIOS: PNP0c02: 0xfff80000-0xffffffff was already reserved
^^^^^^^^^^^^^^^^^^^^^
Looks wrong for me, we are trying to reserve _memory_ range with request_region().
Patch attached.
> PnPBIOS: PNP0c02: 0xfff7f600-0xfff7ffff was already reserved
> PnPBIOS: PNP0c02: 0x398-0x399 has been reserved
> PnPBIOS: PNP0c02: 0x4d0-0x4d1 has been reserved
> PnPBIOS: PNP0c02: 0x8000-0x804f was already reserved
> PnPBIOS: PNP0c02: 0x1040-0x104f has been reserved
> PnPBIOS: PNP0c01: 0xe8000-0xfffff was already reserved
> PnPBIOS: PNP0c01: 0x100000-0x70ffbff was already reserved
> PnPBIOS: PNP0c02: 0xdc000-0xdffff was already reserved
> PnPBIOS: PNP0c02: 0xd1000-0xd3fff was already reserved
> Linux NET4.0 for Linux 2.4
> ...
>
> Stelian.
--
Andrey Panin | Embedded systems software engineer
pazke@orbita1.ru | PGP key: http://www.orbita1.ru/~pazke/AndreyPanin.asc
[-- Attachment #1.2: patch-pnpbios --]
[-- Type: text/plain, Size: 794 bytes --]
diff -ur linux.old/drivers/pnp/pnp_bios.c linux/drivers/pnp/pnp_bios.c
--- linux.old/drivers/pnp/pnp_bios.c Mon Oct 15 15:38:43 2001
+++ linux/drivers/pnp/pnp_bios.c Mon Oct 15 15:54:56 2001
@@ -1052,8 +1052,8 @@
* example do reserve stuff they know about too, so we may well
* have double reservations.
*/
- printk(
- "PnPBIOS: %s: 0x%x-0x%x %s reserved\n",
+ printk(
+ KERN_INFO "PnPBIOS: %s: 0x%x-0x%x %s reserved\n",
pnpid, start, end,
NULL != res ? "has been" : "was already"
);
@@ -1069,6 +1069,9 @@
if ( dev->resource[i].flags & IORESOURCE_UNSET )
/* resource record not used */
break;
+ if (!(dev->resource[i].flags & IORESOURCE_IO))
+ /* memory resource */
+ continue;
if ( dev->resource[i].start == 0 )
/* resource disabled */
continue;
[-- Attachment #2: Type: application/pgp-signature, Size: 232 bytes --]
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH] PnP BIOS -- bugfix; update devlist on setpnp
2001-10-15 12:01 ` Andrey Panin
@ 2001-10-15 12:25 ` Alan Cox
2001-10-15 21:49 ` Thomas Hood
0 siblings, 1 reply; 14+ messages in thread
From: Alan Cox @ 2001-10-15 12:25 UTC (permalink / raw)
To: Andrey Panin; +Cc: linux-kernel, Thomas Hood
> ^^^^^^^^^^^^^^^^^^^^^
> Looks wrong for me, we are trying to reserve _memory_ range with request_re=
> gion().
We should be creating memory and I/O regions as unused but exist rather than
requesting them as owned. We do want to reserve memory regions as present
but unused to void assigning PCI devices over them
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH] PnP BIOS -- bugfix; update devlist on setpnp
2001-10-15 12:25 ` Alan Cox
@ 2001-10-15 21:49 ` Thomas Hood
0 siblings, 0 replies; 14+ messages in thread
From: Thomas Hood @ 2001-10-15 21:49 UTC (permalink / raw)
To: Alan Cox; +Cc: Andrey Panin, linux-kernel
On Mon, 2001-10-15 at 08:25, Alan Cox wrote:
> Andrey Panin wrote:
> > Looks wrong for me, we are trying to reserve _memory_ range with request_re=
> > gion().
>
> We should be creating memory and I/O regions as unused but exist rather than
> requesting them as owned. We do want to reserve memory regions as present
> but unused to void assigning PCI devices over them
Yes, we should.
The patch I submitted does not address that issue. It addresses
the issue of runtime devlist updating (plus the other small things
mentioned in my changelog), which is a big enough deal on its own.
Here's the changelog again for your reference:
1) Fix bugs in resource reservation:
- end of reserved range off by +1
- didn't reserve _all_ system board resources
2) Change code so that set_dev_node updates the devlist, so
drivers loaded after a setpnp will get up-to-date resource
information. Because I haven't protected devlist update
code with locks, this feature isn't SMP safe yet.
3) Miscellaneous code cleanups. Use "pnpbios" more consistently.
Improve printk output. Etc.
Alan: I think the patch can go in as-is, since the much-appreciated
beta testers report no calamities. :) I append it here: it applies
correctly to 2.4.12-ac2 with one hunk offset by two lines.
As noted in (2), however, the patched driver allows updating of
the devlist even though it doesn't use any locks; so I conclude
that the code isn't SMP safe as it is. My secret wish is that
someone else will submit a patch for this, because I'm aware that
my understanding of SMP issues isn't really adequate.
The "flag as present but unused" issue can be addressed in a future
patch. Once again, if someone wants to submit that patch
they're very welcome to do so. Otherwise it'll have to wait for
me to figure out exactly what Alan means. ;)
--
Thomas
The patch again:
--- linux-2.4.10-ac12/init/main.c Wed Oct 10 22:09:58 2001
+++ linux-2.4.10-ac12-fix/init/main.c Fri Oct 12 22:41:30 2001
@@ -824,7 +824,7 @@
isapnp_init();
#endif
#ifdef CONFIG_PNPBIOS
- pnp_bios_init();
+ pnpbios_init();
#endif
#ifdef CONFIG_TC
--- linux-2.4.10-ac12/include/linux/pnp_bios.h Wed Oct 10 22:09:57 2001
+++ linux-2.4.10-ac12-fix/include/linux/pnp_bios.h Sat Oct 13 09:57:24 2001
@@ -132,30 +132,35 @@
return (struct pnpbios_driver *)dev->driver;
}
-extern void pnp_bios_init (void);
-extern int pnp_bios_dev_node_info (struct pnp_dev_node_info *data);
-extern int pnp_bios_get_dev_node (u8 *nodenum, char config, struct pnp_bios_node *data);
-extern int pnp_bios_set_dev_node (u8 nodenum, char config, struct pnp_bios_node *data);
-extern int pnp_bios_get_event (u16 *message);
-extern int pnp_bios_send_message (u16 message);
-extern int pnp_bios_set_stat_res (char *info);
-extern int pnp_bios_get_stat_res (char *info);
-extern int pnp_bios_apm_id_table (char *table, u16 *size);
-extern int pnp_bios_isapnp_config (struct pnp_isa_config_struc *data);
-extern int pnp_bios_escd_info (struct escd_info_struc *data);
-extern int pnp_bios_read_escd (char *data, u32 nvram_base);
-extern int pnp_bios_write_escd (char *data, u32 nvram_base);
-
-extern void pnp_proc_init ( int dont_use_current );
-
#ifdef CONFIG_PNPBIOS
#define pnpbios_for_each_dev(dev) \
for(dev = pnpbios_dev_g(pnpbios_devices.next); dev != pnpbios_dev_g(&pnpbios_devices); dev = pnpbios_dev_g(dev->global_list.next))
-extern int pnp_bios_present (void);
+
+
+extern int pnpbios_dont_use_current_config;
+void *pnpbios_kmalloc(size_t size, int f);
+extern void pnpbios_init (void);
+extern void pnpbios_proc_init (void);
+
extern struct pci_dev *pnpbios_find_device(char *pnpid, struct pci_dev *dev);
-extern int pnpbios_register_driver(struct pnpbios_driver *drv);
+extern int pnpbios_register_driver(struct pnpbios_driver *drv);
extern void pnpbios_unregister_driver(struct pnpbios_driver *drv);
+extern int pnpbios_dev_node_info (struct pnp_dev_node_info *data);
+extern int pnpbios_get_dev_node (u8 *nodenum, char config, struct pnp_bios_node *data);
+extern int pnpbios_set_dev_node (u8 nodenum, char config, struct pnp_bios_node *data);
+#if needed
+extern int pnpbios_get_event (u16 *message);
+extern int pnpbios_send_message (u16 message);
+extern int pnpbios_set_stat_res (char *info);
+extern int pnpbios_get_stat_res (char *info);
+extern int pnpbios_apm_id_table (char *table, u16 *size);
+extern int pnpbios_isapnp_config (struct pnp_isa_config_struc *data);
+extern int pnpbios_escd_info (struct escd_info_struc *data);
+extern int pnpbios_read_escd (char *data, u32 nvram_base);
+extern int pnpbios_write_escd (char *data, u32 nvram_base);
+#endif
+
/*
* a helper function which helps ensure correct pnpbios_driver
* setup and cleanup for commonly-encountered hotplug/modular cases
@@ -189,24 +194,14 @@
return rc;
}
-#else
+#else /* CONFIG_PNPBIOS */
#define pnpbios_for_each_dev(dev) for(dev = NULL; 0; )
-static __inline__ int pnp_bios_present (void)
-{
- return 0;
-}
-
static __inline__ struct pci_dev *pnpbios_find_device(char *pnpid, struct pci_dev *dev)
{
return NULL;
}
-static __inline__ int pnpbios_module_init(struct pnpbios_driver *drv)
-{
- return -ENODEV;
-}
-
static __inline__ int pnpbios_register_driver(struct pnpbios_driver *drv)
{
return 0;
@@ -217,7 +212,12 @@
return;
}
-#endif
+static __inline__ int pnpbios_module_init(struct pnpbios_driver *drv)
+{
+ return -ENODEV;
+}
+
+#endif /* CONFIG_PNPBIOS */
#endif /* __KERNEL__ */
#endif /* _LINUX_PNP_BIOS_H */
--- linux-2.4.10-ac12/drivers/pnp/pnp_bios.c Wed Oct 10 22:09:19 2001
+++ linux-2.4.10-ac12-fix/drivers/pnp/pnp_bios.c Sat Oct 13 11:27:45 2001
@@ -50,11 +50,17 @@
#define PNP_SIGNATURE (('$' << 0) + ('P' << 8) + ('n' << 16) + ('P' << 24))
/*
+ * Forward declarations
+ */
+
+static void pnpbios_update_devlist( u8 nodenum, struct pnp_bios_node *data );
+
+/*
* This is the standard structure used to identify the entry point
* to the Plug and Play bios
*/
#pragma pack(1)
-union pnpbios {
+union pnp_bios_expansion_header {
struct {
u32 signature; /* "$PnP" */
u8 version; /* in BCD */
@@ -83,7 +89,7 @@
u16 segment;
} pnp_bios_callpoint;
-static union pnpbios * pnp_bios_inst_struc = NULL;
+static union pnp_bios_expansion_header * pnp_bios_hdr = NULL;
/* The PnP entries in the GDT */
#define PNP_GDT 0x0060
@@ -214,12 +220,16 @@
printk(KERN_ERR "PnPBIOS: Check with your vendor for an updated BIOS\n");
}
-// if ( status ) printk(KERN_WARNING "PnPBIOS: BIOS returned error 0x%x from function 0x%x.\n", status, func);
-
return status;
}
-static void *pnp_bios_kmalloc(size_t size, int f)
+/*
+ *
+ * UTILITY FUNCTIONS
+ *
+ */
+
+void *pnpbios_kmalloc(size_t size, int f)
{
void *p = kmalloc( size, f );
if ( p == NULL )
@@ -228,18 +238,29 @@
}
/*
+ * Call this only after init time
+ */
+static int pnp_bios_is_present(void)
+{
+ return (pnp_bios_hdr != NULL);
+}
+
+/*
*
* PnP BIOS ACCESS FUNCTIONS
*
+ * pnp_bios_* are local functions used to call the BIOS
+ * pnpbios_* are the public interface to these functions
+ *
*/
/*
* Call PnP BIOS with function 0x00, "get number of system device nodes"
*/
-static int pnp_bios_dev_node_info_silently(struct pnp_dev_node_info *data)
+static int pnp_bios_dev_node_info(struct pnp_dev_node_info *data)
{
u16 status;
- if (!pnp_bios_present ())
+ if (!pnp_bios_is_present ())
return PNP_FUNCTION_NOT_SUPPORTED;
Q2_SET_SEL(PNP_TS1, data, sizeof(struct pnp_dev_node_info));
status = call_pnp_bios(PNP_GET_NUM_SYS_DEV_NODES, 0, PNP_TS1, 2, PNP_TS1, PNP_DS, 0, 0);
@@ -247,11 +268,11 @@
return status;
}
-int pnp_bios_dev_node_info(struct pnp_dev_node_info *data)
+int pnpbios_dev_node_info(struct pnp_dev_node_info *data)
{
- u16 status = pnp_bios_dev_node_info_silently( data );
+ int status = pnp_bios_dev_node_info( data );
if ( status )
- printk(KERN_WARNING "PnPBIOS: PnP BIOS dev_node_info function returned error status 0x%x\n", status);
+ printk(KERN_WARNING "PnPBIOS: dev_node_info: Unexpected status 0x%x\n", status);
return status;
}
@@ -269,22 +290,25 @@
* or volatile current (0) config
* Output: *nodenum=next node or 0xff if no more nodes
*/
-static int pnp_bios_get_dev_node_silently(u8 *nodenum, char boot, struct pnp_bios_node *data)
+static int pnp_bios_get_dev_node(u8 *nodenum, char boot, struct pnp_bios_node *data)
{
u16 status;
- if (!pnp_bios_present ())
- return PNP_FUNCTION_NOT_SUPPORTED;
Q2_SET_SEL(PNP_TS1, nodenum, sizeof(char));
Q2_SET_SEL(PNP_TS2, data, 64 * 1024);
status = call_pnp_bios(PNP_GET_SYS_DEV_NODE, 0, PNP_TS1, 0, PNP_TS2, boot ? 2 : 1, PNP_DS, 0);
return status;
}
-int pnp_bios_get_dev_node(u8 *nodenum, char boot, struct pnp_bios_node *data)
+int pnpbios_get_dev_node(u8 *nodenum, char boot, struct pnp_bios_node *data)
{
- u16 status = pnp_bios_get_dev_node_silently( nodenum, boot, data );
+ int status;
+ if (!pnp_bios_is_present ())
+ return PNP_FUNCTION_NOT_SUPPORTED;
+ if ( !boot & pnpbios_dont_use_current_config )
+ return PNP_FUNCTION_NOT_SUPPORTED;
+ status = pnp_bios_get_dev_node( nodenum, boot, data );
if ( status )
- printk(KERN_WARNING "PnPBIOS: PnP BIOS get_dev_node function returned error status 0x%x\n", status);
+ printk(KERN_WARNING "PnPBIOS: get_dev_node: Unexpected 0x%x\n", status);
return status;
}
@@ -294,21 +318,35 @@
* boot = whether to set nonvolatile boot (!=0)
* or volatile current (0) config
*/
-static int pnp_bios_set_dev_node_silently(u8 nodenum, char boot, struct pnp_bios_node *data)
+static int pnp_bios_set_dev_node(u8 nodenum, char boot, struct pnp_bios_node *data)
{
u16 status;
- if (!pnp_bios_present ())
- return PNP_FUNCTION_NOT_SUPPORTED;
Q2_SET_SEL(PNP_TS1, data, /* *((u16 *) data)*/ 65536);
status = call_pnp_bios(PNP_SET_SYS_DEV_NODE, nodenum, 0, PNP_TS1, boot ? 2 : 1, PNP_DS, 0, 0);
return status;
}
-int pnp_bios_set_dev_node(u8 nodenum, char boot, struct pnp_bios_node *data)
+int pnpbios_set_dev_node(u8 nodenum, char boot, struct pnp_bios_node *data)
{
- u16 status = pnp_bios_set_dev_node_silently( nodenum, boot, data );
- if ( status )
- printk(KERN_WARNING "PnPBIOS: PnP BIOS set_dev_node function returned error status 0x%x\n", status);
+ int status;
+ if (!pnp_bios_is_present ())
+ return PNP_FUNCTION_NOT_SUPPORTED;
+ if ( !boot & pnpbios_dont_use_current_config )
+ return PNP_FUNCTION_NOT_SUPPORTED;
+ status = pnp_bios_set_dev_node( nodenum, boot, data );
+ if ( status ) {
+ printk(KERN_WARNING "PnPBIOS: set_dev_node: Unexpected set_dev_node status 0x%x\n", status);
+ return status;
+ }
+ if ( !boot ) { /* Update devlist */
+ u8 thisnodenum = nodenum;
+ status = pnp_bios_get_dev_node( &nodenum, boot, data );
+ if ( status ) {
+ printk(KERN_WARNING "PnPBIOS: set_dev_node: Unexpected get_dev_node status 0x%x\n", status);
+ return status;
+ }
+ pnpbios_update_devlist( thisnodenum, data );
+ }
return status;
}
@@ -319,7 +357,7 @@
static int pnp_bios_get_event(u16 *event)
{
u16 status;
- if (!pnp_bios_present ())
+ if (!pnp_bios_is_present ())
return PNP_FUNCTION_NOT_SUPPORTED;
Q2_SET_SEL(PNP_TS1, event, sizeof(u16));
status = call_pnp_bios(PNP_GET_EVENT, 0, PNP_TS1, PNP_DS, 0, 0 ,0 ,0);
@@ -334,7 +372,7 @@
static int pnp_bios_send_message(u16 message)
{
u16 status;
- if (!pnp_bios_present ())
+ if (!pnp_bios_is_present ())
return PNP_FUNCTION_NOT_SUPPORTED;
status = call_pnp_bios(PNP_SEND_MESSAGE, message, PNP_DS, 0, 0, 0, 0, 0);
return status;
@@ -348,7 +386,7 @@
static int pnp_bios_dock_station_info(struct pnp_docking_station_info *data)
{
u16 status;
- if (!pnp_bios_present ())
+ if (!pnp_bios_is_present ())
return PNP_FUNCTION_NOT_SUPPORTED;
Q2_SET_SEL(PNP_TS1, data, sizeof(struct pnp_docking_station_info));
status = call_pnp_bios(PNP_GET_DOCKING_STATION_INFORMATION, 0, PNP_TS1, PNP_DS, 0, 0, 0, 0);
@@ -364,7 +402,7 @@
static int pnp_bios_set_stat_res(char *info)
{
u16 status;
- if (!pnp_bios_present ())
+ if (!pnp_bios_is_present ())
return PNP_FUNCTION_NOT_SUPPORTED;
Q2_SET_SEL(PNP_TS1, info, *((u16 *) info));
status = call_pnp_bios(PNP_SET_STATIC_ALLOCED_RES_INFO, 0, PNP_TS1, PNP_DS, 0, 0, 0, 0);
@@ -380,7 +418,7 @@
static int pnp_bios_get_stat_res(char *info)
{
u16 status;
- if (!pnp_bios_present ())
+ if (!pnp_bios_is_present ())
return PNP_FUNCTION_NOT_SUPPORTED;
Q2_SET_SEL(PNP_TS1, info, 64 * 1024);
status = call_pnp_bios(PNP_GET_STATIC_ALLOCED_RES_INFO, 0, PNP_TS1, PNP_DS, 0, 0, 0, 0);
@@ -395,7 +433,7 @@
static int pnp_bios_apm_id_table(char *table, u16 *size)
{
u16 status;
- if (!pnp_bios_present ())
+ if (!pnp_bios_is_present ())
return PNP_FUNCTION_NOT_SUPPORTED;
Q2_SET_SEL(PNP_TS1, table, *size);
Q2_SET_SEL(PNP_TS2, size, sizeof(u16));
@@ -411,7 +449,7 @@
static int pnp_bios_isapnp_config(struct pnp_isa_config_struc *data)
{
u16 status;
- if (!pnp_bios_present ())
+ if (!pnp_bios_is_present ())
return PNP_FUNCTION_NOT_SUPPORTED;
Q2_SET_SEL(PNP_TS1, data, sizeof(struct pnp_isa_config_struc));
status = call_pnp_bios(PNP_GET_PNP_ISA_CONFIG_STRUC, 0, PNP_TS1, PNP_DS, 0, 0, 0, 0);
@@ -426,7 +464,7 @@
static int pnp_bios_escd_info(struct escd_info_struc *data)
{
u16 status;
- if (!pnp_bios_present ())
+ if (!pnp_bios_is_present ())
return ESCD_FUNCTION_NOT_SUPPORTED;
Q2_SET_SEL(PNP_TS1, data, sizeof(struct escd_info_struc));
status = call_pnp_bios(PNP_GET_ESCD_INFO, 0, PNP_TS1, 2, PNP_TS1, 4, PNP_TS1, PNP_DS);
@@ -442,7 +480,7 @@
static int pnp_bios_read_escd(char *data, u32 nvram_base)
{
u16 status;
- if (!pnp_bios_present ())
+ if (!pnp_bios_is_present ())
return ESCD_FUNCTION_NOT_SUPPORTED;
Q2_SET_SEL(PNP_TS1, data, 64 * 1024);
set_base(gdt[PNP_TS2 >> 3], nvram_base);
@@ -459,7 +497,7 @@
static int pnp_bios_write_escd(char *data, u32 nvram_base)
{
u16 status;
- if (!pnp_bios_present ())
+ if (!pnp_bios_is_present ())
return ESCD_FUNCTION_NOT_SUPPORTED;
Q2_SET_SEL(PNP_TS1, data, 64 * 1024);
set_base(gdt[PNP_TS2 >> 3], nvram_base);
@@ -469,10 +507,6 @@
}
#endif
-EXPORT_SYMBOL(pnp_bios_dev_node_info);
-EXPORT_SYMBOL(pnp_bios_get_dev_node);
-EXPORT_SYMBOL(pnp_bios_set_dev_node);
-
/*
*
* PnP DOCKING FUNCTIONS
@@ -482,7 +516,6 @@
#ifdef CONFIG_HOTPLUG
static int unloading = 0;
-
static struct completion unload_sem;
/*
@@ -499,10 +532,10 @@
if (!current->fs->root) {
return -EAGAIN;
}
- if (!(envp = (char **) pnp_bios_kmalloc (20 * sizeof (char *), GFP_KERNEL))) {
+ if (!(envp = (char **) pnpbios_kmalloc (20 * sizeof (char *), GFP_KERNEL))) {
return -ENOMEM;
}
- if (!(buf = pnp_bios_kmalloc (256, GFP_KERNEL))) {
+ if (!(buf = pnpbios_kmalloc (256, GFP_KERNEL))) {
kfree (envp);
return -ENOMEM;
}
@@ -579,7 +612,7 @@
d = 1;
break;
default:
- printk(KERN_WARNING "PnPBIOS: Unexpected error 0x%x returned by BIOS.\n", err);
+ printk(KERN_WARNING "PnPBIOS: pnp_dock_thread: Unexpected status 0x%x returned by BIOS.\n", err);
continue;
}
if(d != docked)
@@ -587,7 +620,9 @@
if(pnp_dock_event(d, &now)==0)
{
docked = d;
-// printk(KERN_INFO "PnPBIOS: Docking station %stached.\n", docked?"at":"de");
+#if 0
+ printk(KERN_INFO "PnPBIOS: Docking station %stached.\n", docked?"at":"de");
+#endif
}
}
}
@@ -598,147 +633,62 @@
/*
*
- * NODE DATA HANDLING FUNCTIONS
+ * NODE DATA PARSING FUNCTIONS
*
*/
-static void inline pnpbios_add_irqresource(struct pci_dev *dev, int irq)
+static void pnpbios_add_irqresource(struct pci_dev *dev, int irq)
{
- // Permit irq==-1 which signifies "disabled"
int i = 0;
while (!(dev->irq_resource[i].flags & IORESOURCE_UNSET) && i < DEVICE_COUNT_IRQ) i++;
if (i < DEVICE_COUNT_IRQ) {
- dev->irq_resource[i].start = irq;
+ dev->irq_resource[i].start = (unsigned long) irq;
dev->irq_resource[i].flags = IORESOURCE_IRQ; // Also clears _UNSET flag
}
}
-static void inline pnpbios_add_dmaresource(struct pci_dev *dev, int dma)
+static void pnpbios_add_dmaresource(struct pci_dev *dev, int dma)
{
- // Permit dma==-1 which signifies "disabled"
int i = 0;
while (!(dev->dma_resource[i].flags & IORESOURCE_UNSET) && i < DEVICE_COUNT_DMA) i++;
if (i < DEVICE_COUNT_DMA) {
- dev->dma_resource[i].start = dma;
+ dev->dma_resource[i].start = (unsigned long) dma;
dev->dma_resource[i].flags = IORESOURCE_DMA; // Also clears _UNSET flag
}
}
-static void inline pnpbios_add_ioresource(struct pci_dev *dev, int io, int len)
+static void pnpbios_add_ioresource(struct pci_dev *dev, int io, int len)
{
int i = 0;
while (!(dev->resource[i].flags & IORESOURCE_UNSET) && i < DEVICE_COUNT_RESOURCE) i++;
if (i < DEVICE_COUNT_RESOURCE) {
- dev->resource[i].start = io;
- dev->resource[i].end = io + len;
+ dev->resource[i].start = (unsigned long) io;
+ dev->resource[i].end = (unsigned long)(io + len - 1);
dev->resource[i].flags = IORESOURCE_IO; // Also clears _UNSET flag
}
}
-static void inline pnpbios_add_memresource(struct pci_dev *dev, int mem, int len)
+static void pnpbios_add_memresource(struct pci_dev *dev, int mem, int len)
{
int i = 0;
while (!(dev->resource[i].flags & IORESOURCE_UNSET) && i < DEVICE_COUNT_RESOURCE) i++;
if (i < DEVICE_COUNT_RESOURCE) {
- dev->resource[i].start = mem;
- dev->resource[i].end = mem + len;
+ dev->resource[i].start = (unsigned long) mem;
+ dev->resource[i].end = (unsigned long)(mem + len - 1);
dev->resource[i].flags = IORESOURCE_MEM; // Also clears _UNSET flag
}
}
-/*
- * request I/O ports which are used according to the PnP BIOS
- * to avoid I/O conflicts.
- */
-static void mboard_request(char *pnpid, int io, int len)
-{
- struct resource *res;
- char *regionid;
-
- if (
- 0 != strcmp(pnpid,"PNP0c01") && /* memory controller */
- 0 != strcmp(pnpid,"PNP0c02") /* system peripheral: other */
- ) {
- return;
- }
-
- if (io < 0x100) {
- /*
- * Below 0x100 is only standard PC hardware
- * (pics, kbd, timer, dma, ...)
- *
- * We should not get resource conflicts there,
- * and the kernel reserves these anyway
- * (see arch/i386/kernel/setup.c).
- */
- return;
- }
-
- /*
- * Anything else we'll try reserve to avoid these ranges are
- * assigned to someone (CardBus bridges for example) and thus are
- * triggering resource conflicts.
- *
- * Failures at this point are usually harmless. pci quirks for
- * example do reserve stuff they know about too, so we might have
- * double reservations here.
- *
- * We really shouldn't just reserve these regions, though, since
- * that prevents the device drivers from claiming them.
- */
- regionid = pnp_bios_kmalloc(16, GFP_KERNEL);
- if ( regionid == NULL )
- return;
- sprintf(regionid, "PnPBIOS %s", pnpid);
- res = request_region(io,len,regionid);
- if ( res == NULL )
- kfree( regionid );
- printk(
- "PnPBIOS: %s: 0x%x-0x%x %s reserved\n",
- pnpid, io, io+len-1,
- NULL != res ? "has been" : "was already"
- );
-
- return;
-}
-
-
-#define HEX(id,a) hex[((id)>>a) & 15]
-#define CHAR(id,a) (0x40 + (((id)>>a) & 31))
-
-static char * __init pnpid32_to_pnpid(u32 id)
-{
- const char *hex = "0123456789abcdef";
- static char str[8];
- id = be32_to_cpu(id);
- str[0] = CHAR(id, 26);
- str[1] = CHAR(id, 21);
- str[2] = CHAR(id,16);
- str[3] = HEX(id, 12);
- str[4] = HEX(id, 8);
- str[5] = HEX(id, 4);
- str[6] = HEX(id, 0);
- str[7] = '\0';
- return str;
-}
-
-#undef CHAR
-#undef HEX
-
-/*
- * parse PNPBIOS "Allocated Resources Block" and fill IO,IRQ,DMA into pci_dev
- */
-static void __init pnpbios_rawdata_2_pci_dev(struct pnp_bios_node *node, struct pci_dev *dev)
+static void pnpbios_node_resource_data_to_dev(struct pnp_bios_node *node, struct pci_dev *dev)
{
unsigned char *p = node->data, *lastp=NULL;
int i;
/*
- * First, set dev contents to default values
+ * First, set resource info to default values
*/
- memset(dev,0,sizeof(struct pci_dev));
for (i=0;i<DEVICE_COUNT_RESOURCE;i++) {
- /* dev->resource[i].start = 0; */
+ dev->resource[i].start = 0; // "disabled"
dev->resource[i].flags = IORESOURCE_UNSET;
}
for (i=0;i<DEVICE_COUNT_IRQ;i++) {
@@ -751,7 +701,7 @@
}
/*
- * Fill in dev info
+ * Fill in dev resource info
*/
while ( (char *)p < ((char *)node->data + node->size )) {
if(p==lastp) break;
@@ -795,7 +745,7 @@
switch (p[0]>>3) {
case 0x04: // irq
{
- int i, mask, irq = -1; // "disabled"
+ int i, mask, irq = -1;
mask= p[1] + p[2]*256;
for (i=0;i<16;i++, mask=mask>>1)
if(mask & 0x01) irq=i;
@@ -804,7 +754,7 @@
}
case 0x05: // dma
{
- int i, mask, dma = -1; // "disabled"
+ int i, mask, dma = -1;
mask = p[1];
for (i=0;i<8;i++, mask = mask>>1)
if(mask & 0x01) dma=i;
@@ -816,7 +766,6 @@
int io= p[2] + p[3] *256;
int len = p[7];
pnpbios_add_ioresource(dev, io, len);
- mboard_request(pnpid32_to_pnpid(node->eisa_id),io,len);
break;
}
case 0x09: // fixed location io
@@ -843,42 +792,53 @@
static LIST_HEAD(pnpbios_devices);
-int pnp_bios_present(void)
-{
- return (pnp_bios_inst_struc != NULL);
-}
-
-EXPORT_SYMBOL(pnp_bios_present);
-
-static int __init pnpbios_insert_device(struct pci_dev *dev)
+static int inline pnpbios_insert_device(struct pci_dev *dev)
{
/* FIXME: Need to check for re-add of existing node */
list_add_tail(&dev->global_list, &pnpbios_devices);
return 0;
}
-/*
- * Build the list of pci_dev objects from the PnP table
- */
-
+#define HEX(id,a) hex[((id)>>a) & 15]
+#define CHAR(id,a) (0x40 + (((id)>>a) & 31))
+//
+static void inline pnpid32_to_pnpid(u32 id, char *str)
+{
+ const char *hex = "0123456789abcdef";
+
+ id = be32_to_cpu(id);
+ str[0] = CHAR(id, 26);
+ str[1] = CHAR(id, 21);
+ str[2] = CHAR(id,16);
+ str[3] = HEX(id, 12);
+ str[4] = HEX(id, 8);
+ str[5] = HEX(id, 4);
+ str[6] = HEX(id, 0);
+ str[7] = '\0';
+
+ return;
+}
+//
+#undef CHAR
+#undef HEX
+
static void __init pnpbios_build_devlist(void)
{
int i;
int nodenum;
int nodes_got = 0;
+ int devs = 0;
struct pnp_bios_node *node;
struct pnp_dev_node_info node_info;
struct pci_dev *dev;
- char *pnpid;
-
- if (!pnp_bios_present ())
+ if (!pnp_bios_is_present ())
return;
if (pnp_bios_dev_node_info(&node_info) != 0)
return;
- node = pnp_bios_kmalloc(node_info.max_node_size, GFP_KERNEL);
+ node = pnpbios_kmalloc(node_info.max_node_size, GFP_KERNEL);
if (!node)
return;
@@ -891,22 +851,45 @@
if (pnp_bios_get_dev_node((u8 *)&nodenum, (char )1 , node))
break;
nodes_got++;
- dev = pnp_bios_kmalloc(sizeof (struct pci_dev), GFP_KERNEL);
+ dev = pnpbios_kmalloc(sizeof (struct pci_dev), GFP_KERNEL);
if (!dev)
break;
- pnpbios_rawdata_2_pci_dev(node,dev);
+ memset(dev,0,sizeof(struct pci_dev));
dev->devfn=thisnodenum;
- pnpid = pnpid32_to_pnpid(node->eisa_id);
memcpy(dev->name,"PNPBIOS",8);
- memcpy(dev->slot_name,pnpid,8);
+ pnpid32_to_pnpid(node->eisa_id,dev->slot_name);
+ pnpbios_node_resource_data_to_dev(node,dev);
if(pnpbios_insert_device(dev)<0)
kfree(dev);
+ devs++;
}
kfree(node);
- printk(KERN_INFO "PnPBIOS: %i node%s reported by PnP BIOS\n", nodes_got, nodes_got != 1 ? "s" : "");
+ printk(KERN_INFO "PnPBIOS: %i node%s reported by PnP BIOS; %i recorded by driver.\n",
+ nodes_got, nodes_got != 1 ? "s" : "", devs);
}
+static struct pci_dev *pnpbios_find_device_by_nodenum( u8 nodenum )
+{
+ struct pci_dev *dev;
+
+ pnpbios_for_each_dev(dev) {
+ if(dev->devfn == nodenum)
+ return dev;
+ }
+
+ return NULL;
+}
+
+static void pnpbios_update_devlist( u8 nodenum, struct pnp_bios_node *data )
+{
+ struct pci_dev *dev = pnpbios_find_device_by_nodenum( nodenum );
+ if ( dev ) {
+ pnpbios_node_resource_data_to_dev(data,dev);
+ }
+
+ return;
+}
/*
*
@@ -920,22 +903,19 @@
struct pci_dev *pnpbios_find_device(char *pnpid, struct pci_dev *prev)
{
struct pci_dev *dev;
- int num;
-
- if(prev==NULL)
- num=0; /* Start from beginning */
- else
- num=prev->devfn + 1; /* Encode node number here */
+ int nodenum;
+ nodenum = 0;
+ if(prev)
+ nodenum=prev->devfn + 1; /* Encode node number here */
- pnpbios_for_each_dev(dev)
- {
- if(dev->devfn >= num)
- {
+ pnpbios_for_each_dev(dev) {
+ if(dev->devfn >= nodenum) {
if(memcmp(dev->slot_name, pnpid, 7)==0)
return dev;
}
}
+
return NULL;
}
@@ -1049,54 +1029,145 @@
EXPORT_SYMBOL(pnpbios_unregister_driver);
+/*
+ *
+ * RESOURCE RESERVATION FUNCTIONS
+ *
+ */
+
+static void __init pnpbios_reserve_resource_range(char *pnpid, int start, int end)
+{
+ struct resource *res;
+ char *regionid;
+
+ regionid = pnpbios_kmalloc(16, GFP_KERNEL);
+ if ( regionid == NULL )
+ return;
+ sprintf(regionid, "PnPBIOS %s", pnpid);
+ res = request_region(start,end-start+1,regionid);
+ if ( res == NULL )
+ kfree( regionid );
+ /*
+ * Failures at this point are usually harmless. pci quirks for
+ * example do reserve stuff they know about too, so we may well
+ * have double reservations.
+ */
+ printk(
+ "PnPBIOS: %s: 0x%x-0x%x %s reserved\n",
+ pnpid, start, end,
+ NULL != res ? "has been" : "was already"
+ );
+
+ return;
+}
+
+static void __init pnpbios_reserve_resources_of_dev( struct pci_dev *dev )
+{
+ int i;
+
+ for (i=0;i<DEVICE_COUNT_RESOURCE;i++) {
+ if ( dev->resource[i].flags & IORESOURCE_UNSET )
+ /* resource record not used */
+ break;
+ if ( dev->resource[i].start == 0 )
+ /* resource disabled */
+ continue;
+ if ( dev->resource[i].start < 0x100 )
+ /*
+ * Below 0x100 is only standard PC hardware
+ * (pics, kbd, timer, dma, ...)
+ *
+ * We should not get resource conflicts there,
+ * and the kernel reserves these anyway
+ * (see arch/i386/kernel/setup.c).
+ */
+ continue;
+ if ( dev->resource[i].end < dev->resource[i].start )
+ /* insane */
+ continue;
+ pnpbios_reserve_resource_range(
+ dev->slot_name,
+ dev->resource[i].start,
+ dev->resource[i].end
+ );
+ }
+
+ return;
+}
+
+/*
+ * Reserve resources used by system board devices
+ *
+ * We really shouldn't just _reserve_ these regions since
+ * that prevents the device drivers from claiming them.
+ */
+static void __init pnpbios_reserve_resources( void )
+{
+ struct pci_dev *dev;
+
+ pnpbios_for_each_dev(dev) {
+ if (
+ 0 != strcmp(dev->slot_name,"PNP0c01") && /* memory controller */
+ 0 != strcmp(dev->slot_name,"PNP0c02") /* system peripheral: other */
+ ) {
+ continue;
+ }
+ pnpbios_reserve_resources_of_dev(dev);
+ }
+
+ return;
+}
+
/*
*
* INIT AND EXIT
*
*
- * Search the defined area (0xf0000-0xffff0) for a valid PnP BIOS
- * structure and, if one is found, sets up the selectors and
- * entry points
*/
extern int is_sony_vaio_laptop;
-static int pnp_bios_disabled;
-static int pnp_bios_dont_use_current_config;
+static int pnpbios_disabled;
+int pnpbios_dont_use_current_config;
-static int disable_pnp_bios(char *str)
+static int __init pnpbios_disable_pnp_bios(char *str)
{
- pnp_bios_disabled=1;
+ pnpbios_disabled=1;
return 0;
}
-static int disable_use_of_current_config(char *str)
+static int __init pnpbios_disable_use_of_current_config(char *str)
{
- pnp_bios_dont_use_current_config=1;
+ pnpbios_dont_use_current_config=1;
return 0;
}
-__setup("nobiospnp", disable_pnp_bios);
-__setup("nobioscurrpnp", disable_use_of_current_config);
+__setup("nobiospnp", pnpbios_disable_pnp_bios);
+__setup("nobioscurrpnp", pnpbios_disable_use_of_current_config);
-void pnp_bios_init(void)
+void __init pnpbios_init(void)
{
- union pnpbios *check;
+ union pnp_bios_expansion_header *check;
u8 sum;
int i, length;
spin_lock_init(&pnp_bios_lock);
- if(pnp_bios_disabled) {
+ if(pnpbios_disabled) {
printk(KERN_INFO "PnPBIOS: Disabled.\n");
return;
}
if ( is_sony_vaio_laptop )
- pnp_bios_dont_use_current_config = 1;
+ pnpbios_dont_use_current_config = 1;
- for (check = (union pnpbios *) __va(0xf0000);
- check < (union pnpbios *) __va(0xffff0);
+ /*
+ * Search the defined area (0xf0000-0xffff0) for a valid PnP BIOS
+ * structure and, if one is found, sets up the selectors and
+ * entry points
+ */
+ for (check = (union pnp_bios_expansion_header *) __va(0xf0000);
+ check < (union pnp_bios_expansion_header *) __va(0xffff0);
((void *) (check)) += 16) {
if (check->fields.signature != PNP_SIGNATURE)
continue;
@@ -1123,12 +1194,14 @@
Q_SET_SEL(PNP_DS, check->fields.pm16dseg, 64 * 1024);
pnp_bios_callpoint.offset = check->fields.pm16offset;
pnp_bios_callpoint.segment = PNP_CS16;
- pnp_bios_inst_struc = check;
+ pnp_bios_hdr = check;
break;
}
+
pnpbios_build_devlist();
+ pnpbios_reserve_resources();
#ifdef CONFIG_PROC_FS
- pnp_proc_init( pnp_bios_dont_use_current_config );
+ pnpbios_proc_init();
#endif
#ifdef CONFIG_HOTPLUG
init_completion(&unload_sem);
@@ -1142,16 +1215,18 @@
MODULE_LICENSE("GPL");
/* We have to run it early and specifically in non modular.. */
-module_init(pnp_bios_init);
+module_init(pnpbios_init);
#ifdef CONFIG_HOTPLUG
-static void pnp_bios_exit(void)
+static void pnpbios_exit(void)
{
+ /* free_resources() ought to go here */
+ /* pnpbios_proc_done() */
unloading = 1;
wait_for_completion(&unload_sem);
}
-module_exit(pnp_bios_exit);
+module_exit(pnpbios_exit);
#endif
#endif
--- linux-2.4.10-ac12/drivers/pnp/pnp_proc.c Wed Oct 10 22:09:19 2001
+++ linux-2.4.10-ac12-fix/drivers/pnp/pnp_proc.c Sat Oct 13 08:42:05 2001
@@ -31,10 +31,10 @@
*eof = 1;
return 0;
}
- node = kmalloc(node_info.max_node_size, GFP_KERNEL);
+ node = pnpbios_kmalloc(node_info.max_node_size, GFP_KERNEL);
if (!node) return -ENOMEM;
for (i=0,nodenum=0;i<0xff && nodenum!=0xff; i++) {
- if ( pnp_bios_get_dev_node(&nodenum, 1, node) )
+ if ( pnpbios_get_dev_node(&nodenum, 1, node) )
break;
p += sprintf(p, "%02x\t%08x\t%02x:%02x:%02x\t%04x\n",
node->handle, node->eisa_id,
@@ -57,9 +57,9 @@
*eof = 1;
return 0;
}
- node = kmalloc(node_info.max_node_size, GFP_KERNEL);
+ node = pnpbios_kmalloc(node_info.max_node_size, GFP_KERNEL);
if (!node) return -ENOMEM;
- if ( pnp_bios_get_dev_node(&nodenum, boot, node) )
+ if ( pnpbios_get_dev_node(&nodenum, boot, node) )
return -EIO;
len = node->size - sizeof(struct pnp_bios_node);
memcpy(buf, node->data, len);
@@ -74,22 +74,25 @@
int boot = (long)data >> 8;
u8 nodenum = (long)data;
- node = kmalloc(node_info.max_node_size, GFP_KERNEL);
+ node = pnpbios_kmalloc(node_info.max_node_size, GFP_KERNEL);
if (!node) return -ENOMEM;
- if ( pnp_bios_get_dev_node(&nodenum, boot, node) )
+ if ( pnpbios_get_dev_node(&nodenum, boot, node) )
return -EIO;
if (count != node->size - sizeof(struct pnp_bios_node))
return -EINVAL;
memcpy(node->data, buf, count);
- if (pnp_bios_set_dev_node(node->handle, boot, node) != 0)
+ if (pnpbios_set_dev_node(node->handle, boot, node) != 0)
return -EINVAL;
kfree(node);
return count;
}
-static int pnp_proc_dont_use_current_config;
-
-void pnp_proc_init( int dont_use_current )
+/*
+ * When this is called, pnpbios functions are assumed to
+ * work and the pnpbios_dont_use_current_config flag
+ * should already have been set to the appropriate value
+ */
+void pnpbios_proc_init( void )
{
struct pnp_bios_node *node;
struct proc_dir_entry *ent;
@@ -97,10 +100,7 @@
int i;
u8 nodenum;
- pnp_proc_dont_use_current_config = dont_use_current;
-
- if (!pnp_bios_present()) return;
- if (pnp_bios_dev_node_info(&node_info) != 0) return;
+ if (pnpbios_dev_node_info(&node_info) != 0) return;
proc_pnp = proc_mkdir("pnp", proc_bus);
if (!proc_pnp) return;
@@ -108,13 +108,13 @@
if (!proc_pnp_boot) return;
create_proc_read_entry("devices", 0, proc_pnp, proc_read_devices, NULL);
- node = kmalloc(node_info.max_node_size, GFP_KERNEL);
+ node = pnpbios_kmalloc(node_info.max_node_size, GFP_KERNEL);
if (!node) return;
for (i=0,nodenum = 0; i<0xff && nodenum != 0xff; i++) {
- if (pnp_bios_get_dev_node(&nodenum, 1, node) != 0)
+ if (pnpbios_get_dev_node(&nodenum, 1, node) != 0)
break;
sprintf(name, "%02x", node->handle);
- if ( !pnp_proc_dont_use_current_config ) {
+ if ( !pnpbios_dont_use_current_config ) {
ent = create_proc_entry(name, 0, proc_pnp);
if (ent) {
ent->read_proc = proc_read_node;
@@ -132,7 +132,7 @@
kfree(node);
}
-void pnp_proc_done(void)
+void pnpbios_proc_done(void)
{
int i;
char name[3];
@@ -141,7 +141,7 @@
for (i=0; i<0xff; i++) {
sprintf(name, "%02x", i);
- if ( !pnp_proc_dont_use_current_config )
+ if ( !pnpbios_dont_use_current_config )
remove_proc_entry(name, proc_pnp);
remove_proc_entry(name, proc_pnp_boot);
}
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH] PnP BIOS -- bugfix; update devlist on setpnp
2001-10-13 15:40 Thomas Hood
2001-10-15 6:37 ` Jurgen Botz
@ 2001-10-15 14:15 ` Ion Badulescu
2001-10-17 2:48 ` Steven A. DuChene
2 siblings, 0 replies; 14+ messages in thread
From: Ion Badulescu @ 2001-10-15 14:15 UTC (permalink / raw)
To: Thomas Hood; +Cc: linux-kernel, stelian.pop, sduchene, jurgen
On 13 Oct 2001, Thomas Hood wrote:
> Vaio users: Please make sure that this doesn't oops.
> Others: Try using setpnp to change the current configuration.
> Unload and reload the parport drivers to check that they
> reinitialize with the updated resource information provided
> by the PnP BIOS driver.
Works here on the inspiron 5k. Parport detects its config correctly, even
after multiple loads/unloads, lspnp and setpnp seem to be doing the right
thing, parport detects the new parameters after changing them with setpnp.
Relevant dmesg output:
PnPBIOS: Found PnP BIOS installation structure at 0xc00f7230.
PnPBIOS: PnP BIOS version 1.0, entry 0xf0000:0xa610, dseg 0x400.
PnPBIOS: 17 nodes reported by PnP BIOS; 17 recorded by driver.
PnPBIOS: PNP0c02: 0xfff80000-0xffffffff was already reserved
PnPBIOS: PNP0c01: 0xe8000-0xfffff was already reserved
PnPBIOS: PNP0c01: 0x100000-0xbffffff was already reserved
PnPBIOS: PNP0c02: 0x4d0-0x4d1 has been reserved
PnPBIOS: PNP0c02: 0x1000-0x103f has been reserved
PnPBIOS: PNP0c02: 0x1040-0x104f has been reserved
SBF: ACPI BOOT descriptor is wrong length (39)
SBF: Simple Boot Flag extension found and enabled.
SBF: Setting boot flags 0x1
parport: PnP BIOS reports device PNPBIOS PNP0401 (node number 0x16) is
configured to use io 0x0378, io 0x0778, irq 7, dma 3
[and then after 'setpnp 16 dma 1']
parport: PnP BIOS reports device PNPBIOS PNP0401 (node number 0x16) is
configured to use io 0x0378, io 0x0778, irq 7, dma 1
Thanks,
Ion
--
It is better to keep your mouth shut and be thought a fool,
than to open it and remove all doubt.
^ permalink raw reply [flat|nested] 14+ messages in thread* Re: [PATCH] PnP BIOS -- bugfix; update devlist on setpnp
2001-10-13 15:40 Thomas Hood
2001-10-15 6:37 ` Jurgen Botz
2001-10-15 14:15 ` Ion Badulescu
@ 2001-10-17 2:48 ` Steven A. DuChene
2 siblings, 0 replies; 14+ messages in thread
From: Steven A. DuChene @ 2001-10-17 2:48 UTC (permalink / raw)
To: Thomas Hood; +Cc: linux-kernel, stelian.pop, ion, sduchene, jurgen
Thomas:
Just to let you know I still have the same problem with a resource conflict
between the PnPBIOS code and the i2c/lm_sensors stuff at 1040 with this
latest patch. Again, this is on a Intel Lancewood (L440GX) motherboard.
I also have a system with a Intel STL2 motherboard (successor to the
Lancewood) so I will test that under the same conditions later tonight.
modprobe i2c-piix4
/lib/modules/2.4.10-ac12/kernel/drivers/i2c/i2c-piix4.o: init_module: No such device
Hint: insmod errors can be caused by incorrect module parameters, including invalid IO or IRQ parameters
/lib/modules/2.4.10-ac12/kernel/drivers/i2c/i2c-piix4.o: insmod /lib/modules/2.4.10-ac12/kernel/drivers/i2c/i2c-piix4.o failed
/lib/modules/2.4.10-ac12/kernel/drivers/i2c/i2c-piix4.o: insmod i2c-piix4 failed
dmesg
.
.
.
i2c-piix4.o version 2.6.1 (20010830)
i2c-piix4.o: Found PIIX4 device
i2c-piix4.o: SMB region 0x1040 already in use!
i2c-piix4.o: Device not detected, module not inserted.
cat /proc/ioports
.
.
.
0c00-0c3f : Intel Corporation 82371AB PIIX4 ACPI
0c00-0c3f : PnPBIOS PNP0c02
0ca0-0ca3 : PnPBIOS PNP0c02
0cb8-0cbf : PnPBIOS PNP0c02
0cf8-0cff : PCI conf1
1000-103f : PnPBIOS PNP0c02
1040-105f : Intel Corporation 82371AB PIIX4 ACPI
1040-104f : PnPBIOS PNP0c02
.
.
.
--
Steven A. DuChene sad@ale.org
linux-clusters@mindspring.com
sduchene@mindspring.com
http://www.mindspring.com/~sduchene/
^ permalink raw reply [flat|nested] 14+ messages in thread
end of thread, other threads:[~2001-10-17 20:59 UTC | newest]
Thread overview: 14+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2001-10-17 3:14 [PATCH] PnP BIOS -- bugfix; update devlist on setpnp Thomas Hood
2001-10-17 8:10 ` Steven A. DuChene
2001-10-17 13:35 ` Thomas Hood
2001-10-17 16:08 ` Steven A. DuChene
2001-10-17 16:04 ` Gunther Mayer
2001-10-17 20:58 ` Thomas Hood
-- strict thread matches above, loose matches on Subject: below --
2001-10-13 15:40 Thomas Hood
2001-10-15 6:37 ` Jurgen Botz
2001-10-15 9:45 ` Stelian Pop
2001-10-15 12:01 ` Andrey Panin
2001-10-15 12:25 ` Alan Cox
2001-10-15 21:49 ` Thomas Hood
2001-10-15 14:15 ` Ion Badulescu
2001-10-17 2:48 ` Steven A. DuChene
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox