--- linux/drivers/net/irda/nsc-ircc.c.ori	2005-06-10 16:19:36.000000000 +0200
+++ linux/drivers/net/irda/nsc-ircc.c	2005-06-10 16:22:21.000000000 +0200
@@ -12,6 +12,7 @@
  *     Copyright (c) 1998-2000 Dag Brattli <dagb@cs.uit.no>
  *     Copyright (c) 1998 Lichen Wang, <lwang@actisys.com>
  *     Copyright (c) 1998 Actisys Corp., www.actisys.com
+ *     Copyright (c) 2000-2004 Jean Tourrilhes <jt@hpl.hp.com>
  *     All Rights Reserved
  *      
  *     This program is free software; you can redistribute it and/or 
@@ -53,6 +54,7 @@
 #include <linux/init.h>
 #include <linux/rtnetlink.h>
 #include <linux/dma-mapping.h>
+#include <linux/pnp.h>
 
 #include <asm/io.h>
 #include <asm/dma.h>
@@ -86,6 +88,8 @@
 static int nsc_ircc_init_108(nsc_chip_t *chip, chipio_t *info);
 static int nsc_ircc_init_338(nsc_chip_t *chip, chipio_t *info);
 static int nsc_ircc_init_39x(nsc_chip_t *chip, chipio_t *info);
+static int __devinit nsc_ircc_pnp_probe(struct pnp_dev *dev, const struct pnp_device_id *id);
+static void __devexit nsc_ircc_pnp_remove(struct pnp_dev * dev);
 
 /* These are the known NSC chips */
 static nsc_chip_t chips[] = {
@@ -125,8 +129,24 @@
 	"No dongle connected",
 };
 
+/* PNP probing */
+static const struct pnp_device_id nsc_ircc_pnp_table[] = {
+	{ .id = "NSC6001", .driver_data = 0 },
+	{ .id = "IBM0071", .driver_data = 0 },
+	{ }
+};
+
+MODULE_DEVICE_TABLE(pnp, nsc_ircc_pnp_table);
+
+static struct pnp_driver nsc_ircc_pnp_driver = {
+	.name = "nsc-ircc",
+	.id_table = nsc_ircc_pnp_table,
+	.probe = nsc_ircc_pnp_probe,
+	.remove = __devexit_p(nsc_ircc_pnp_remove),
+};
+
 /* Some prototypes */
-static int  nsc_ircc_open(int i, chipio_t *info);
+static int  nsc_ircc_open(chipio_t *info);
 static int  nsc_ircc_close(struct nsc_ircc_cb *self);
 static int  nsc_ircc_setup(chipio_t *info);
 static void nsc_ircc_pio_receive(struct nsc_ircc_cb *self);
@@ -147,6 +167,9 @@
 static struct net_device_stats *nsc_ircc_net_get_stats(struct net_device *dev);
 static int nsc_ircc_pmproc(struct pm_dev *dev, pm_request_t rqst, void *data);
 
+/* Globals */
+static int pnp_registered_port;
+
 /*
  * Function nsc_ircc_init ()
  *
@@ -162,6 +185,14 @@
 	int cfg, id;
 	int reg;
 	int i = 0;
+	int r;
+
+	/* Register with PnP subsystem to detect disable ports */
+	r = pnp_register_driver(&nsc_ircc_pnp_driver);
+	if (r >= 0) {
+		pnp_registered_port = 1;
+		ret = 0;
+	}
 
 	/* Probe for all the NSC chipsets we know about */
 	for (chip=chips; chip->name ; chip++) {
@@ -203,7 +234,7 @@
 				} else
 					chip->probe(chip, &info);
 
-				if (nsc_ircc_open(i, &info) == 0)
+				if (nsc_ircc_open(&info) == 0)
 					ret = 0;
 				i++;
 			} else {
@@ -228,6 +259,9 @@
 
 	pm_unregister_all(nsc_ircc_pmproc);
 
+	if (pnp_registered_port)
+		pnp_unregister_driver(&nsc_ircc_pnp_driver);
+
 	for (i=0; i < 4; i++) {
 		if (dev_self[i])
 			nsc_ircc_close(dev_self[i]);
@@ -240,7 +274,7 @@
  *    Open driver instance
  *
  */
-static int __init nsc_ircc_open(int i, chipio_t *info)
+static int __devinit nsc_ircc_open(chipio_t *info)
 {
 	struct net_device *dev;
 	struct nsc_ircc_cb *self;
@@ -250,6 +284,16 @@
 
 	IRDA_DEBUG(2, "%s()\n", __FUNCTION__);
 
+	int i;
+ 	for (i=0; i < 4; i++) {
+		if (!dev_self[i])
+			break;
+	}
+	if (i == 4) {
+		IRDA_ERROR("%s(), maximum number of supported chips reached!\n", __FUNCTION__);
+		return -ENOMEM;
+	}
+
 	IRDA_MESSAGE("%s, Found chip at base=0x%03x\n", driver_name,
 		     info->cfg_base);
 
@@ -388,7 +432,7 @@
  *    Close driver instance
  *
  */
-static int __exit nsc_ircc_close(struct nsc_ircc_cb *self)
+static int __devexit nsc_ircc_close(struct nsc_ircc_cb *self)
 {
 	int iobase;
 
@@ -805,6 +849,56 @@
 	return 0;
 }
 
+/* PNP probing */
+static int __devinit
+nsc_ircc_pnp_probe(struct pnp_dev *dev, const struct pnp_device_id *id)
+{
+	chipio_t info;
+
+	memset(&info, 0, sizeof(chipio_t));
+	info.irq = -1;
+	info.dma = -1;
+
+	/* There don't seem to be any way to get the cfg_base.
+	 * On my box, cfg_base is in the PnP descriptor of the
+	 * motherboard. Oh well... Jean II */
+
+	if (pnp_port_valid(dev, 0) &&
+		!(pnp_port_flags(dev, 0) & IORESOURCE_DISABLED))
+		info.fir_base = pnp_port_start(dev, 0);
+
+	if (pnp_irq_valid(dev, 0) &&
+		!(pnp_irq_flags(dev, 0) & IORESOURCE_DISABLED))
+		info.irq = pnp_irq(dev, 0);
+
+	if (pnp_dma_valid(dev, 0) &&
+		!(pnp_dma_flags(dev, 0) & IORESOURCE_DISABLED))
+		info.dma = pnp_dma(dev, 0);
+
+	IRDA_DEBUG(0, "%s() : Found cfg_base 0x%03X ; firbase 0x%03X ; irq %d ; dma %d.\n", __FUNCTION__, info.cfg_base, info.fir_base, info.irq, info.dma);
+
+	if(/*(info.cfg_base == 0) ||*/ (info.fir_base == 0) ||
+	   (info.irq == -1) || (info.dma == -1)) {
+		/* Returning an error will disable the device. Yuck ! */
+		//return -EINVAL;
+		return 0;
+	}
+
+	/* We should identify and initialise the device */
+	if (nsc_ircc_open(&info) == 0)
+		pnp_set_drvdata(dev, (void *)1);
+
+	return 0;
+}
+
+static void __devexit
+nsc_ircc_pnp_remove(struct pnp_dev * dev)
+{
+	int index = (int)pnp_get_drvdata(dev);
+	if (index && dev_self[index - 1])
+		nsc_ircc_close(dev_self[index - 1]);
+}
+
 /*
  * Function nsc_ircc_setup (info)
  *
