public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
* PnP BIOS driver status
@ 2002-03-08 23:00 Thomas Hood
  2002-03-08 23:14 ` Dave Jones
  2002-03-09  1:00 ` Brian Gerst
  0 siblings, 2 replies; 16+ messages in thread
From: Thomas Hood @ 2002-03-08 23:00 UTC (permalink / raw)
  To: linux-kernel

A couple people have asked me about the status of the 
PnP BIOS driver, so I thought I'd post an update. 

History: During the pre-Tosatti 2.4-ac series the driver was 
hammered into a reliable form.  However it never entered the 
mainline kernel series. 

The driver was then stripped down to the core functionality 
required to make the lspnp and setpnp utilities work. 
pnpbios_register_driver() and pnpbios_unregister_driver() are 
still there but aren't used by anything.  Additional /proc/ 
interface files were then added to allow reading of ESCD info. 

The latest version of the driver seems nice 'n' stable and can 
be found in Alan's latest 2.4 patches. 

Current 2.5 kernels also contain the driver, but it's a bit out 
of date.  There's a patch in 2.5-dj but that's also out of date. 
("Out of date" here means "missing new features and some 
cleanups".)  Once DJ releases a 2.5.6-dj I'll send him a patch 
to bring his tree up to date.  Then he can pass it on to Linus. 

-- 
Thomas Hood


^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: PnP BIOS driver status
  2002-03-08 23:00 PnP BIOS driver status Thomas Hood
@ 2002-03-08 23:14 ` Dave Jones
  2002-03-09  0:43   ` Thomas Hood
  2002-03-09  1:00 ` Brian Gerst
  1 sibling, 1 reply; 16+ messages in thread
From: Dave Jones @ 2002-03-08 23:14 UTC (permalink / raw)
  To: Thomas Hood; +Cc: linux-kernel

On Fri, Mar 08, 2002 at 06:00:40PM -0500, Thomas Hood wrote:
 
 > Current 2.5 kernels also contain the driver, but it's a bit out 
 > of date.  There's a patch in 2.5-dj but that's also out of date. 
 > ("Out of date" here means "missing new features and some 
 > cleanups".)

 The bits that handle ESCD ? I merged that.
 
 > Once DJ releases a 2.5.6-dj I'll send him a patch 
 > to bring his tree up to date.  Then he can pass it on to Linus. 

 You may have to wait a while. Most of my life just got packed
 into boxes, and is about to go out the door to a new home.
 It'll take a week or so to get back on my feet.

-- 
| Dave Jones.        http://www.codemonkey.org.uk
| SuSE Labs

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: PnP BIOS driver status
  2002-03-08 23:14 ` Dave Jones
@ 2002-03-09  0:43   ` Thomas Hood
  0 siblings, 0 replies; 16+ messages in thread
From: Thomas Hood @ 2002-03-09  0:43 UTC (permalink / raw)
  To: Dave Jones; +Cc: linux-kernel

On Fri, 2002-03-08 at 18:14, Dave Jones wrote:
>  The bits that handle ESCD ? I merged that.

Here are the additional bits from the -ac tree, diffed
against 2.5.6 + 2.5.5-dj3 patch.  The changes include:

- Improve some comments
- Postpone starting the kernel thread (Alan Cox)
- Call kernel thread 'kpnpbiosd' instead of 'kpnpbios'
- Consolidate printing of error messages to save space
- Add __init and __exit tags and return appropriate error codes
- Print slightly more consistent messages
- Get closer to supporting build-as-module

--
Thomas

--- linux-2.5.6_2.5.5-dj3/include/linux/pnpbios.h_DJ	Fri Mar  8 18:37:58 2002
+++ linux-2.5.6_2.5.5-dj3/include/linux/pnpbios.h	Fri Mar  8 19:12:25 2002
@@ -143,7 +143,8 @@
 extern int  pnpbios_dont_use_current_config;
 extern void *pnpbios_kmalloc(size_t size, int f);
 extern int pnpbios_init (void);
-extern void pnpbios_proc_init (void);
+extern int pnpbios_proc_init (void);
+extern void pnpbios_proc_exit (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);
--- linux-2.5.6_2.5.5-dj3/drivers/pnp/pnpbios_core.c_DJ	Fri Mar  8 18:40:02 2002
+++ linux-2.5.6_2.5.5-dj3/drivers/pnp/pnpbios_core.c	Fri Mar  8 19:09:39 2002
@@ -4,7 +4,7 @@
  * Originally (C) 1998 Christian Schmidt <schmidt@digadd.de>
  * Modifications (c) 1998 Tom Lees <tom@lpsg.demon.co.uk>
  * Minor reorganizations by David Hinds <dahinds@users.sourceforge.net>
- * Modifications (c) 2001 by Thomas Hood <jdthood@mail.com>
+ * Modifications (c) 2001,2002 by Thomas Hood <jdthood@mail.com>
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by the
@@ -205,6 +205,11 @@
  *
  */
 
+static void pnpbios_warn_unexpected_status(const char * module, u16 status)
+{
+	printk(KERN_ERR "PnPBIOS: %s: Unexpected status 0x%x\n", module, status);
+}
+
 void *pnpbios_kmalloc(size_t size, int f)
 {
 	void *p = kmalloc( size, f );
@@ -251,7 +256,7 @@
 static int __pnp_bios_dev_node_info(struct pnp_dev_node_info *data)
 {
 	u16 status;
-	if (!pnp_bios_present ())
+	if (!pnp_bios_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);
@@ -263,7 +268,7 @@
 {
 	int status = __pnp_bios_dev_node_info( data );
 	if ( status )
-		printk(KERN_WARNING "PnPBIOS: dev_node_info: Unexpected status 0x%x\n", status);
+		pnpbios_warn_unexpected_status( "dev_node_info", status );
 	return status;
 }
 
@@ -284,7 +289,7 @@
 static int __pnp_bios_get_dev_node(u8 *nodenum, char boot, struct pnp_bios_node *data)
 {
 	u16 status;
-	if (!pnp_bios_present ())
+	if (!pnp_bios_present())
 		return PNP_FUNCTION_NOT_SUPPORTED;
 	if ( !boot & pnpbios_dont_use_current_config )
 		return PNP_FUNCTION_NOT_SUPPORTED;
@@ -299,7 +304,7 @@
 	int status;
 	status =  __pnp_bios_get_dev_node( nodenum, boot, data );
 	if ( status )
-		printk(KERN_WARNING "PnPBIOS: get_dev_node: Unexpected status 0x%x\n", status);
+		pnpbios_warn_unexpected_status( "get_dev_node", status );
 	return status;
 }
 
@@ -313,7 +318,7 @@
 static int __pnp_bios_set_dev_node(u8 nodenum, char boot, struct pnp_bios_node *data)
 {
 	u16 status;
-	if (!pnp_bios_present ())
+	if (!pnp_bios_present())
 		return PNP_FUNCTION_NOT_SUPPORTED;
 	if ( !boot & pnpbios_dont_use_current_config )
 		return PNP_FUNCTION_NOT_SUPPORTED;
@@ -327,7 +332,7 @@
 	int status;
 	status =  __pnp_bios_set_dev_node( nodenum, boot, data );
 	if ( status ) {
-		printk(KERN_WARNING "PnPBIOS: set_dev_node: Unexpected status 0x%x\n", status);
+		pnpbios_warn_unexpected_status( "set_dev_node", status );
 		return status;
 	}
 	if ( !boot ) { /* Update devlist */
@@ -347,7 +352,7 @@
 static int pnp_bios_get_event(u16 *event)
 {
 	u16 status;
-	if (!pnp_bios_present ())
+	if (!pnp_bios_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);
@@ -362,7 +367,7 @@
 static int pnp_bios_send_message(u16 message)
 {
 	u16 status;
-	if (!pnp_bios_present ())
+	if (!pnp_bios_present())
 		return PNP_FUNCTION_NOT_SUPPORTED;
 	status = call_pnp_bios(PNP_SEND_MESSAGE, message, PNP_DS, 0, 0, 0, 0, 0);
 	return status;
@@ -376,7 +381,7 @@
 static int pnp_bios_dock_station_info(struct pnp_docking_station_info *data)
 {
 	u16 status;
-	if (!pnp_bios_present ())
+	if (!pnp_bios_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);
@@ -392,7 +397,7 @@
 static int pnp_bios_set_stat_res(char *info)
 {
 	u16 status;
-	if (!pnp_bios_present ())
+	if (!pnp_bios_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);
@@ -407,7 +412,7 @@
 static int __pnp_bios_get_stat_res(char *info)
 {
 	u16 status;
-	if (!pnp_bios_present ())
+	if (!pnp_bios_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);
@@ -419,7 +424,7 @@
 	int status;
 	status = __pnp_bios_get_stat_res( info );
 	if ( status )
-		printk(KERN_WARNING "PnPBIOS: get_stat_res: Unexpected status 0x%x\n", status);
+		pnpbios_warn_unexpected_status( "get_stat_res", status );
 	return status;
 }
 
@@ -430,7 +435,7 @@
 static int pnp_bios_apm_id_table(char *table, u16 *size)
 {
 	u16 status;
-	if (!pnp_bios_present ())
+	if (!pnp_bios_present())
 		return PNP_FUNCTION_NOT_SUPPORTED;
 	Q2_SET_SEL(PNP_TS1, table, *size);
 	Q2_SET_SEL(PNP_TS2, size, sizeof(u16));
@@ -445,7 +450,7 @@
 static int __pnp_bios_isapnp_config(struct pnp_isa_config_struc *data)
 {
 	u16 status;
-	if (!pnp_bios_present ())
+	if (!pnp_bios_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);
@@ -457,7 +462,7 @@
 	int status;
 	status = __pnp_bios_isapnp_config( data );
 	if ( status )
-		printk(KERN_WARNING "PnPBIOS: isapnp_config: Unexpected status 0x%x\n", status);
+		pnpbios_warn_unexpected_status( "isapnp_config", status );
 	return status;
 }
 
@@ -467,7 +472,7 @@
 static int __pnp_bios_escd_info(struct escd_info_struc *data)
 {
 	u16 status;
-	if (!pnp_bios_present ())
+	if (!pnp_bios_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);
@@ -479,7 +484,7 @@
 	int status;
 	status = __pnp_bios_escd_info( data );
 	if ( status )
-		printk(KERN_WARNING "PnPBIOS: escd_info: Unexpected status 0x%x\n", status);
+		pnpbios_warn_unexpected_status( "escd_info", status );
 	return status;
 }
 
@@ -490,7 +495,7 @@
 static int __pnp_bios_read_escd(char *data, u32 nvram_base)
 {
 	u16 status;
-	if (!pnp_bios_present ())
+	if (!pnp_bios_present())
 		return ESCD_FUNCTION_NOT_SUPPORTED;
 	Q2_SET_SEL(PNP_TS1, data, 64 * 1024);
 	set_base(gdt[PNP_TS2 >> 3], nvram_base);
@@ -504,7 +509,7 @@
 	int status;
 	status = __pnp_bios_read_escd( data, nvram_base );
 	if ( status )
-		printk(KERN_ERR "PnPBIOS: read_escd: Unexpected status 0x%x\n", status);
+		pnpbios_warn_unexpected_status( "read_escd", status );
 	return status;
 }
 
@@ -515,7 +520,7 @@
 static int pnp_bios_write_escd(char *data, u32 nvram_base)
 {
 	u16 status;
-	if (!pnp_bios_present ())
+	if (!pnp_bios_present())
 		return ESCD_FUNCTION_NOT_SUPPORTED;
 	Q2_SET_SEL(PNP_TS1, data, 64 * 1024);
 	set_base(gdt[PNP_TS2 >> 3], nvram_base);
@@ -602,10 +607,10 @@
 	int docked = -1, d = 0;
 	daemonize();
 	reparent_to_init();
-	strcpy(current->comm, "kpnpbios");
+	strcpy(current->comm, "kpnpbiosd");
 	while(!unloading && !signal_pending(current))
 	{
-		int err;
+		int status;
 		
 		/*
 		 * Poll every 2 seconds
@@ -615,9 +620,9 @@
 		if(signal_pending(current))
 			break;
 
-		err = pnp_bios_dock_station_info(&now);
+		status = pnp_bios_dock_station_info(&now);
 
-		switch(err)
+		switch(status)
 		{
 			/*
 			 * No dock to manage
@@ -631,7 +636,7 @@
 				d = 1;
 				break;
 			default:
-				printk(KERN_WARNING "PnPBIOS: pnp_dock_thread: Unexpected status 0x%x\n", err);
+				pnpbios_warn_unexpected_status( "pnp_dock_thread", status );
 				continue;
 		}
 		if(d != docked)
@@ -874,13 +879,13 @@
 static void __init build_devlist(void)
 {
 	u8 nodenum;
-	int nodes_got = 0;
-	int devs = 0;
+	unsigned int nodes_got = 0;
+	unsigned int devs = 0;
 	struct pnp_bios_node *node;
 	struct pnp_dev_node_info node_info;
 	struct pci_dev *dev;
 	
-	if (!pnp_bios_present ())
+	if (!pnp_bios_present())
 		return;
 
 	if (pnp_bios_dev_node_info(&node_info) != 0)
@@ -912,7 +917,7 @@
 		else
 			devs++;
 		if (nodenum <= thisnodenum) {
-			printk(KERN_ERR "PnPBIOS: build_devlist(): Node number 0x%x is out of sequence following node 0x%x. Aborting.\n", (int)nodenum, (int)thisnodenum);
+			printk(KERN_ERR "PnPBIOS: build_devlist: Node number 0x%x is out of sequence following node 0x%x. Aborting.\n", (unsigned int)nodenum, (unsigned int)thisnodenum);
 			break;
 		}
 	}
@@ -1215,14 +1220,14 @@
 {
 	union pnp_bios_expansion_header *check;
 	u8 sum;
-	int i, length;
+	int i, length, r;
 
 	spin_lock_init(&pnp_bios_lock);
 	spin_lock_init(&pnpbios_devices_lock);
 
 	if(pnpbios_disabled) {
 		printk(KERN_INFO "PnPBIOS: Disabled\n");
-		return 0;
+		return -ENODEV;
 	}
 
 	if ( is_sony_vaio_laptop )
@@ -1264,12 +1269,21 @@
 		pnp_bios_hdr = check;
 		break;
 	}
+	if (!pnp_bios_present())
+		return -ENODEV;
 	build_devlist();
 	if ( ! dont_reserve_resources )
 		reserve_resources();
 #ifdef CONFIG_PROC_FS
-	pnpbios_proc_init();
+	r = pnpbios_proc_init();
+	if (r)
+		return r;
 #endif
+	return 0;
+}
+
+static int __init pnpbios_thread_init(void)
+{
 #ifdef CONFIG_HOTPLUG	
 	init_completion(&unload_sem);
 	if(kernel_thread(pnp_dock_thread, NULL, CLONE_FS | CLONE_FILES | CLONE_SIGNAL)>0)
@@ -1278,23 +1292,46 @@
 	return 0;
 }
 
-#ifdef MODULE
+#ifndef MODULE
+
+/* init/main.c calls pnpbios_init early */
+
+/* Start the kernel thread later: */
+module_init(pnpbios_thread_init);
+
+#else
+
+/*
+ * N.B.: Building pnpbios as a module hasn't been fully implemented
+ */
 
 MODULE_LICENSE("GPL");
 
-/* We have to run it early and not as a module. */
-module_init(pnpbios_init);
+static int __init pnpbios_init_all(void)
+{
+	int r;
 
-#ifdef CONFIG_HOTPLUG
-static void pnpbios_exit(void)
+	r = pnpbios_init();
+	if (r)
+		return r;
+	r = pnpbios_thread_init();
+	if (r)
+		return r;
+	return 0;
+}
+
+static void __exit pnpbios_exit(void)
 {
-	/* free_resources() ought to go here */
-	/* pnpbios_proc_done() */
+#ifdef CONFIG_HOTPLUG
 	unloading = 1;
 	wait_for_completion(&unload_sem);
+#endif
+	pnpbios_proc_exit();
+	/* We ought to free resources here */
+	return;
 }
 
+module_init(pnpbios_init_all);
 module_exit(pnpbios_exit);
 
-#endif
 #endif
--- linux-2.5.6_2.5.5-dj3/drivers/pnp/pnpbios_proc.c_DJ	Fri Mar  8 18:37:58 2002
+++ linux-2.5.6_2.5.5-dj3/drivers/pnp/pnpbios_proc.c	Fri Mar  8 19:10:32 2002
@@ -2,7 +2,20 @@
  * /proc/bus/pnp interface for Plug and Play devices
  *
  * Written by David Hinds, dahinds@users.sourceforge.net
- * Modified by Thomas Hood, jdthood_AT_mail.com
+ * Modified by Thomas Hood, jdthood@mail.com
+ *
+ * The .../devices and .../<node> and .../boot/<node> files are
+ * utilized by the lspnp and setpnp utilities, supplied with the
+ * pcmcia-cs package.
+ *     http://pcmcia-cs.sourceforge.net
+ *
+ * The .../escd file is utilized by the lsescd utility written by
+ * Gunther Mayer.
+ *     http://home.t-online.de/home/gunther.mayer/lsescd
+ *
+ * The .../legacy_device_resources file is not used yet.
+ *
+ * The other files are human-readable.
  */
 
 //#include <pcmcia/config.h>
@@ -66,7 +79,7 @@
 
 	/* sanity check */
 	if (escd.escd_size > (32*1024)) {
-		printk(KERN_ERR "PnPBIOS: Error: ESCD size is too great\n");
+		printk(KERN_ERR "PnPBIOS: proc_read_escd: ESCD size is too great\n");
 		return -EFBIG;
 	}
 
@@ -122,7 +135,7 @@
 			     node->type_code[0], node->type_code[1],
 			     node->type_code[2], node->flags);
 		if (nodenum <= thisnodenum) {
-			printk(KERN_ERR "PnPBIOS: proc_read_devices(): Node number 0x%x is out of sequence following node 0x%x. Aborting.\n", (int)nodenum, (int)thisnodenum);
+			printk(KERN_ERR "%s Node number 0x%x is out of sequence following node 0x%x. Aborting.\n", "PnPBIOS: proc_read_devices:", (unsigned int)nodenum, (unsigned int)thisnodenum);
 			*eof = 1;
 			break;
 		}
@@ -177,20 +190,22 @@
  * work and the pnpbios_dont_use_current_config flag
  * should already have been set to the appropriate value
  */
-void pnpbios_proc_init( void )
+int __init pnpbios_proc_init( void )
 {
 	struct pnp_bios_node *node;
 	struct proc_dir_entry *ent;
 	char name[3];
-	int i;
 	u8 nodenum;
 
-	if (pnp_bios_dev_node_info(&node_info) != 0) return;
+	if (pnp_bios_dev_node_info(&node_info))
+		return -EIO;
 	
 	proc_pnp = proc_mkdir("pnp", proc_bus);
-	if (!proc_pnp) return;
+	if (!proc_pnp)
+		return -EIO;
 	proc_pnp_boot = proc_mkdir("boot", proc_pnp);
-	if (!proc_pnp_boot) return;
+	if (!proc_pnp_boot)
+		return -EIO;
 	create_proc_read_entry("devices", 0, proc_pnp, proc_read_devices, NULL);
 	create_proc_read_entry("configuration_info", 0, proc_pnp, proc_read_pnpconfig, NULL);
 	create_proc_read_entry("escd_info", 0, proc_pnp, proc_read_escdinfo, NULL);
@@ -198,8 +213,11 @@
 	create_proc_read_entry("legacy_device_resources", 0, proc_pnp, proc_read_legacyres, NULL);
 	
 	node = pnpbios_kmalloc(node_info.max_node_size, GFP_KERNEL);
-	if (!node) return;
-	for (i=0,nodenum = 0; i<0xff && nodenum != 0xff; i++) {
+	if (!node)
+		return -ENOMEM;
+
+	for (nodenum=0; nodenum<0xff; ) {
+		u8 thisnodenum = nodenum;
 		if (pnp_bios_get_dev_node(&nodenum, 1, node) != 0)
 			break;
 		sprintf(name, "%02x", node->handle);
@@ -217,11 +235,17 @@
 			ent->write_proc = proc_write_node;
 			ent->data = (void *)(long)(node->handle+0x100);
 		}
+		if (nodenum <= thisnodenum) {
+			printk(KERN_ERR "%s Node number 0x%x is out of sequence following node 0x%x. Aborting.\n", "PnPBIOS: proc_init:", (unsigned int)nodenum, (unsigned int)thisnodenum);
+			break;
+		}
 	}
 	kfree(node);
+
+	return 0;
 }
 
-void pnpbios_proc_done(void)
+void __exit pnpbios_proc_exit(void)
 {
 	int i;
 	char name[3];
@@ -241,4 +265,6 @@
 	remove_proc_entry("devices", proc_pnp);
 	remove_proc_entry("boot", proc_pnp);
 	remove_proc_entry("pnp", proc_bus);
+
+	return;
 }


^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: PnP BIOS driver status
  2002-03-08 23:00 PnP BIOS driver status Thomas Hood
  2002-03-08 23:14 ` Dave Jones
@ 2002-03-09  1:00 ` Brian Gerst
  2002-03-09  1:10   ` Thomas Hood
  2002-03-09  1:25   ` Alan Cox
  1 sibling, 2 replies; 16+ messages in thread
From: Brian Gerst @ 2002-03-09  1:00 UTC (permalink / raw)
  To: Thomas Hood; +Cc: linux-kernel

Thomas Hood wrote:
> 
> A couple people have asked me about the status of the
> PnP BIOS driver, so I thought I'd post an update.
> 
> History: During the pre-Tosatti 2.4-ac series the driver was
> hammered into a reliable form.  However it never entered the
> mainline kernel series.
> 
> The driver was then stripped down to the core functionality
> required to make the lspnp and setpnp utilities work.
> pnpbios_register_driver() and pnpbios_unregister_driver() are
> still there but aren't used by anything.  Additional /proc/
> interface files were then added to allow reading of ESCD info.
> 
> The latest version of the driver seems nice 'n' stable and can
> be found in Alan's latest 2.4 patches.
> 
> Current 2.5 kernels also contain the driver, but it's a bit out
> of date.  There's a patch in 2.5-dj but that's also out of date.
> ("Out of date" here means "missing new features and some
> cleanups".)  Once DJ releases a 2.5.6-dj I'll send him a patch
> to bring his tree up to date.  Then he can pass it on to Linus.

The current driver is not SMP-safe.  It is modifying the GDT descriptors
outside of the pnp_bios_lock.  Also, you can remove the __cli(), as
spin_lock_irq() already turns off interrupts.

-- 

						Brian Gerst

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: PnP BIOS driver status
  2002-03-09  1:00 ` Brian Gerst
@ 2002-03-09  1:10   ` Thomas Hood
  2002-03-09  2:23     ` Brian Gerst
  2002-03-09  1:25   ` Alan Cox
  1 sibling, 1 reply; 16+ messages in thread
From: Thomas Hood @ 2002-03-09  1:10 UTC (permalink / raw)
  To: Brian Gerst; +Cc: linux-kernel

On Fri, 2002-03-08 at 20:00, Brian Gerst wrote:
> The current driver is not SMP-safe.

That's true.

> It is modifying the GDT descriptors
> outside of the pnp_bios_lock.  Also, you can remove the __cli(), as
> spin_lock_irq() already turns off interrupts.

I'd welcome a patch like the return of a kidnapped pet.

--
Thomas


^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: PnP BIOS driver status
  2002-03-09  1:00 ` Brian Gerst
  2002-03-09  1:10   ` Thomas Hood
@ 2002-03-09  1:25   ` Alan Cox
  2002-03-09  1:37     ` Brian Gerst
  1 sibling, 1 reply; 16+ messages in thread
From: Alan Cox @ 2002-03-09  1:25 UTC (permalink / raw)
  To: Brian Gerst; +Cc: Thomas Hood, linux-kernel

> The current driver is not SMP-safe.  It is modifying the GDT descriptors
> outside of the pnp_bios_lock.  Also, you can remove the __cli(), as
> spin_lock_irq() already turns off interrupts.

The GDT descriptors are private to the PNP BIOS and constant values once
set up. No PnPBIOS call is made before the configuration is done.

Seems ok to me - or am I missing something ?

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: PnP BIOS driver status
  2002-03-09  1:25   ` Alan Cox
@ 2002-03-09  1:37     ` Brian Gerst
  2002-03-09  2:00       ` Alan Cox
  0 siblings, 1 reply; 16+ messages in thread
From: Brian Gerst @ 2002-03-09  1:37 UTC (permalink / raw)
  To: Alan Cox; +Cc: Thomas Hood, linux-kernel

Alan Cox wrote:
> 
> > The current driver is not SMP-safe.  It is modifying the GDT descriptors
> > outside of the pnp_bios_lock.  Also, you can remove the __cli(), as
> > spin_lock_irq() already turns off interrupts.
> 
> The GDT descriptors are private to the PNP BIOS and constant values once
> set up. No PnPBIOS call is made before the configuration is done.
> 
> Seems ok to me - or am I missing something ?

Two user processes calling functions through /proc...

-- 

						Brian Gerst

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: PnP BIOS driver status
  2002-03-09  2:00       ` Alan Cox
@ 2002-03-09  1:51         ` Brian Gerst
  2002-03-09  2:26           ` Alan Cox
  0 siblings, 1 reply; 16+ messages in thread
From: Brian Gerst @ 2002-03-09  1:51 UTC (permalink / raw)
  To: Alan Cox; +Cc: Thomas Hood, linux-kernel

Alan Cox wrote:
> 
> > > The GDT descriptors are private to the PNP BIOS and constant values once
> > > set up. No PnPBIOS call is made before the configuration is done.
> > >
> > > Seems ok to me - or am I missing something ?
> >
> > Two user processes calling functions through /proc...
> 
> The GDT descriptors are set up before /proc comes into being. I'm checking
> 2.4 code here - has someone left old stuff in 2.5 ?

PNP_TS1 and PNP_TS2 are changed on every call to the bios to point to
where the data for the 32-bit code lives.

-- 

						Brian Gerst

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: PnP BIOS driver status
  2002-03-09  1:37     ` Brian Gerst
@ 2002-03-09  2:00       ` Alan Cox
  2002-03-09  1:51         ` Brian Gerst
  0 siblings, 1 reply; 16+ messages in thread
From: Alan Cox @ 2002-03-09  2:00 UTC (permalink / raw)
  To: Brian Gerst; +Cc: Alan Cox, Thomas Hood, linux-kernel

> > The GDT descriptors are private to the PNP BIOS and constant values once
> > set up. No PnPBIOS call is made before the configuration is done.
> > 
> > Seems ok to me - or am I missing something ?
> 
> Two user processes calling functions through /proc...

The GDT descriptors are set up before /proc comes into being. I'm checking
2.4 code here - has someone left old stuff in 2.5 ?

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: PnP BIOS driver status
  2002-03-09  1:10   ` Thomas Hood
@ 2002-03-09  2:23     ` Brian Gerst
  2002-03-09  3:02       ` Thomas Hood
  0 siblings, 1 reply; 16+ messages in thread
From: Brian Gerst @ 2002-03-09  2:23 UTC (permalink / raw)
  To: Thomas Hood; +Cc: linux-kernel

[-- Attachment #1: Type: text/plain, Size: 421 bytes --]

Thomas Hood wrote:
> 
> On Fri, 2002-03-08 at 20:00, Brian Gerst wrote:
> > The current driver is not SMP-safe.
> 
> That's true.
> 
> > It is modifying the GDT descriptors
> > outside of the pnp_bios_lock.  Also, you can remove the __cli(), as
> > spin_lock_irq() already turns off interrupts.
> 
> I'd welcome a patch like the return of a kidnapped pet.

How does this patch look?  Against 2.5.6

-- 

						Brian Gerst

[-- Attachment #2: pnpbios-segs-1 --]
[-- Type: text/plain, Size: 6363 bytes --]

diff -urN linux-2.5.6/drivers/pnp/pnpbios_core.c linux/drivers/pnp/pnpbios_core.c
--- linux-2.5.6/drivers/pnp/pnpbios_core.c	Fri Mar  8 07:51:30 2002
+++ linux/drivers/pnp/pnpbios_core.c	Fri Mar  8 21:15:58 2002
@@ -141,7 +141,9 @@
 static spinlock_t pnp_bios_lock;
 
 static inline u16 call_pnp_bios(u16 func, u16 arg1, u16 arg2, u16 arg3,
-                                u16 arg4, u16 arg5, u16 arg6, u16 arg7)
+				u16 arg4, u16 arg5, u16 arg6, u16 arg7,
+				void *ts1_base, u32 ts1_size,
+				void *ts2_base, u32 ts2_size)
 {
 	unsigned long flags;
 	u16 status;
@@ -155,7 +157,12 @@
 
 	/* On some boxes IRQ's during PnP BIOS calls are deadly.  */
 	spin_lock_irqsave(&pnp_bios_lock, flags);
-	__cli();
+
+	if (ts1_size)
+		Q2_SET_SEL(PNP_TS1, ts1_base, ts1_size);
+	if (ts2_size)
+		Q2_SET_SEL(PNP_TS2, ts2_base, ts2_size);
+
 	__asm__ __volatile__(
 	        "pushl %%ebp\n\t"
 		"pushl %%edi\n\t"
@@ -253,8 +260,8 @@
 	u16 status;
 	if (!pnp_bios_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);
+	status = call_pnp_bios(PNP_GET_NUM_SYS_DEV_NODES, 0, PNP_TS1, 2, PNP_TS1, PNP_DS, 0, 0,
+			       data, sizeof(struct pnp_dev_node_info), 0, 0);
 	data->no_nodes &= 0xff;
 	return status;
 }
@@ -288,9 +295,8 @@
 		return PNP_FUNCTION_NOT_SUPPORTED;
 	if ( !boot & pnpbios_dont_use_current_config )
 		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);
+	status = call_pnp_bios(PNP_GET_SYS_DEV_NODE, 0, PNP_TS1, 0, PNP_TS2, boot ? 2 : 1, PNP_DS, 0,
+			       nodenum, sizeof(char), data, 65536);
 	return status;
 }
 
@@ -317,8 +323,8 @@
 		return PNP_FUNCTION_NOT_SUPPORTED;
 	if ( !boot & pnpbios_dont_use_current_config )
 		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);
+	status = call_pnp_bios(PNP_SET_SYS_DEV_NODE, nodenum, 0, PNP_TS1, boot ? 2 : 1, PNP_DS, 0, 0,
+			       data, 65536, 0, 0);
 	return status;
 }
 
@@ -352,8 +358,8 @@
 	u16 status;
 	if (!pnp_bios_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);
+	status = call_pnp_bios(PNP_GET_EVENT, 0, PNP_TS1, PNP_DS, 0, 0 ,0 ,0,
+			       event, sizeof(u16), 0, 0);
 	return status;
 }
 #endif
@@ -367,7 +373,7 @@
 	u16 status;
 	if (!pnp_bios_present ())
 		return PNP_FUNCTION_NOT_SUPPORTED;
-	status = call_pnp_bios(PNP_SEND_MESSAGE, message, PNP_DS, 0, 0, 0, 0, 0);
+	status = call_pnp_bios(PNP_SEND_MESSAGE, message, PNP_DS, 0, 0, 0, 0, 0, 0, 0, 0, 0);
 	return status;
 }
 #endif
@@ -381,8 +387,8 @@
 	u16 status;
 	if (!pnp_bios_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);
+	status = call_pnp_bios(PNP_GET_DOCKING_STATION_INFORMATION, 0, PNP_TS1, PNP_DS, 0, 0, 0, 0,
+			       data, sizeof(struct pnp_docking_station_info), 0, 0);
 	return status;
 }
 #endif
@@ -397,8 +403,8 @@
 	u16 status;
 	if (!pnp_bios_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);
+	status = call_pnp_bios(PNP_SET_STATIC_ALLOCED_RES_INFO, 0, PNP_TS1, PNP_DS, 0, 0, 0, 0,
+			       info, *((u16 *) info), 0, 0);
 	return status;
 }
 #endif
@@ -413,8 +419,8 @@
 	u16 status;
 	if (!pnp_bios_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);
+	status = call_pnp_bios(PNP_GET_STATIC_ALLOCED_RES_INFO, 0, PNP_TS1, PNP_DS, 0, 0, 0, 0,
+			       info, 65536, 0, 0);
 	return status;
 }
 #endif
@@ -428,9 +434,8 @@
 	u16 status;
 	if (!pnp_bios_present ())
 		return PNP_FUNCTION_NOT_SUPPORTED;
-	Q2_SET_SEL(PNP_TS1, table, *size);
-	Q2_SET_SEL(PNP_TS2, size, sizeof(u16));
-	status = call_pnp_bios(PNP_GET_APM_ID_TABLE, 0, PNP_TS2, 0, PNP_TS1, PNP_DS, 0, 0);
+	status = call_pnp_bios(PNP_GET_APM_ID_TABLE, 0, PNP_TS2, 0, PNP_TS1, PNP_DS, 0, 0,
+			       table, *size, size, sizeof(u16));
 	return status;
 }
 #endif
@@ -444,8 +449,8 @@
 	u16 status;
 	if (!pnp_bios_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);
+	status = call_pnp_bios(PNP_GET_PNP_ISA_CONFIG_STRUC, 0, PNP_TS1, PNP_DS, 0, 0, 0, 0,
+			       data, sizeof(struct pnp_isa_config_struc), 0, 0);
 	return status;
 }
 #endif
@@ -459,8 +464,8 @@
 	u16 status;
 	if (!pnp_bios_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);
+	status = call_pnp_bios(PNP_GET_ESCD_INFO, 0, PNP_TS1, 2, PNP_TS1, 4, PNP_TS1, PNP_DS,
+			       data, sizeof(struct escd_info_struc), 0, 0);
 	return status;
 }
 #endif
@@ -475,10 +480,8 @@
 	u16 status;
 	if (!pnp_bios_present ())
 		return ESCD_FUNCTION_NOT_SUPPORTED;
-	Q2_SET_SEL(PNP_TS1, data, 64 * 1024);
-	set_base(gdt[PNP_TS2 >> 3], nvram_base);
-	set_limit(gdt[PNP_TS2 >> 3], 64 * 1024);
-	status = call_pnp_bios(PNP_READ_ESCD, 0, PNP_TS1, PNP_TS2, PNP_DS, 0, 0, 0);
+	status = call_pnp_bios(PNP_READ_ESCD, 0, PNP_TS1, PNP_TS2, PNP_DS, 0, 0, 0,
+			       data, 65536, nvram_base, 65536);
 	return status;
 }
 #endif
@@ -492,10 +495,8 @@
 	u16 status;
 	if (!pnp_bios_present ())
 		return ESCD_FUNCTION_NOT_SUPPORTED;
-	Q2_SET_SEL(PNP_TS1, data, 64 * 1024);
-	set_base(gdt[PNP_TS2 >> 3], nvram_base);
-	set_limit(gdt[PNP_TS2 >> 3], 64 * 1024);
-	status = call_pnp_bios(PNP_WRITE_ESCD, 0, PNP_TS1, PNP_TS2, PNP_DS, 0, 0, 0);
+	status = call_pnp_bios(PNP_WRITE_ESCD, 0, PNP_TS1, PNP_TS2, PNP_DS, 0, 0, 0,
+			       data, 65536, nvram_base, 65536);
 	return status;
 }
 #endif

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: PnP BIOS driver status
  2002-03-09  2:26           ` Alan Cox
@ 2002-03-09  2:24             ` Thomas Hood
  2002-03-09  2:48             ` Thomas Hood
  2002-03-09 14:44             ` Thomas Hood
  2 siblings, 0 replies; 16+ messages in thread
From: Thomas Hood @ 2002-03-09  2:24 UTC (permalink / raw)
  To: Alan Cox; +Cc: Brian Gerst, linux-kernel

On Fri, 2002-03-08 at 21:26, Alan Cox wrote:
> Got you - yes Thomas he's absolutely right. The lock needs to be
> taken by the callers before they set the PNP_TS* entries. 

Yep.  I'll submit a patch to Alan and update the one I just
posted for DJ.

--
Thomas


^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: PnP BIOS driver status
  2002-03-09  1:51         ` Brian Gerst
@ 2002-03-09  2:26           ` Alan Cox
  2002-03-09  2:24             ` Thomas Hood
                               ` (2 more replies)
  0 siblings, 3 replies; 16+ messages in thread
From: Alan Cox @ 2002-03-09  2:26 UTC (permalink / raw)
  To: Brian Gerst; +Cc: Alan Cox, Thomas Hood, linux-kernel

> > The GDT descriptors are set up before /proc comes into being. I'm checking
> > 2.4 code here - has someone left old stuff in 2.5 ?
> 
> PNP_TS1 and PNP_TS2 are changed on every call to the bios to point to
> where the data for the 32-bit code lives.

Got you - yes Thomas he's absolutely right. The lock needs to be taken
by the callers before they set the PNP_TS* entries. 


^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: PnP BIOS driver status
  2002-03-09  2:26           ` Alan Cox
  2002-03-09  2:24             ` Thomas Hood
@ 2002-03-09  2:48             ` Thomas Hood
  2002-03-09 14:44             ` Thomas Hood
  2 siblings, 0 replies; 16+ messages in thread
From: Thomas Hood @ 2002-03-09  2:48 UTC (permalink / raw)
  To: Alan Cox; +Cc: Brian Gerst, linux-kernel

Here the patch for Alan (which also includes the
kpnpbios -> kpnpbiosd change):

--- linux-2.4.19-pre2-ac3/drivers/pnp/pnpbios_core.c_ORIG	Fri Mar  8 17:35:44 2002
+++ linux-2.4.19-pre2-ac3/drivers/pnp/pnpbios_core.c	Fri Mar  8 21:43:10 2002
@@ -139,10 +139,16 @@
 
 static spinlock_t pnp_bios_lock;
 
+/*
+ * call_pnp_bios
+ *
+ * Call with the pnp_bios_lock held and with irqs disabled.
+ * On some boxes IRQ's during PnP BIOS calls are deadly.
+ */
+
 static inline u16 call_pnp_bios(u16 func, u16 arg1, u16 arg2, u16 arg3,
                                 u16 arg4, u16 arg5, u16 arg6, u16 arg7)
 {
-	unsigned long flags;
 	u16 status;
 
 	/*
@@ -152,9 +158,6 @@
 	if(pnp_bios_is_utter_crap)
 		return PNP_FUNCTION_NOT_SUPPORTED;
 
-	/* On some boxes IRQ's during PnP BIOS calls are deadly.  */
-	spin_lock_irqsave(&pnp_bios_lock, flags);
-	__cli();
 	__asm__ __volatile__(
 	        "pushl %%ebp\n\t"
 		"pushl %%edi\n\t"
@@ -184,7 +187,6 @@
 		  "i" (0)
 		: "memory"
 	);
-	spin_unlock_irqrestore(&pnp_bios_lock, flags);
 	
 	/* If we get here and this is set then the PnP BIOS faulted on us. */
 	if(pnp_bios_is_utter_crap)
@@ -220,7 +222,7 @@
 /*
  * Call this only after init time
  */
-static int pnp_bios_present(void)
+static inline int pnp_bios_present(void)
 {
 	return (pnp_bios_hdr != NULL);
 }
@@ -254,11 +256,14 @@
  */
 static int __pnp_bios_dev_node_info(struct pnp_dev_node_info *data)
 {
+	unsigned long flags;
 	u16 status;
 	if (!pnp_bios_present())
 		return PNP_FUNCTION_NOT_SUPPORTED;
+	spin_lock_irqsave(&pnp_bios_lock, flags);
 	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);
+	spin_unlock_irqrestore(&pnp_bios_lock, flags);
 	data->no_nodes &= 0xff;
 	return status;
 }
@@ -287,14 +292,17 @@
  */
 static int __pnp_bios_get_dev_node(u8 *nodenum, char boot, struct pnp_bios_node *data)
 {
+	unsigned long flags;
 	u16 status;
 	if (!pnp_bios_present())
 		return PNP_FUNCTION_NOT_SUPPORTED;
 	if ( !boot & pnpbios_dont_use_current_config )
 		return PNP_FUNCTION_NOT_SUPPORTED;
+	spin_lock_irqsave(&pnp_bios_lock, flags);
 	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);
+	spin_unlock_irqrestore(&pnp_bios_lock, flags);
 	return status;
 }
 
@@ -316,13 +324,16 @@
  */
 static int __pnp_bios_set_dev_node(u8 nodenum, char boot, struct pnp_bios_node *data)
 {
+	unsigned long flags;
 	u16 status;
 	if (!pnp_bios_present())
 		return PNP_FUNCTION_NOT_SUPPORTED;
 	if ( !boot & pnpbios_dont_use_current_config )
 		return PNP_FUNCTION_NOT_SUPPORTED;
+	spin_lock_irqsave(&pnp_bios_lock, flags);
 	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);
+	spin_unlock_irqrestore(&pnp_bios_lock, flags);
 	return status;
 }
 
@@ -350,11 +361,14 @@
  */
 static int pnp_bios_get_event(u16 *event)
 {
+	unsigned long flags;
 	u16 status;
 	if (!pnp_bios_present())
 		return PNP_FUNCTION_NOT_SUPPORTED;
+	spin_lock_irqsave(&pnp_bios_lock, flags);
 	Q2_SET_SEL(PNP_TS1, event, sizeof(u16));
 	status = call_pnp_bios(PNP_GET_EVENT, 0, PNP_TS1, PNP_DS, 0, 0 ,0 ,0);
+	spin_unlock_irqrestore(&pnp_bios_lock, flags);
 	return status;
 }
 #endif
@@ -365,10 +379,13 @@
  */
 static int pnp_bios_send_message(u16 message)
 {
+	unsigned long flags;
 	u16 status;
 	if (!pnp_bios_present())
 		return PNP_FUNCTION_NOT_SUPPORTED;
+	spin_lock_irqsave(&pnp_bios_lock, flags);
 	status = call_pnp_bios(PNP_SEND_MESSAGE, message, PNP_DS, 0, 0, 0, 0, 0);
+	spin_unlock_irqrestore(&pnp_bios_lock, flags);
 	return status;
 }
 #endif
@@ -379,11 +396,14 @@
  */
 static int pnp_bios_dock_station_info(struct pnp_docking_station_info *data)
 {
+	unsigned long flags;
 	u16 status;
 	if (!pnp_bios_present())
 		return PNP_FUNCTION_NOT_SUPPORTED;
+	spin_lock_irqsave(&pnp_bios_lock, flags);
 	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);
+	spin_unlock_irqrestore(&pnp_bios_lock, flags);
 	return status;
 }
 #endif
@@ -395,11 +415,14 @@
  */
 static int pnp_bios_set_stat_res(char *info)
 {
+	unsigned long flags;
 	u16 status;
 	if (!pnp_bios_present())
 		return PNP_FUNCTION_NOT_SUPPORTED;
+	spin_lock_irqsave(&pnp_bios_lock, flags);
 	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);
+	spin_unlock_irqrestore(&pnp_bios_lock, flags);
 	return status;
 }
 #endif
@@ -410,11 +433,14 @@
  */
 static int __pnp_bios_get_stat_res(char *info)
 {
+	unsigned long flags;
 	u16 status;
 	if (!pnp_bios_present())
 		return PNP_FUNCTION_NOT_SUPPORTED;
+	spin_lock_irqsave(&pnp_bios_lock, flags);
 	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);
+	spin_unlock_irqrestore(&pnp_bios_lock, flags);
 	return status;
 }
 
@@ -433,12 +459,15 @@
  */
 static int pnp_bios_apm_id_table(char *table, u16 *size)
 {
+	unsigned long flags;
 	u16 status;
 	if (!pnp_bios_present())
 		return PNP_FUNCTION_NOT_SUPPORTED;
+	spin_lock_irqsave(&pnp_bios_lock, flags);
 	Q2_SET_SEL(PNP_TS1, table, *size);
 	Q2_SET_SEL(PNP_TS2, size, sizeof(u16));
 	status = call_pnp_bios(PNP_GET_APM_ID_TABLE, 0, PNP_TS2, 0, PNP_TS1, PNP_DS, 0, 0);
+	spin_unlock_irqrestore(&pnp_bios_lock, flags);
 	return status;
 }
 #endif
@@ -448,11 +477,14 @@
  */
 static int __pnp_bios_isapnp_config(struct pnp_isa_config_struc *data)
 {
+	unsigned long flags;
 	u16 status;
 	if (!pnp_bios_present())
 		return PNP_FUNCTION_NOT_SUPPORTED;
+	spin_lock_irqsave(&pnp_bios_lock, flags);
 	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);
+	spin_unlock_irqrestore(&pnp_bios_lock, flags);
 	return status;
 }
 
@@ -470,11 +502,14 @@
  */
 static int __pnp_bios_escd_info(struct escd_info_struc *data)
 {
+	unsigned long flags;
 	u16 status;
 	if (!pnp_bios_present())
 		return ESCD_FUNCTION_NOT_SUPPORTED;
+	spin_lock_irqsave(&pnp_bios_lock, flags);
 	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);
+	spin_unlock_irqrestore(&pnp_bios_lock, flags);
 	return status;
 }
 
@@ -493,13 +528,16 @@
  */
 static int __pnp_bios_read_escd(char *data, u32 nvram_base)
 {
+	unsigned long flags;
 	u16 status;
 	if (!pnp_bios_present())
 		return ESCD_FUNCTION_NOT_SUPPORTED;
+	spin_lock_irqsave(&pnp_bios_lock, flags);
 	Q2_SET_SEL(PNP_TS1, data, 64 * 1024);
 	set_base(gdt[PNP_TS2 >> 3], nvram_base);
 	set_limit(gdt[PNP_TS2 >> 3], 64 * 1024);
 	status = call_pnp_bios(PNP_READ_ESCD, 0, PNP_TS1, PNP_TS2, PNP_DS, 0, 0, 0);
+	spin_unlock_irqrestore(&pnp_bios_lock, flags);
 	return status;
 }
 
@@ -518,13 +556,16 @@
  */
 static int pnp_bios_write_escd(char *data, u32 nvram_base)
 {
+	unsigned long flags;
 	u16 status;
 	if (!pnp_bios_present())
 		return ESCD_FUNCTION_NOT_SUPPORTED;
+	spin_lock_irqsave(&pnp_bios_lock, flags);
 	Q2_SET_SEL(PNP_TS1, data, 64 * 1024);
 	set_base(gdt[PNP_TS2 >> 3], nvram_base);
 	set_limit(gdt[PNP_TS2 >> 3], 64 * 1024);
 	status = call_pnp_bios(PNP_WRITE_ESCD, 0, PNP_TS1, PNP_TS2, PNP_DS, 0, 0, 0);
+	spin_unlock_irqrestore(&pnp_bios_lock, flags);
 	return status;
 }
 #endif
@@ -606,7 +647,7 @@
 	int docked = -1, d = 0;
 	daemonize();
 	reparent_to_init();
-	strcpy(current->comm, "kpnpbios");
+	strcpy(current->comm, "kpnpbiosd");
 	while(!unloading && !signal_pending(current))
 	{
 		int status;


^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: PnP BIOS driver status
  2002-03-09  2:23     ` Brian Gerst
@ 2002-03-09  3:02       ` Thomas Hood
  0 siblings, 0 replies; 16+ messages in thread
From: Thomas Hood @ 2002-03-09  3:02 UTC (permalink / raw)
  To: Brian Gerst; +Cc: linux-kernel, Alan Cox

On Fri, 2002-03-08 at 21:23, Brian Gerst wrote:
> How does this patch look?  Against 2.5.6

Better than mine.

Alan: I suggest applying Brian's patch plus the 
change from 'kpnpbios' to 'kpnpbiosd'.

I'll integrate Brian's patch into my patch for David
Jones's patch to 2.5.x ... tomorrow.


^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: PnP BIOS driver status
  2002-03-09  2:26           ` Alan Cox
  2002-03-09  2:24             ` Thomas Hood
  2002-03-09  2:48             ` Thomas Hood
@ 2002-03-09 14:44             ` Thomas Hood
  2 siblings, 0 replies; 16+ messages in thread
From: Thomas Hood @ 2002-03-09 14:44 UTC (permalink / raw)
  To: Alan Cox; +Cc: Brian Gerst, linux-kernel

Alan: I just tried to apply Brian's patch and noticed that 
it was against 2.5.6.  Here is his patch versus 2.4.19-pre2-ac3 
with the kpnpbios -> kpnpbiosd change added in. 
// Thomas

--- linux-2.4.19-pre2-ac3/drivers/pnp/pnpbios_core.c_ORIG	Fri Mar  8 17:35:44 2002
+++ linux-2.4.19-pre2-ac3/drivers/pnp/pnpbios_core.c	Sat Mar  9 09:39:56 2002
@@ -140,7 +140,9 @@
 static spinlock_t pnp_bios_lock;
 
 static inline u16 call_pnp_bios(u16 func, u16 arg1, u16 arg2, u16 arg3,
-                                u16 arg4, u16 arg5, u16 arg6, u16 arg7)
+                                u16 arg4, u16 arg5, u16 arg6, u16 arg7,
+                                void *ts1_base, u32 ts1_size,
+                                void *ts2_base, u32 ts2_size)
 {
 	unsigned long flags;
 	u16 status;
@@ -154,7 +156,12 @@
 
 	/* On some boxes IRQ's during PnP BIOS calls are deadly.  */
 	spin_lock_irqsave(&pnp_bios_lock, flags);
-	__cli();
+
+	if (ts1_size)
+		Q2_SET_SEL(PNP_TS1, ts1_base, ts1_size);
+	if (ts2_size)
+		Q2_SET_SEL(PNP_TS2, ts2_base, ts2_size);
+
 	__asm__ __volatile__(
 	        "pushl %%ebp\n\t"
 		"pushl %%edi\n\t"
@@ -220,7 +227,7 @@
 /*
  * Call this only after init time
  */
-static int pnp_bios_present(void)
+static inline int pnp_bios_present(void)
 {
 	return (pnp_bios_hdr != NULL);
 }
@@ -257,8 +264,8 @@
 	u16 status;
 	if (!pnp_bios_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);
+	status = call_pnp_bios(PNP_GET_NUM_SYS_DEV_NODES, 0, PNP_TS1, 2, PNP_TS1, PNP_DS, 0, 0,
+			       data, sizeof(struct pnp_dev_node_info), 0, 0);
 	data->no_nodes &= 0xff;
 	return status;
 }
@@ -292,9 +299,8 @@
 		return PNP_FUNCTION_NOT_SUPPORTED;
 	if ( !boot & pnpbios_dont_use_current_config )
 		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);
+	status = call_pnp_bios(PNP_GET_SYS_DEV_NODE, 0, PNP_TS1, 0, PNP_TS2, boot ? 2 : 1, PNP_DS, 0,
+			       nodenum, sizeof(char), data, 65536);
 	return status;
 }
 
@@ -321,8 +327,8 @@
 		return PNP_FUNCTION_NOT_SUPPORTED;
 	if ( !boot & pnpbios_dont_use_current_config )
 		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);
+	status = call_pnp_bios(PNP_SET_SYS_DEV_NODE, nodenum, 0, PNP_TS1, boot ? 2 : 1, PNP_DS, 0, 0,
+			       data, 65536, 0, 0);
 	return status;
 }
 
@@ -353,8 +359,8 @@
 	u16 status;
 	if (!pnp_bios_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);
+	status = call_pnp_bios(PNP_GET_EVENT, 0, PNP_TS1, PNP_DS, 0, 0 ,0 ,0,
+			       event, sizeof(u16), 0, 0);
 	return status;
 }
 #endif
@@ -368,7 +374,7 @@
 	u16 status;
 	if (!pnp_bios_present())
 		return PNP_FUNCTION_NOT_SUPPORTED;
-	status = call_pnp_bios(PNP_SEND_MESSAGE, message, PNP_DS, 0, 0, 0, 0, 0);
+	status = call_pnp_bios(PNP_SEND_MESSAGE, message, PNP_DS, 0, 0, 0, 0, 0, 0, 0, 0, 0);
 	return status;
 }
 #endif
@@ -382,8 +388,8 @@
 	u16 status;
 	if (!pnp_bios_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);
+	status = call_pnp_bios(PNP_GET_DOCKING_STATION_INFORMATION, 0, PNP_TS1, PNP_DS, 0, 0, 0, 0,
+			       data, sizeof(struct pnp_docking_station_info), 0, 0);
 	return status;
 }
 #endif
@@ -398,8 +404,8 @@
 	u16 status;
 	if (!pnp_bios_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);
+	status = call_pnp_bios(PNP_SET_STATIC_ALLOCED_RES_INFO, 0, PNP_TS1, PNP_DS, 0, 0, 0, 0,
+			       info, *((u16 *) info), 0, 0);
 	return status;
 }
 #endif
@@ -413,8 +419,8 @@
 	u16 status;
 	if (!pnp_bios_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);
+	status = call_pnp_bios(PNP_GET_STATIC_ALLOCED_RES_INFO, 0, PNP_TS1, PNP_DS, 0, 0, 0, 0,
+			       info, 65536, 0, 0);
 	return status;
 }
 
@@ -436,9 +442,8 @@
 	u16 status;
 	if (!pnp_bios_present())
 		return PNP_FUNCTION_NOT_SUPPORTED;
-	Q2_SET_SEL(PNP_TS1, table, *size);
-	Q2_SET_SEL(PNP_TS2, size, sizeof(u16));
-	status = call_pnp_bios(PNP_GET_APM_ID_TABLE, 0, PNP_TS2, 0, PNP_TS1, PNP_DS, 0, 0);
+	status = call_pnp_bios(PNP_GET_APM_ID_TABLE, 0, PNP_TS2, 0, PNP_TS1, PNP_DS, 0, 0,
+			       table, *size, size, sizeof(u16));
 	return status;
 }
 #endif
@@ -451,8 +456,8 @@
 	u16 status;
 	if (!pnp_bios_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);
+	status = call_pnp_bios(PNP_GET_PNP_ISA_CONFIG_STRUC, 0, PNP_TS1, PNP_DS, 0, 0, 0, 0,
+			       data, sizeof(struct pnp_isa_config_struc), 0, 0);
 	return status;
 }
 
@@ -473,8 +478,8 @@
 	u16 status;
 	if (!pnp_bios_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);
+	status = call_pnp_bios(PNP_GET_ESCD_INFO, 0, PNP_TS1, 2, PNP_TS1, 4, PNP_TS1, PNP_DS,
+			       data, sizeof(struct escd_info_struc), 0, 0);
 	return status;
 }
 
@@ -496,10 +501,8 @@
 	u16 status;
 	if (!pnp_bios_present())
 		return ESCD_FUNCTION_NOT_SUPPORTED;
-	Q2_SET_SEL(PNP_TS1, data, 64 * 1024);
-	set_base(gdt[PNP_TS2 >> 3], nvram_base);
-	set_limit(gdt[PNP_TS2 >> 3], 64 * 1024);
-	status = call_pnp_bios(PNP_READ_ESCD, 0, PNP_TS1, PNP_TS2, PNP_DS, 0, 0, 0);
+	status = call_pnp_bios(PNP_READ_ESCD, 0, PNP_TS1, PNP_TS2, PNP_DS, 0, 0, 0,
+			       data, 65536, nvram_base, 65536);
 	return status;
 }
 
@@ -521,10 +524,8 @@
 	u16 status;
 	if (!pnp_bios_present())
 		return ESCD_FUNCTION_NOT_SUPPORTED;
-	Q2_SET_SEL(PNP_TS1, data, 64 * 1024);
-	set_base(gdt[PNP_TS2 >> 3], nvram_base);
-	set_limit(gdt[PNP_TS2 >> 3], 64 * 1024);
-	status = call_pnp_bios(PNP_WRITE_ESCD, 0, PNP_TS1, PNP_TS2, PNP_DS, 0, 0, 0);
+	status = call_pnp_bios(PNP_WRITE_ESCD, 0, PNP_TS1, PNP_TS2, PNP_DS, 0, 0, 0,
+			       data, 65536, nvram_base, 65536);
 	return status;
 }
 #endif
@@ -606,7 +607,7 @@
 	int docked = -1, d = 0;
 	daemonize();
 	reparent_to_init();
-	strcpy(current->comm, "kpnpbios");
+	strcpy(current->comm, "kpnpbiosd");
 	while(!unloading && !signal_pending(current))
 	{
 		int status;


^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: PnP BIOS driver status
@ 2002-03-09 15:11 Thomas Hood
  0 siblings, 0 replies; 16+ messages in thread
From: Thomas Hood @ 2002-03-09 15:11 UTC (permalink / raw)
  To: Dave Jones; +Cc: linux-kernel

Here are the additional bits from the -ac tree, plus Brian's
SMP fix, diffed against 2.5.6 + 2.5.5-dj3 patch.  The changes
include:

- Improve some comments
- Postpone starting the kernel thread (Alan Cox)
- Call kernel thread 'kpnpbiosd' instead of 'kpnpbios'
- Consolidate printing of error messages to save space
- Add __init and __exit tags and return appropriate error codes
- Print slightly more consistent messages
- Get closer to supporting build-as-module
- Make SMP safe (Brian Gerst)

--
Thomas

--- linux-2.5.6_2.5.5-dj3/include/linux/pnpbios.h_DJ	Fri Mar  8 18:37:58 2002
+++ linux-2.5.6_2.5.5-dj3/include/linux/pnpbios.h	Fri Mar  8 19:43:25 2002
@@ -143,7 +143,8 @@
 extern int  pnpbios_dont_use_current_config;
 extern void *pnpbios_kmalloc(size_t size, int f);
 extern int pnpbios_init (void);
-extern void pnpbios_proc_init (void);
+extern int pnpbios_proc_init (void);
+extern void pnpbios_proc_exit (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);
--- linux-2.5.6_2.5.5-dj3/drivers/pnp/pnpbios_core.c_DJ	Fri Mar  8 18:40:02 2002
+++ linux-2.5.6_2.5.5-dj3/drivers/pnp/pnpbios_core.c	Sat Mar  9 10:08:21 2002
@@ -4,7 +4,7 @@
  * Originally (C) 1998 Christian Schmidt <schmidt@digadd.de>
  * Modifications (c) 1998 Tom Lees <tom@lpsg.demon.co.uk>
  * Minor reorganizations by David Hinds <dahinds@users.sourceforge.net>
- * Modifications (c) 2001 by Thomas Hood <jdthood@mail.com>
+ * Modifications (c) 2001,2002 by Thomas Hood <jdthood@mail.com>
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by the
@@ -141,7 +141,9 @@
 static spinlock_t pnp_bios_lock;
 
 static inline u16 call_pnp_bios(u16 func, u16 arg1, u16 arg2, u16 arg3,
-                                u16 arg4, u16 arg5, u16 arg6, u16 arg7)
+				u16 arg4, u16 arg5, u16 arg6, u16 arg7,
+				void *ts1_base, u32 ts1_size,
+				void *ts2_base, u32 ts2_size)
 {
 	unsigned long flags;
 	u16 status;
@@ -155,7 +157,12 @@
 
 	/* On some boxes IRQ's during PnP BIOS calls are deadly.  */
 	spin_lock_irqsave(&pnp_bios_lock, flags);
-	__cli();
+
+	if (ts1_size)
+		Q2_SET_SEL(PNP_TS1, ts1_base, ts1_size);
+	if (ts2_size)
+		Q2_SET_SEL(PNP_TS2, ts2_base, ts2_size);
+
 	__asm__ __volatile__(
 	        "pushl %%ebp\n\t"
 		"pushl %%edi\n\t"
@@ -205,6 +212,11 @@
  *
  */
 
+static void pnpbios_warn_unexpected_status(const char * module, u16 status)
+{
+	printk(KERN_ERR "PnPBIOS: %s: Unexpected status 0x%x\n", module, status);
+}
+
 void *pnpbios_kmalloc(size_t size, int f)
 {
 	void *p = kmalloc( size, f );
@@ -216,7 +228,7 @@
 /*
  * Call this only after init time
  */
-static int pnp_bios_present(void)
+static inline int pnp_bios_present(void)
 {
 	return (pnp_bios_hdr != NULL);
 }
@@ -251,10 +263,10 @@
 static int __pnp_bios_dev_node_info(struct pnp_dev_node_info *data)
 {
 	u16 status;
-	if (!pnp_bios_present ())
+	if (!pnp_bios_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);
+	status = call_pnp_bios(PNP_GET_NUM_SYS_DEV_NODES, 0, PNP_TS1, 2, PNP_TS1, PNP_DS, 0, 0,
+			       data, sizeof(struct pnp_dev_node_info), 0, 0);
 	data->no_nodes &= 0xff;
 	return status;
 }
@@ -263,7 +275,7 @@
 {
 	int status = __pnp_bios_dev_node_info( data );
 	if ( status )
-		printk(KERN_WARNING "PnPBIOS: dev_node_info: Unexpected status 0x%x\n", status);
+		pnpbios_warn_unexpected_status( "dev_node_info", status );
 	return status;
 }
 
@@ -284,13 +296,12 @@
 static int __pnp_bios_get_dev_node(u8 *nodenum, char boot, struct pnp_bios_node *data)
 {
 	u16 status;
-	if (!pnp_bios_present ())
+	if (!pnp_bios_present())
 		return PNP_FUNCTION_NOT_SUPPORTED;
 	if ( !boot & pnpbios_dont_use_current_config )
 		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);
+	status = call_pnp_bios(PNP_GET_SYS_DEV_NODE, 0, PNP_TS1, 0, PNP_TS2, boot ? 2 : 1, PNP_DS, 0,
+			       nodenum, sizeof(char), data, 65536);
 	return status;
 }
 
@@ -299,7 +310,7 @@
 	int status;
 	status =  __pnp_bios_get_dev_node( nodenum, boot, data );
 	if ( status )
-		printk(KERN_WARNING "PnPBIOS: get_dev_node: Unexpected status 0x%x\n", status);
+		pnpbios_warn_unexpected_status( "get_dev_node", status );
 	return status;
 }
 
@@ -313,12 +324,12 @@
 static int __pnp_bios_set_dev_node(u8 nodenum, char boot, struct pnp_bios_node *data)
 {
 	u16 status;
-	if (!pnp_bios_present ())
+	if (!pnp_bios_present())
 		return PNP_FUNCTION_NOT_SUPPORTED;
 	if ( !boot & pnpbios_dont_use_current_config )
 		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);
+	status = call_pnp_bios(PNP_SET_SYS_DEV_NODE, nodenum, 0, PNP_TS1, boot ? 2 : 1, PNP_DS, 0, 0,
+			       data, 65536, 0, 0);
 	return status;
 }
 
@@ -327,7 +338,7 @@
 	int status;
 	status =  __pnp_bios_set_dev_node( nodenum, boot, data );
 	if ( status ) {
-		printk(KERN_WARNING "PnPBIOS: set_dev_node: Unexpected status 0x%x\n", status);
+		pnpbios_warn_unexpected_status( "set_dev_node", status );
 		return status;
 	}
 	if ( !boot ) { /* Update devlist */
@@ -347,10 +358,10 @@
 static int pnp_bios_get_event(u16 *event)
 {
 	u16 status;
-	if (!pnp_bios_present ())
+	if (!pnp_bios_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);
+	status = call_pnp_bios(PNP_GET_EVENT, 0, PNP_TS1, PNP_DS, 0, 0 ,0 ,0,
+			       event, sizeof(u16), 0, 0);
 	return status;
 }
 #endif
@@ -362,9 +373,9 @@
 static int pnp_bios_send_message(u16 message)
 {
 	u16 status;
-	if (!pnp_bios_present ())
+	if (!pnp_bios_present())
 		return PNP_FUNCTION_NOT_SUPPORTED;
-	status = call_pnp_bios(PNP_SEND_MESSAGE, message, PNP_DS, 0, 0, 0, 0, 0);
+	status = call_pnp_bios(PNP_SEND_MESSAGE, message, PNP_DS, 0, 0, 0, 0, 0, 0, 0, 0, 0);
 	return status;
 }
 #endif
@@ -376,10 +387,10 @@
 static int pnp_bios_dock_station_info(struct pnp_docking_station_info *data)
 {
 	u16 status;
-	if (!pnp_bios_present ())
+	if (!pnp_bios_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);
+	status = call_pnp_bios(PNP_GET_DOCKING_STATION_INFORMATION, 0, PNP_TS1, PNP_DS, 0, 0, 0, 0,
+			       data, sizeof(struct pnp_docking_station_info), 0, 0);
 	return status;
 }
 #endif
@@ -392,10 +403,10 @@
 static int pnp_bios_set_stat_res(char *info)
 {
 	u16 status;
-	if (!pnp_bios_present ())
+	if (!pnp_bios_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);
+	status = call_pnp_bios(PNP_SET_STATIC_ALLOCED_RES_INFO, 0, PNP_TS1, PNP_DS, 0, 0, 0, 0,
+			       info, *((u16 *) info), 0, 0);
 	return status;
 }
 #endif
@@ -407,10 +418,10 @@
 static int __pnp_bios_get_stat_res(char *info)
 {
 	u16 status;
-	if (!pnp_bios_present ())
+	if (!pnp_bios_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);
+	status = call_pnp_bios(PNP_GET_STATIC_ALLOCED_RES_INFO, 0, PNP_TS1, PNP_DS, 0, 0, 0, 0,
+			       info, 65536, 0, 0);
 	return status;
 }
 
@@ -419,7 +430,7 @@
 	int status;
 	status = __pnp_bios_get_stat_res( info );
 	if ( status )
-		printk(KERN_WARNING "PnPBIOS: get_stat_res: Unexpected status 0x%x\n", status);
+		pnpbios_warn_unexpected_status( "get_stat_res", status );
 	return status;
 }
 
@@ -430,11 +441,10 @@
 static int pnp_bios_apm_id_table(char *table, u16 *size)
 {
 	u16 status;
-	if (!pnp_bios_present ())
+	if (!pnp_bios_present())
 		return PNP_FUNCTION_NOT_SUPPORTED;
-	Q2_SET_SEL(PNP_TS1, table, *size);
-	Q2_SET_SEL(PNP_TS2, size, sizeof(u16));
-	status = call_pnp_bios(PNP_GET_APM_ID_TABLE, 0, PNP_TS2, 0, PNP_TS1, PNP_DS, 0, 0);
+	status = call_pnp_bios(PNP_GET_APM_ID_TABLE, 0, PNP_TS2, 0, PNP_TS1, PNP_DS, 0, 0,
+			       table, *size, size, sizeof(u16));
 	return status;
 }
 #endif
@@ -445,10 +455,10 @@
 static int __pnp_bios_isapnp_config(struct pnp_isa_config_struc *data)
 {
 	u16 status;
-	if (!pnp_bios_present ())
+	if (!pnp_bios_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);
+	status = call_pnp_bios(PNP_GET_PNP_ISA_CONFIG_STRUC, 0, PNP_TS1, PNP_DS, 0, 0, 0, 0,
+			       data, sizeof(struct pnp_isa_config_struc), 0, 0);
 	return status;
 }
 
@@ -457,7 +467,7 @@
 	int status;
 	status = __pnp_bios_isapnp_config( data );
 	if ( status )
-		printk(KERN_WARNING "PnPBIOS: isapnp_config: Unexpected status 0x%x\n", status);
+		pnpbios_warn_unexpected_status( "isapnp_config", status );
 	return status;
 }
 
@@ -467,10 +477,10 @@
 static int __pnp_bios_escd_info(struct escd_info_struc *data)
 {
 	u16 status;
-	if (!pnp_bios_present ())
+	if (!pnp_bios_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);
+	status = call_pnp_bios(PNP_GET_ESCD_INFO, 0, PNP_TS1, 2, PNP_TS1, 4, PNP_TS1, PNP_DS,
+			       data, sizeof(struct escd_info_struc), 0, 0);
 	return status;
 }
 
@@ -479,7 +489,7 @@
 	int status;
 	status = __pnp_bios_escd_info( data );
 	if ( status )
-		printk(KERN_WARNING "PnPBIOS: escd_info: Unexpected status 0x%x\n", status);
+		pnpbios_warn_unexpected_status( "escd_info", status );
 	return status;
 }
 
@@ -490,12 +500,10 @@
 static int __pnp_bios_read_escd(char *data, u32 nvram_base)
 {
 	u16 status;
-	if (!pnp_bios_present ())
+	if (!pnp_bios_present())
 		return ESCD_FUNCTION_NOT_SUPPORTED;
-	Q2_SET_SEL(PNP_TS1, data, 64 * 1024);
-	set_base(gdt[PNP_TS2 >> 3], nvram_base);
-	set_limit(gdt[PNP_TS2 >> 3], 64 * 1024);
-	status = call_pnp_bios(PNP_READ_ESCD, 0, PNP_TS1, PNP_TS2, PNP_DS, 0, 0, 0);
+	status = call_pnp_bios(PNP_READ_ESCD, 0, PNP_TS1, PNP_TS2, PNP_DS, 0, 0, 0,
+			       data, 65536, (void *)nvram_base, 65536);
 	return status;
 }
 
@@ -504,7 +512,7 @@
 	int status;
 	status = __pnp_bios_read_escd( data, nvram_base );
 	if ( status )
-		printk(KERN_ERR "PnPBIOS: read_escd: Unexpected status 0x%x\n", status);
+		pnpbios_warn_unexpected_status( "read_escd", status );
 	return status;
 }
 
@@ -515,12 +523,10 @@
 static int pnp_bios_write_escd(char *data, u32 nvram_base)
 {
 	u16 status;
-	if (!pnp_bios_present ())
+	if (!pnp_bios_present())
 		return ESCD_FUNCTION_NOT_SUPPORTED;
-	Q2_SET_SEL(PNP_TS1, data, 64 * 1024);
-	set_base(gdt[PNP_TS2 >> 3], nvram_base);
-	set_limit(gdt[PNP_TS2 >> 3], 64 * 1024);
-	status = call_pnp_bios(PNP_WRITE_ESCD, 0, PNP_TS1, PNP_TS2, PNP_DS, 0, 0, 0);
+	status = call_pnp_bios(PNP_WRITE_ESCD, 0, PNP_TS1, PNP_TS2, PNP_DS, 0, 0, 0,
+			       data, 65536, (void *)nvram_base, 65536);
 	return status;
 }
 #endif
@@ -602,10 +608,10 @@
 	int docked = -1, d = 0;
 	daemonize();
 	reparent_to_init();
-	strcpy(current->comm, "kpnpbios");
+	strcpy(current->comm, "kpnpbiosd");
 	while(!unloading && !signal_pending(current))
 	{
-		int err;
+		int status;
 		
 		/*
 		 * Poll every 2 seconds
@@ -615,9 +621,9 @@
 		if(signal_pending(current))
 			break;
 
-		err = pnp_bios_dock_station_info(&now);
+		status = pnp_bios_dock_station_info(&now);
 
-		switch(err)
+		switch(status)
 		{
 			/*
 			 * No dock to manage
@@ -631,7 +637,7 @@
 				d = 1;
 				break;
 			default:
-				printk(KERN_WARNING "PnPBIOS: pnp_dock_thread: Unexpected status 0x%x\n", err);
+				pnpbios_warn_unexpected_status( "pnp_dock_thread", status );
 				continue;
 		}
 		if(d != docked)
@@ -874,13 +880,13 @@
 static void __init build_devlist(void)
 {
 	u8 nodenum;
-	int nodes_got = 0;
-	int devs = 0;
+	unsigned int nodes_got = 0;
+	unsigned int devs = 0;
 	struct pnp_bios_node *node;
 	struct pnp_dev_node_info node_info;
 	struct pci_dev *dev;
 	
-	if (!pnp_bios_present ())
+	if (!pnp_bios_present())
 		return;
 
 	if (pnp_bios_dev_node_info(&node_info) != 0)
@@ -912,7 +918,7 @@
 		else
 			devs++;
 		if (nodenum <= thisnodenum) {
-			printk(KERN_ERR "PnPBIOS: build_devlist(): Node number 0x%x is out of sequence following node 0x%x. Aborting.\n", (int)nodenum, (int)thisnodenum);
+			printk(KERN_ERR "PnPBIOS: build_devlist: Node number 0x%x is out of sequence following node 0x%x. Aborting.\n", (unsigned int)nodenum, (unsigned int)thisnodenum);
 			break;
 		}
 	}
@@ -1215,14 +1221,14 @@
 {
 	union pnp_bios_expansion_header *check;
 	u8 sum;
-	int i, length;
+	int i, length, r;
 
 	spin_lock_init(&pnp_bios_lock);
 	spin_lock_init(&pnpbios_devices_lock);
 
 	if(pnpbios_disabled) {
 		printk(KERN_INFO "PnPBIOS: Disabled\n");
-		return 0;
+		return -ENODEV;
 	}
 
 	if ( is_sony_vaio_laptop )
@@ -1264,12 +1270,21 @@
 		pnp_bios_hdr = check;
 		break;
 	}
+	if (!pnp_bios_present())
+		return -ENODEV;
 	build_devlist();
 	if ( ! dont_reserve_resources )
 		reserve_resources();
 #ifdef CONFIG_PROC_FS
-	pnpbios_proc_init();
+	r = pnpbios_proc_init();
+	if (r)
+		return r;
 #endif
+	return 0;
+}
+
+static int __init pnpbios_thread_init(void)
+{
 #ifdef CONFIG_HOTPLUG	
 	init_completion(&unload_sem);
 	if(kernel_thread(pnp_dock_thread, NULL, CLONE_FS | CLONE_FILES | CLONE_SIGNAL)>0)
@@ -1278,23 +1293,46 @@
 	return 0;
 }
 
-#ifdef MODULE
+#ifndef MODULE
+
+/* init/main.c calls pnpbios_init early */
+
+/* Start the kernel thread later: */
+module_init(pnpbios_thread_init);
+
+#else
+
+/*
+ * N.B.: Building pnpbios as a module hasn't been fully implemented
+ */
 
 MODULE_LICENSE("GPL");
 
-/* We have to run it early and not as a module. */
-module_init(pnpbios_init);
+static int __init pnpbios_init_all(void)
+{
+	int r;
 
-#ifdef CONFIG_HOTPLUG
-static void pnpbios_exit(void)
+	r = pnpbios_init();
+	if (r)
+		return r;
+	r = pnpbios_thread_init();
+	if (r)
+		return r;
+	return 0;
+}
+
+static void __exit pnpbios_exit(void)
 {
-	/* free_resources() ought to go here */
-	/* pnpbios_proc_done() */
+#ifdef CONFIG_HOTPLUG
 	unloading = 1;
 	wait_for_completion(&unload_sem);
+#endif
+	pnpbios_proc_exit();
+	/* We ought to free resources here */
+	return;
 }
 
+module_init(pnpbios_init_all);
 module_exit(pnpbios_exit);
 
-#endif
 #endif
--- linux-2.5.6_2.5.5-dj3/drivers/pnp/pnpbios_proc.c_DJ	Fri Mar  8 18:37:58 2002
+++ linux-2.5.6_2.5.5-dj3/drivers/pnp/pnpbios_proc.c	Fri Mar  8 19:10:32 2002
@@ -2,7 +2,20 @@
  * /proc/bus/pnp interface for Plug and Play devices
  *
  * Written by David Hinds, dahinds@users.sourceforge.net
- * Modified by Thomas Hood, jdthood_AT_mail.com
+ * Modified by Thomas Hood, jdthood@mail.com
+ *
+ * The .../devices and .../<node> and .../boot/<node> files are
+ * utilized by the lspnp and setpnp utilities, supplied with the
+ * pcmcia-cs package.
+ *     http://pcmcia-cs.sourceforge.net
+ *
+ * The .../escd file is utilized by the lsescd utility written by
+ * Gunther Mayer.
+ *     http://home.t-online.de/home/gunther.mayer/lsescd
+ *
+ * The .../legacy_device_resources file is not used yet.
+ *
+ * The other files are human-readable.
  */
 
 //#include <pcmcia/config.h>
@@ -66,7 +79,7 @@
 
 	/* sanity check */
 	if (escd.escd_size > (32*1024)) {
-		printk(KERN_ERR "PnPBIOS: Error: ESCD size is too great\n");
+		printk(KERN_ERR "PnPBIOS: proc_read_escd: ESCD size is too great\n");
 		return -EFBIG;
 	}
 
@@ -122,7 +135,7 @@
 			     node->type_code[0], node->type_code[1],
 			     node->type_code[2], node->flags);
 		if (nodenum <= thisnodenum) {
-			printk(KERN_ERR "PnPBIOS: proc_read_devices(): Node number 0x%x is out of sequence following node 0x%x. Aborting.\n", (int)nodenum, (int)thisnodenum);
+			printk(KERN_ERR "%s Node number 0x%x is out of sequence following node 0x%x. Aborting.\n", "PnPBIOS: proc_read_devices:", (unsigned int)nodenum, (unsigned int)thisnodenum);
 			*eof = 1;
 			break;
 		}
@@ -177,20 +190,22 @@
  * work and the pnpbios_dont_use_current_config flag
  * should already have been set to the appropriate value
  */
-void pnpbios_proc_init( void )
+int __init pnpbios_proc_init( void )
 {
 	struct pnp_bios_node *node;
 	struct proc_dir_entry *ent;
 	char name[3];
-	int i;
 	u8 nodenum;
 
-	if (pnp_bios_dev_node_info(&node_info) != 0) return;
+	if (pnp_bios_dev_node_info(&node_info))
+		return -EIO;
 	
 	proc_pnp = proc_mkdir("pnp", proc_bus);
-	if (!proc_pnp) return;
+	if (!proc_pnp)
+		return -EIO;
 	proc_pnp_boot = proc_mkdir("boot", proc_pnp);
-	if (!proc_pnp_boot) return;
+	if (!proc_pnp_boot)
+		return -EIO;
 	create_proc_read_entry("devices", 0, proc_pnp, proc_read_devices, NULL);
 	create_proc_read_entry("configuration_info", 0, proc_pnp, proc_read_pnpconfig, NULL);
 	create_proc_read_entry("escd_info", 0, proc_pnp, proc_read_escdinfo, NULL);
@@ -198,8 +213,11 @@
 	create_proc_read_entry("legacy_device_resources", 0, proc_pnp, proc_read_legacyres, NULL);
 	
 	node = pnpbios_kmalloc(node_info.max_node_size, GFP_KERNEL);
-	if (!node) return;
-	for (i=0,nodenum = 0; i<0xff && nodenum != 0xff; i++) {
+	if (!node)
+		return -ENOMEM;
+
+	for (nodenum=0; nodenum<0xff; ) {
+		u8 thisnodenum = nodenum;
 		if (pnp_bios_get_dev_node(&nodenum, 1, node) != 0)
 			break;
 		sprintf(name, "%02x", node->handle);
@@ -217,11 +235,17 @@
 			ent->write_proc = proc_write_node;
 			ent->data = (void *)(long)(node->handle+0x100);
 		}
+		if (nodenum <= thisnodenum) {
+			printk(KERN_ERR "%s Node number 0x%x is out of sequence following node 0x%x. Aborting.\n", "PnPBIOS: proc_init:", (unsigned int)nodenum, (unsigned int)thisnodenum);
+			break;
+		}
 	}
 	kfree(node);
+
+	return 0;
 }
 
-void pnpbios_proc_done(void)
+void __exit pnpbios_proc_exit(void)
 {
 	int i;
 	char name[3];
@@ -241,4 +265,6 @@
 	remove_proc_entry("devices", proc_pnp);
 	remove_proc_entry("boot", proc_pnp);
 	remove_proc_entry("pnp", proc_bus);
+
+	return;
 }



^ permalink raw reply	[flat|nested] 16+ messages in thread

end of thread, other threads:[~2002-03-09 15:10 UTC | newest]

Thread overview: 16+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2002-03-08 23:00 PnP BIOS driver status Thomas Hood
2002-03-08 23:14 ` Dave Jones
2002-03-09  0:43   ` Thomas Hood
2002-03-09  1:00 ` Brian Gerst
2002-03-09  1:10   ` Thomas Hood
2002-03-09  2:23     ` Brian Gerst
2002-03-09  3:02       ` Thomas Hood
2002-03-09  1:25   ` Alan Cox
2002-03-09  1:37     ` Brian Gerst
2002-03-09  2:00       ` Alan Cox
2002-03-09  1:51         ` Brian Gerst
2002-03-09  2:26           ` Alan Cox
2002-03-09  2:24             ` Thomas Hood
2002-03-09  2:48             ` Thomas Hood
2002-03-09 14:44             ` Thomas Hood
  -- strict thread matches above, loose matches on Subject: below --
2002-03-09 15:11 Thomas Hood

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox