[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

[PATCH] PCMCIA network cards + Cardbus



Hi,

I have created patches now for ddetect and netcfg which implement
Cardbus support and proper configuration of PCMCIA network
interfaces. The latter means that it doesn't create an auto entry for
PCMCIA cards but lists it in a "mapping hotplug" stanza. The whole
thing is implemented by a temporary hotplug agent. The module loading
part for Cardbus devices isn't very nice but I'm not sure how to do it
otherwise, and besides, we will have to do it differently for 2.6
kernels anyway.

(By the way, is anybody actively working on porting d-i to 2.6
kernels?)

-- 
Pelle
Index: ddetect/hotplug-pcmcia.sh
===================================================================
--- ddetect/hotplug-pcmcia.sh	(revision 0)
+++ ddetect/hotplug-pcmcia.sh	(revision 0)
@@ -0,0 +1,73 @@
+#!/bin/sh
+#
+# hotplug-pcmcia.sh - Handle hotplug events for PCMCIA devices during detection
+#
+
+log () {
+    logger -t hotplug-pcmcia "$@"
+}
+
+TYPE="$1"
+
+case $TYPE in
+    net)
+	if [ "$INTERFACE" == "" ]; then
+	    log "Got net event without interface"
+	    exit 1
+	fi
+
+	log "Detected PCMCIA network interface $INTERFACE"
+	echo $INTERFACE >>/etc/network/devhotplug
+	;;
+
+    # PCI hotplugging for Cardbus cards on 2.4 kernels only
+    pci)
+	if [ "$PCI_SLOT_NAME" = "" ]; then
+	    log "Got pci event without slot name"
+	    exit 1
+	fi
+
+	# Sanity check
+	if ! [ -f /tmp/pcmcia-discover-snapshot ]; then
+	    log "Got PCI event but have no discover snapshot! 2.6 kernel?"
+	    exit 1
+	fi
+
+	log "Detected Cardbus device at $PCI_SLOT_NAME"
+
+	# Take another snapshot of discover information and compare it
+	# with the old one to find out the module for the new device
+
+	log "Searching for module..."
+
+	modules_before=`cat /tmp/pcmcia-discover-snapshot`
+
+	DISCOVER_TEST=$(discover --version 2> /dev/null)
+	if expr "$DISCOVER_TEST" : 'discover 2.*' > /dev/null 2>&1; then
+	    dpath=linux/module/name
+	    dver=`uname -r|cut -d. -f1,2` # Kernel version (e.g. 2.4)
+	    dflags="-d all -e pci scsi fixeddisk modem network removabledisk"
+	    
+	    echo `discover --data-path=$dpath --data-version=$dver $dflags` \
+		| sed 's/ $//' >/tmp/pcmcia-discover-snapshot
+	else
+	    discover --format="%m " --disable-all --enable=pci \
+		scsi ide ethernet \
+		| sed 's/ $//' >/tmp/pcmcia-discover-snapshot
+	fi
+	    
+	modules_after=`cat /tmp/pcmcia-discover-snapshot`
+	module=`echo "${modules_after#$modules_before}" | sed 's/^ //'`
+
+	if [ -n "$module" ]; then
+	    log "Found module $module, loading"
+	    modprobe -v $module 2>&1 | logger -t hotplug-pcmcia
+	else
+	    log "No module found for Cardbus device at $PCI_SLOT_NAME"
+	fi
+	;;
+
+    *)
+	log "Got unsupported event type \"$TYPE\""
+	;;
+esac

Property changes on: ddetect/hotplug-pcmcia.sh
___________________________________________________________________
Name: svn:executable
   + *

Index: ddetect/hw-detect.sh
===================================================================
--- ddetect/hw-detect.sh	(revision 12932)
+++ ddetect/hw-detect.sh	(working copy)
@@ -303,9 +303,46 @@
 
 # get pcmcia running if possible
 if [ -x /etc/init.d/pcmcia ]; then
-	db_progress INFO hw-detect/pcmcia_step
-	CARDMGR_OPTS="-f" /etc/init.d/pcmcia start </dev/null 2>&1 | logger -t hw-detect
-	db_progress STEP $OTHER_STEPSIZE
+    db_progress INFO hw-detect/pcmcia_step
+
+    # If hotplugging is available in the kernel, we can use it to load
+    # modules for Cardbus cards and tell which network interfaces belong
+    # to PCMCIA devices. The former is only necessary on 2.4 kernels,
+    # though.
+    if [ -f /proc/sys/kernel/hotplug ]; then
+        # Snapshot discover information so we can detect modules for
+	# Cardbus cards by later comparison in the hotplug handler.
+	# (Only on 2.4 kernels.)
+	if expr `uname -r` : "2.4.*" >/dev/null 2>&1; then
+	    DISCOVER_TEST=$(discover --version 2> /dev/null)
+	    if expr "$DISCOVER_TEST" : 'discover 2.*' > /dev/null 2>&1; then
+		dpath=linux/module/name
+		dver=`uname -r|cut -d. -f1,2` # Kernel version (e.g. 2.4)
+		dflags="-d all -e pci scsi fixeddisk modem network removabledisk"
+		
+		echo `discover --data-path=$dpath --data-version=$dver $dflags` \
+		    | sed 's/ $//' >/tmp/pcmcia-discover-snapshot
+	    else
+		discover --format="%m " --disable-all --enable=pci \
+		    scsi ide ethernet \
+		    | sed 's/ $//' >/tmp/pcmcia-discover-snapshot
+	    fi
+	fi
+	
+        # Simple handling of hotplug events during PCMCIA detection
+	saved_hotplug=`cat /proc/sys/kernel/hotplug`
+	echo /bin/hotplug-pcmcia >/proc/sys/kernel/hotplug
+    fi
+    
+    CARDMGR_OPTS="-f" /etc/init.d/pcmcia start </dev/null 2>&1 \
+	| logger -t hw-detect
+    
+    if [ -f /proc/sys/kernel/hotplug ]; then
+	echo $saved_hotplug >/proc/sys/kernel/hotplug
+	rm -f /tmp/pcmcia-discover-snapshot
+    fi
+    
+    db_progress STEP $OTHER_STEPSIZE
 fi
 if [ -e /proc/bus/pccard/drivers ]; then
 	apt-install pcmcia-cs || true
Index: ddetect/Makefile
===================================================================
--- ddetect/Makefile	(revision 12932)
+++ ddetect/Makefile	(working copy)
@@ -25,6 +25,7 @@
 install-hw-detect: hw-detect.sh
 	$(INSTALL) -d $(bindir)
 	$(INSTALL) hw-detect.sh $(bindir)/hw-detect
+	$(INSTALL) hotplug-pcmcia.sh $(bindir)/hotplug-pcmcia
 
 install-hw-detect-full:
 
Index: netcfg/netcfg-common.c
===================================================================
--- netcfg/netcfg-common.c	(revision 12932)
+++ netcfg/netcfg-common.c	(working copy)
@@ -259,6 +259,30 @@
         return strdup("Unknown interface");
 }
 
+int iface_is_hotpluggable(const char *iface)
+{
+#define DEVHOTPLUG "/etc/network/devhotplug"
+    FILE* f = NULL;
+    char buf[256];
+    size_t len = strlen(iface);
+    int result = 0;
+    
+    if (!(f = fopen(DEVHOTPLUG, "r")))
+        return 0;
+    
+    while (fgets(buf, 256, f) != NULL)
+    {
+        if (!strncmp(buf, iface, len))
+        {
+            result = 1;
+            break;
+        }
+    }
+    
+    fclose(f);
+    
+    return result;
+}
 
 FILE *file_open(char *path, const char *opentype)
 {
@@ -466,6 +490,15 @@
         fprintf(fp, HELPFUL_COMMENT);
         fprintf(fp, "auto lo\n");
         fprintf(fp, "iface lo inet loopback\n");
+        if (iface_is_hotpluggable(interface)) {
+            fprintf(fp, "\n");
+            fprintf(fp, "# This is a list of hotpluggable network interfaces.\n");
+            fprintf(fp, "# They will be activated automatically by the "
+                    "hotplug subsystem.\n");
+            fprintf(fp, "mapping hotplug\n");
+            fprintf(fp, "\tscript grep\n");
+            fprintf(fp, "\tmap %s\n", interface);
+        }
         fclose(fp);
 
         di_system_prebaseconfig_append(prebaseconfig, "cp %s %s\n",
@@ -703,7 +736,8 @@
                 "\n# This entry was created during the Debian installation\n");
         fprintf(fp,
                 "# (network, broadcast and gateway are optional)\n");
-        fprintf(fp, "auto %s\n", interface);
+        if (!iface_is_hotpluggable(interface))
+            fprintf(fp, "auto %s\n", interface);
         fprintf(fp, "iface %s inet static\n", interface);
         fprintf(fp, "\taddress %s\n", inet_ntop (AF_INET, &ipaddress, ptr1, sizeof (ptr1)));
         fprintf(fp, "\tnetmask %s\n", inet_ntop (AF_INET, &netmask, ptr1, sizeof (ptr1)));
@@ -1002,7 +1036,8 @@
     if ((fp = file_open(INTERFACES_FILE, "a"))) {
         fprintf(fp,
                 "\n# This entry was created during the Debian installation\n");
-        fprintf(fp, "auto %s\n", iface);
+        if (!iface_is_hotpluggable(iface))
+            fprintf(fp, "auto %s\n", iface);
         fprintf(fp, "iface %s inet dhcp\n", iface);
         if (host)
             fprintf(fp, "\thostname %s\n", host);

Reply to: