ChangeSet 1.853.1.1, 2002/11/11 17:47:38-08:00, ambx1@neo.rr.com

[PATCH] PnP BIOS fixes - 2.5.46 (1/6)

This Patch should at least partially fix the problems caused by broken PnP
BIOSes.  More fixes will come later but this should boot.  Please report general
protection faults.  The PnP BIOS proc interface may still not work if you have a
broken PnP BIOS.  Also adds basic support for PnP BIOS flags and removes some
currently unused stuff.


diff -Nru a/drivers/pnp/pnpbios/core.c b/drivers/pnp/pnpbios/core.c
--- a/drivers/pnp/pnpbios/core.c	Tue Nov 12 11:14:20 2002
+++ b/drivers/pnp/pnpbios/core.c	Tue Nov 12 11:14:20 2002
@@ -1256,6 +1256,12 @@
 	struct pnp_dev_node_info node_info;
 	u8 nodenum = dev->number;
 	struct pnp_bios_node * node;
+
+	/* just in case */
+	if(dev->driver)
+		return -EBUSY;
+	if(!pnp_is_dynamic(dev))
+		return -EPERM;
 	if (pnp_bios_dev_node_info(&node_info) != 0)
 		return -ENODEV;
 	node = pnpbios_kmalloc(node_info.max_node_size, GFP_KERNEL);
@@ -1273,8 +1279,13 @@
 	struct pnp_dev_node_info node_info;
 	u8 nodenum = dev->number;
 	struct pnp_bios_node * node;
-	node = pnpbios_kmalloc(node_info.max_node_size, GFP_KERNEL);
 
+	/* just in case */
+	if(dev->driver)
+		return -EBUSY;
+	if (flags == PNP_DYNAMIC && !pnp_is_dynamic(dev))
+		return -EPERM;
+	node = pnpbios_kmalloc(node_info.max_node_size, GFP_KERNEL);
 	if (pnp_bios_dev_node_info(&node_info) != 0)
 		return -ENODEV;
 	if (!node)
@@ -1323,6 +1334,11 @@
 	struct pnp_bios_node * node;
 	if (!config)
 		return -1;
+	/* just in case */
+	if(dev->driver)
+		return -EBUSY;
+	if(dev->flags & PNP_NO_DISABLE || !pnp_is_dynamic(dev))
+		return -EPERM;
 	memset(config, 0, sizeof(struct pnp_cfg));
 	if (!dev || !dev->active)
 		return -EINVAL;
@@ -1402,10 +1418,13 @@
 	for(nodenum=0; nodenum<0xff; ) {
 		u8 thisnodenum = nodenum;
 		/* We build the list from the "boot" config because
-		 * asking for the "current" config causes some
-		 * BIOSes to crash.
+		 * we know that the resources couldn't have changed
+		 * at this stage.  Furthermore some buggy PnP BIOSes
+		 * will crash if we request the "current" config
+		 * from devices that are can only be static such as
+		 * those controlled by the "system" driver.
 		 */
-		if (pnp_bios_get_dev_node(&nodenum, (char )0 , node))
+		if (pnp_bios_get_dev_node(&nodenum, (char )1, node))
 			break;
 		nodes_got++;
 		dev =  pnpbios_kmalloc(sizeof (struct pnp_dev), GFP_KERNEL);
@@ -1426,6 +1445,7 @@
 		pos = node_current_resource_data_to_dev(node,dev);
 		pos = node_possible_resource_data_to_dev(pos,node,dev);
 		node_id_data_to_dev(pos,node,dev);
+		dev->flags = node->flags;
 
 		dev->protocol = &pnpbios_protocol;
 
@@ -1450,10 +1470,7 @@
  *
  */
 
-extern int is_sony_vaio_laptop;
-
 static int pnpbios_disabled; /* = 0 */
-static int dont_reserve_resources; /* = 0 */
 int pnpbios_dont_use_current_config; /* = 0 */
 
 #ifndef MODULE
@@ -1471,8 +1488,6 @@
 			str += 3;
 		if (strncmp(str, "curr", 4) == 0)
 			pnpbios_dont_use_current_config = invert;
-		if (strncmp(str, "res", 3) == 0)
-			dont_reserve_resources = invert;
 		str = strchr(str, ',');
 		if (str != NULL)
 			str += strspn(str, ", \t");
@@ -1498,9 +1513,6 @@
 		printk(KERN_INFO "PnPBIOS: Disabled\n");
 		return -ENODEV;
 	}
-
-	if ( is_sony_vaio_laptop )
-		pnpbios_dont_use_current_config = 1;
 
 	/*
  	 * Search the defined area (0xf0000-0xffff0) for a valid PnP BIOS
diff -Nru a/include/linux/pnp.h b/include/linux/pnp.h
--- a/include/linux/pnp.h	Tue Nov 12 11:14:20 2002
+++ b/include/linux/pnp.h	Tue Nov 12 11:14:20 2002
@@ -53,6 +53,7 @@
 	struct	device	    dev;	/* Driver Model device interface */
 	void  		  * driver_data;/* data private to the driver */
 	void		  * protocol_data;
+	int		    flags;	/* used by protocols */
 	struct proc_dir_entry *procent;	/* device entry in /proc/bus/isapnp */
 };
 
@@ -108,7 +109,7 @@
 #define DEV_DMA(dev, index) (dev->dma_resource[index].start)
 
 #define PNP_PORT_FLAG_16BITADDR	(1<<0)
-#define PNP_PORT_FLAG_FIXED		(1<<1)
+#define PNP_PORT_FLAG_FIXED	(1<<1)
 
 struct pnp_port {
 	unsigned short min;		/* min base number */
diff -Nru a/include/linux/pnpbios.h b/include/linux/pnpbios.h
--- a/include/linux/pnpbios.h	Tue Nov 12 11:14:20 2002
+++ b/include/linux/pnpbios.h	Tue Nov 12 11:14:20 2002
@@ -75,6 +75,19 @@
 #define PNPMSG_POWER_OFF		0x41
 #define PNPMSG_PNP_OS_ACTIVE		0x42
 #define PNPMSG_PNP_OS_INACTIVE		0x43
+/*
+ * Plug and Play BIOS flags
+ */
+#define PNP_NO_DISABLE		0x0001
+#define PNP_NO_CONFIG		0x0002
+#define PNP_OUTPUT		0x0004
+#define PNP_INPUT		0x0008
+#define PNP_BOOTABLE		0x0010
+#define PNP_DOCK		0x0020
+#define PNP_REMOVABLE		0x0040
+#define pnp_is_static(x) (x->flags & 0x0100) == 0x0000
+#define pnp_is_dynamic(x) x->flags & 0x0080
+
 /* 0x8000 through 0xffff are OEM defined */
 
 #pragma pack(1)
