--- peak_pci.c.orig	2011-07-28 13:43:20.000000000 +0200
+++ peak_pci.c	2011-07-28 14:08:08.000000000 +0200
@@ -38,6 +38,9 @@
 
 #define DRV_NAME  "peak_pci"
 
+// Maximum number of PEAK CAN channels on a PCI device
+#define MAX_PCAN_CHANNELS_PER_CARD 4
+
 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,23)
 #error This driver does not support Kernel versions < 2.6.23
 #endif
@@ -50,14 +53,10 @@
 struct peak_pci {
 	int channel;
 	struct pci_dev *pci_dev;
-	struct net_device *slave_dev;
+	struct net_device *slave_dev[MAX_PCAN_CHANNELS_PER_CARD - 1];
 	volatile void __iomem *conf_addr;
 };
 
-#define PEAK_PCI_SINGLE	     0	/* single channel device */
-#define PEAK_PCI_MASTER	     1	/* multi channel master device */
-#define PEAK_PCI_SLAVE	     2	/* multi channel slave device */
-
 #define PEAK_PCI_CAN_CLOCK   (16000000 / 2)
 
 #define PEAK_PCI_CDR_SINGLE  (CDR_CBP | CDR_CLKOUT_MASK | CDR_CLK_OFF)
@@ -108,12 +107,14 @@
 
 	/* Select and clear in Pita stored interrupt */
 	icr_low = readw(board->conf_addr + PITA_ICR);
-	if (board->channel == PEAK_PCI_SLAVE) {
-		if (icr_low & 0x0001)
-			writew(0x0001, board->conf_addr + PITA_ICR);
-	} else {
-		if (icr_low & 0x0002)
-			writew(0x0002, board->conf_addr + PITA_ICR);
+	switch(board->channel) {
+		case 0: if (icr_low & 0x0002) { writew(0x0002, board->conf_addr + PITA_ICR); } break;
+		case 1: if (icr_low & 0x0001) { writew(0x0001, board->conf_addr + PITA_ICR); } break;
+		case 2: if (icr_low & 0x0040) { writew(0x0040, board->conf_addr + PITA_ICR); } break;
+		case 3: if (icr_low & 0x0080) { writew(0x0080, board->conf_addr + PITA_ICR); } break;
+		default:
+					printk(KERN_INFO "Peak CAN card with an enormous amount of channels detected: %d, channel disabled.\n", board->channel);
+					break;
 	}
 }
 
@@ -139,15 +140,17 @@
 		unregister_sja1000dev(dev);
 	case 4:
 		icr_high = readw(board->conf_addr + PITA_ICR + 2);
-		if (board->channel == PEAK_PCI_SLAVE)
-			icr_high &= ~0x0001;
-		else
-			icr_high &= ~0x0002;
+		switch(board->channel) {
+			case 0: icr_high &= ~0x0002; break;
+			case 1: icr_high &= ~0x0001; break;
+			case 2: icr_high &= ~0x0040; break;
+			case 3: icr_high &= ~0x0080; break;
+		}
 		writew(icr_high, board->conf_addr + PITA_ICR + 2);
 	case 3:
 		iounmap(priv->reg_base);
 	case 2:
-		if (board->channel != PEAK_PCI_SLAVE)
+		if (board->channel == 0) // master channel
 			iounmap((void *)board->conf_addr);
 	case 1:
 		free_sja1000dev(dev);
@@ -177,7 +180,7 @@
 	board->pci_dev = pdev;
 	board->channel = channel;
 
-	if (channel != PEAK_PCI_SLAVE) {
+	if (channel == 0) { // master channel only
 
 		addr = pci_resource_start(pdev, 0);
 		board->conf_addr = ioremap(addr, PCI_CONFIG_PORT_SIZE);
@@ -190,11 +193,9 @@
 		/* Set GPIO control register */
 		writew(0x0005, board->conf_addr + PITA_GPIOICR + 2);
 
-		/* Enable single or dual channel */
-		if (channel == PEAK_PCI_MASTER)
-			writeb(0x00, board->conf_addr + PITA_GPIOICR);
-		else
-			writeb(0x04, board->conf_addr + PITA_GPIOICR);
+		// enable all channels of this card
+		writeb(0x00, board->conf_addr + PITA_GPIOICR);
+
 		/* Toggle reset */
 		writeb(0x05, board->conf_addr + PITA_MISC + 3);
 		mdelay(5);
@@ -203,13 +204,14 @@
 	} else {
 		struct sja1000_priv *master_priv = netdev_priv(*master_dev);
 		struct peak_pci *master_board = master_priv->priv;
-		master_board->slave_dev = dev;
+		BUG_ON(! (channel - 1 < sizeof(board->slave_dev)/sizeof(struct net_device *)));
+		master_board->slave_dev[channel - 1] = dev;
 		board->conf_addr = master_board->conf_addr;
 	}
 
 	addr = pci_resource_start(pdev, 1);
-	if (channel == PEAK_PCI_SLAVE)
-		addr += PCI_PORT_SIZE;
+	if (channel > 0)
+		addr += PCI_PORT_SIZE * board->channel;
 
 	priv->reg_base = ioremap(addr, PCI_PORT_SIZE);
 	if (priv->reg_base == 0) {
@@ -226,7 +228,7 @@
 
 	priv->ocr = PEAK_PCI_OCR;
 
-	if (channel == PEAK_PCI_MASTER)
+	if (channel == 0)
 		priv->cdr = PEAK_PCI_CDR_MASTER;
 	else
 		priv->cdr = PEAK_PCI_CDR_SINGLE;
@@ -239,10 +241,12 @@
 #endif
 	dev->irq = pdev->irq;
 	icr_high = readw(board->conf_addr + PITA_ICR + 2);
-	if (channel == PEAK_PCI_SLAVE)
-		icr_high |= 0x0001;
-	else
-		icr_high |= 0x0002;
+	switch(channel) {
+		case 0: icr_high |= 0x0002; break;
+		case 1: icr_high |= 0x0001; break;
+		case 2: icr_high |= 0x0040; break;
+		case 3: icr_high |= 0x0080; break;
+     }
 	writew(icr_high, board->conf_addr + PITA_ICR + 2);
 	init_step = 4;
 
@@ -256,7 +260,7 @@
 		goto failure;
 	}
 
-	if (channel != PEAK_PCI_SLAVE)
+	if (channel == 0)
 		*master_dev = dev;
 
 	printk(KERN_INFO "%s: %s at reg_base=0x%p conf_addr=%p irq=%d\n",
@@ -295,21 +299,20 @@
 	if (err)
 		goto failure_cleanup;
 
-	if (sub_sys_id > 3) {
-		err = peak_pci_add_chan(pdev,
-					PEAK_PCI_MASTER, &master_dev);
-		if (err)
-			goto failure_cleanup;
-
-		err = peak_pci_add_chan(pdev,
-					PEAK_PCI_SLAVE, &master_dev);
-		if (err)
-			goto failure_cleanup;
-	} else {
-		err = peak_pci_add_chan(pdev, PEAK_PCI_SINGLE,
-					     &master_dev);
-		if (err)
-			goto failure_cleanup;
+	/* Add the CAN channels. The number of channels available depends on sub_sys_id */
+								// 1st channel is always present
+	if ((err = peak_pci_add_chan(pdev, 0, &master_dev))) { goto failure_cleanup; }
+
+	if (sub_sys_id >= 4) {		// 2nd channel
+		if ((err = peak_pci_add_chan(pdev, 1, &master_dev))) { goto failure_cleanup; }
+	}
+
+	if (sub_sys_id >= 10) {		// 3rd channel
+		if ((err = peak_pci_add_chan(pdev, 2, &master_dev))) { goto failure_cleanup; }
+	}
+
+	if (sub_sys_id >= 12) {		// 4th channel
+		if ((err = peak_pci_add_chan(pdev, 3, &master_dev))) { goto failure_cleanup; }
 	}
 
 	pci_set_drvdata(pdev, master_dev);
@@ -332,8 +335,13 @@
 	struct sja1000_priv *priv = netdev_priv(dev);
 	struct peak_pci *board = priv->priv;
 
-	if (board->slave_dev)
-		peak_pci_del_chan(board->slave_dev, 0);
+	// close all associated CAN channels of this card
+	int i;
+	for(i = 0; i < sizeof(board->slave_dev)/sizeof(struct net_device *) ; i++) {
+		if(board->slave_dev[i] != NULL) {
+			peak_pci_del_chan(board->slave_dev[i], 0);
+		}
+	}
 	peak_pci_del_chan(dev, 0);
 
 	pci_release_regions(pdev);
