hal/hald/linux2 Makefile.am, 1.1, 1.2 classdev.c, 1.2, 1.3 ids.c, 1.1, 1.2 ids.h, 1.1, 1.2 pcmcia_cs.h, NONE, 1.1 pcmcia_utils.c, NONE, 1.1 pcmcia_utils.h, NONE, 1.1 physdev.c, 1.1, 1.2

David Zeuthen david at freedesktop.org
Sat Jan 22 12:13:47 PST 2005


Update of /cvs/hal/hal/hald/linux2
In directory gabe:/tmp/cvs-serv2337/hald/linux2

Modified Files:
	Makefile.am classdev.c ids.c ids.h physdev.c 
Added Files:
	pcmcia_cs.h pcmcia_utils.c pcmcia_utils.h 
Log Message:
2005-01-22  David Zeuthen  <davidz at redhat.com>

	* tools/device-manager/Const.py.in: Add pnp and serio to BUS_NAMES

	* hald/linux2/physdev.c: Refactor this file a bit and add support
	for the following bus devices: ide, pnp, serio, pcmcia

	* hald/linux2/ids.h (ids_find_pnp): Add prototype

	* hald/linux2/ids.c (ids_find_pnp): New function; just use
	a hardcoded array and do a slow O(n) search (might want to
	optimize this later)

	* hald/linux2/classdev.c (add_classdev_after_probing): Compute
	UDI may fail; remember to clean up

	* hald/linux2/Makefile.am: Add pcmcia_utils.[ch] as we'll need
	them until sysfs got the right properties

	* hald/linux2/pcmcia_utils.[ch]: New files; imported from old
	backend

	* hald/linux2/pcmcia_cs.h: Ditto



Index: Makefile.am
===================================================================
RCS file: /cvs/hal/hal/hald/linux2/Makefile.am,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -d -r1.1 -r1.2
--- Makefile.am	18 Jan 2005 19:48:13 -0000	1.1
+++ Makefile.am	22 Jan 2005 20:13:42 -0000	1.2
@@ -20,7 +20,9 @@
 	classdev.h		classdev.c			\
 	blockdev.h		blockdev.c			\
 	util.h			util.c				\
-	ids.h			ids.c
+	ids.h			ids.c				\
+	pcmcia_utils.h		pcmcia_utils.c
+
 
 
 

Index: classdev.c
===================================================================
RCS file: /cvs/hal/hal/hald/linux2/classdev.c,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -d -r1.2 -r1.3
--- classdev.c	19 Jan 2005 22:26:47 -0000	1.2
+++ classdev.c	22 Jan 2005 20:13:42 -0000	1.3
@@ -203,8 +203,10 @@
 	di_search_and_merge (d);
 
 	/* Compute UDI */
-	if (!handler->compute_udi (d))
+	if (!handler->compute_udi (d)) {
+		hal_device_store_remove (hald_get_tdl (), d);
 		goto out;
+	}
 	
 	/* TODO: Merge persistent properties */
 

Index: ids.c
===================================================================
RCS file: /cvs/hal/hal/hald/linux2/ids.c,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -d -r1.1 -r1.2
--- ids.c	18 Jan 2005 19:48:13 -0000	1.1
+++ ids.c	22 Jan 2005 20:13:42 -0000	1.2
@@ -558,3 +558,335 @@
 	usb_ids_load (HWDATA_DIR "/usb.ids");
 }
 
+
+/* This, somewhat incomplete, list is from http://www.plasma-online.de/english/identify/serial/pnp_id_pnp.html */
+static char *pnp_ids_list[] = {
+	"PNP0000", "AT Interrupt Controller",
+	"PNP0001", "EISA Interrupt Controller",
+	"PNP0002", "MCA Interrupt Controller",
+	"PNP0003", "APIC",
+	"PNP0004", "Cyrix SLiC MP interrupt controller",
+	"PNP0100", "AT Timer",
+	"PNP0101", "EISA Timer",
+	"PNP0102", "MCA Timer",
+	"PNP0200", "AT DMA Controller",
+	"PNP0201", "EISA DMA Controller",
+	"PNP0202", "MCA DMA Controller",
+	"PNP0300", "IBM PC/XT keyboard controller (83-key)",
+	"PNP0301", "IBM PC/AT keyboard controller (86-key)",
+	"PNP0302", "IBM PC/XT keyboard controller (84-key)",
+	"PNP0303", "IBM Enhanced (101/102-key, PS/2 mouse support)",
+	"PNP0304", "Olivetti Keyboard (83-key)",
+	"PNP0305", "Olivetti Keyboard (102-key)",
+	"PNP0306", "Olivetti Keyboard (86-key)",
+	"PNP0307", "Microsoft Windows(R) Keyboard",
+	"PNP0308", "General Input Device Emulation Interface (GIDEI) legacy",
+	"PNP0309", "Olivetti Keyboard (A101/102 key)",
+	"PNP030A", "AT&T 302 keyboard",
+	"PNP030B", "Reserved by Microsoft",
+	"PNP0320", "Japanese 101-key keyboard",
+	"PNP0321", "Japanese AX keyboard",
+	"PNP0322", "Japanese 106-key keyboard A01",
+	"PNP0323", "Japanese 106-key keyboard 002/003",
+	"PNP0324", "Japanese 106-key keyboard 001",
+	"PNP0325", "Japanese Toshiba Desktop keyboard",
+	"PNP0326", "Japanese Toshiba Laptop keyboard",
+	"PNP0327", "Japanese Toshiba Notebook keyboard",
+	"PNP0340", "Korean 84-key keyboard",
+	"PNP0341", "Korean 86-key keyboard",
+	"PNP0342", "Korean Enhanced keyboard",
+	"PNP0343", "Korean Enhanced keyboard 101b",
+	"PNP0343", "Korean Enhanced keyboard 101c",
+	"PNP0344", "Korean Enhanced keyboard 103",
+	"PNP0400", "Standard LPT printer port",
+	"PNP0401", "ECP printer port",
+	"PNP0500", "Standard PC COM port",
+	"PNP0501", "16550A-compatible COM port",
+	"PNP0510", "Generic IRDA-compatible device",
+	"PNP0600", "Generic ESDI/IDE/ATA compatible hard disk controller",
+	"PNP0601", "Plus Hardcard II",
+	"PNP0602", "Plus Hardcard IIXL/EZ",
+	"PNP0603", "Generic IDE supporting Microsoft Device Bay Specification",
+	"PNP0700", "PC standard floppy disk controller",
+	"PNP0701", "Standard floppy controller supporting MS Device Bay Spec",
+	"PNP0802", "Microsoft Sound System compatible device (obsolete, use PNPB0xx instead)",
+	"PNP0900", "VGA Compatible",
+	"PNP0901", "Video Seven VRAM/VRAM II/1024i",
+	"PNP0902", "IBM 8514/A Compatible",
+	"PNP0903", "Trident VGA",
+	"PNP0904", "Cirrus Logic Laptop VGA",
+	"PNP0905", "Cirrus Logic VGA",
+	"PNP0906", "Tseng Labs ET4000",
+	"PNP0907", "Western Digital VGA",
+	"PNP0908", "Western Digital Laptop VGA",
+	"PNP0909", "S3 Inc. 911/924",
+	"PNP090A", "ATI Ultra Pro/Plus (Mach 32)",
+	"PNP090B", "ATI Ultra (Mach 8)",
+	"PNP090C", "IBM XGA Compatible",
+	"PNP090D", "ATI VGA Wonder",
+	"PNP090E", "Weitek P9000 Graphics Adapter",
+	"PNP090F", "Oak Technology VGA",
+	"PNP0910", "Compaq QVision",
+	"PNP0911", "IBM XGA/2",
+	"PNP0912", "Tseng Labs ET4000 W32/W32i/W32p",
+	"PNP0913", "S3 Inc. 801/928/964",
+	"PNP0914", "Cirrus Logic 5429/5434 (memory mapped)",
+	"PNP0915", "Compaq Advanced VGA (AVGA)",
+	"PNP0916", "ATI Ultra Pro Turbo (Mach64)",
+	"PNP0917", "Reserved by Microsoft",
+	"PNP0918", "Matrox MGA",
+	"PNP0919", "Compaq QVision 2000",
+	"PNP091A", "Tseng Labs W128",
+	"PNP0930", "Chips & Technologies Super VGA",
+	"PNP0931", "Chips & Technologies Accelerator",
+	"PNP0940", "NCR 77c22e Super VGA",
+	"PNP0941", "NCR 77c32blt",
+	"PNP09FF", "Plug and Play Monitors (VESA DDC)",
+	"PNP0A00", "ISA Bus",
+	"PNP0A01", "EISA Bus",
+	"PNP0A02", "MCA Bus",
+	"PNP0A03", "PCI Bus",
+	"PNP0A04", "VESA/VL Bus",
+	"PNP0A05", "Generic ACPI Bus",
+	"PNP0A06", "Generic ACPI Extended-IO Bus (EIO bus)",
+	"PNP0800", "AT-style speaker sound",
+	"PNP0B00", "AT Real-Time Clock",
+	"PNP0C00", "Plug and Play BIOS (only created by the root enumerator)",
+	"PNP0C01", "System Board",
+	"PNP0C02", "General ID for reserving resources required by PnP motherboard registers. (Not device specific.)",
+	"PNP0C03", "Plug and Play BIOS Event Notification Interrupt",
+	"PNP0C04", "Math Coprocessor",
+	"PNP0C05", "APM BIOS (Version independent)",
+	"PNP0C06", "Reserved for identification of early Plug and Play BIOS implementation",
+	"PNP0C07", "Reserved for identification of early Plug and Play BIOS implementation",
+	"PNP0C08", "ACPI system board hardware",
+	"PNP0C09", "ACPI Embedded Controller",
+	"PNP0C0A", "ACPI Control Method Battery",
+	"PNP0C0B", "ACPI Fan",
+	"PNP0C0C", "ACPI power button device",
+	"PNP0C0D", "ACPI lid device",
+	"PNP0C0E", "ACPI sleep button device",
+	"PNP0C0F", "PCI interrupt link device",
+	"PNP0C10", "ACPI system indicator device",
+	"PNP0C11", "ACPI thermal zone",
+	"PNP0C12", "Device Bay Controller",
+	"PNP0E00", "Intel 82365-Compatible PCMCIA Controller",
+	"PNP0E01", "Cirrus Logic CL-PD6720 PCMCIA Controller",
+	"PNP0E02", "VLSI VL82C146 PCMCIA Controller",
+	"PNP0E03", "Intel 82365-compatible CardBus controller",
+	"PNP0F00", "Microsoft Bus Mouse",
+	"PNP0F01", "Microsoft Serial Mouse",
+	"PNP0F02", "Microsoft InPort Mouse",
+	"PNP0F03", "Microsoft PS/2-style Mouse",
+	"PNP0F04", "Mouse Systems Mouse",
+	"PNP0F05", "Mouse Systems 3-Button Mouse (COM2)",
+	"PNP0F06", "Genius Mouse (COM1)",
+	"PNP0F07", "Genius Mouse (COM2)",
+	"PNP0F08", "Logitech Serial Mouse",
+	"PNP0F09", "Microsoft BallPoint Serial Mouse",
+	"PNP0F0A", "Microsoft Plug and Play Mouse",
+	"PNP0F0B", "Microsoft Plug and Play BallPoint Mouse",
+	"PNP0F0C", "Microsoft-compatible Serial Mouse",
+	"PNP0F0D", "Microsoft-compatible InPort-compatible Mouse",
+	"PNP0F0E", "Microsoft-compatible PS/2-style Mouse",
+	"PNP0F0F", "Microsoft-compatible Serial BallPoint-compatible Mouse",
+	"PNP0F10", "Texas Instruments QuickPort Mouse",
+	"PNP0F11", "Microsoft-compatible Bus Mouse",
+	"PNP0F12", "Logitech PS/2-style Mouse",
+	"PNP0F13", "PS/2 Port for PS/2-style Mice",
+	"PNP0F14", "Microsoft Kids Mouse",
+	"PNP0F15", "Logitech bus mouse",
+	"PNP0F16", "Logitech SWIFT device",
+	"PNP0F17", "Logitech-compatible serial mouse",
+	"PNP0F18", "Logitech-compatible bus mouse",
+	"PNP0F19", "Logitech-compatible PS/2-style Mouse",
+	"PNP0F1A", "Logitech-compatible SWIFT Device",
+	"PNP0F1B", "HP Omnibook Mouse",
+	"PNP0F1C", "Compaq LTE Trackball PS/2-style Mouse",
+	"PNP0F1D", "Compaq LTE Trackball Serial Mouse",
+	"PNP0F1E", "Microsoft Kids Trackball Mouse",
+	"PNP0F1F", "Reserved by Microsoft Input Device Group",
+	"PNP0F20", "Reserved by Microsoft Input Device Group",
+	"PNP0F21", "Reserved by Microsoft Input Device Group",
+	"PNP0F22", "Reserved by Microsoft Input Device Group",
+	"PNP0F23", "Reserved by Microsoft Input Device Group",
+	"PNP0FFF", "Reserved by Microsoft Systems",
+	"PNP8001", "Novell/Anthem NE3200",
+	"PNP8004", "Compaq NE3200",
+	"PNP8006", "Intel EtherExpress/32",
+	"PNP8008", "HP EtherTwist EISA LAN Adapter/32 (HP27248A)",
+	"PNP8065", "Ungermann-Bass NIUps or NIUps/EOTP",
+	"PNP8072", "DEC (DE211) EtherWorks MC/TP",
+	"PNP8073", "DEC (DE212) EtherWorks MC/TP_BNC",
+	"PNP8078", "DCA 10 Mb MCA",
+	"PNP8074", "HP MC LAN Adapter/16 TP (PC27246)",
+	"PNP80C9", "IBM Token Ring",
+	"PNP80CA", "IBM Token Ring II",
+	"PNP80CB", "IBM Token Ring II/Short",
+	"PNP80CC", "IBM Token Ring 4/16Mbs",
+	"PNP80D3", "Novell/Anthem NE1000",
+	"PNP80D4", "Novell/Anthem NE2000",
+	"PNP80D5", "NE1000 Compatible",
+	"PNP80D6", "NE2000 Compatible",
+	"PNP80D7", "Novell/Anthem NE1500T",
+	"PNP80D8", "Novell/Anthem NE2100",
+	"PNP80DD", "SMC ARCNETPC",
+	"PNP80DE", "SMC ARCNET PC100, PC200",
+	"PNP80DF", "SMC ARCNET PC110, PC210, PC250",
+	"PNP80E0", "SMC ARCNET PC130/E",
+	"PNP80E1", "SMC ARCNET PC120, PC220, PC260",
+	"PNP80E2", "SMC ARCNET PC270/E",
+	"PNP80E5", "SMC ARCNET PC600W, PC650W",
+	"PNP80E7", "DEC DEPCA",
+	"PNP80E8", "DEC (DE100) EtherWorks LC",
+	"PNP80E9", "DEC (DE200) EtherWorks Turbo",
+	"PNP80EA", "DEC (DE101) EtherWorks LC/TP",
+	"PNP80EB", "DEC (DE201) EtherWorks Turbo/TP",
+	"PNP80EC", "DEC (DE202) EtherWorks Turbo/TP_BNC",
+	"PNP80ED", "DEC (DE102) EtherWorks LC/TP_BNC",
+	"PNP80EE", "DEC EE101 (Built-In)",
+	"PNP80EF", "DEC PC 433 WS (Built-In)",
+	"PNP80F1", "3Com EtherLink Plus",
+	"PNP80F3", "3Com EtherLink II or IITP (8 or 16-bit)",
+	"PNP80F4", "3Com TokenLink",
+	"PNP80F6", "3Com EtherLink 16",
+	"PNP80F7", "3Com EtherLink III",
+	"PNP80F8", "3Com Generic Etherlink Plug and Play Device",
+	"PNP80FB", "Thomas Conrad TC6045",
+	"PNP80FC", "Thomas Conrad TC6042",
+	"PNP80FD", "Thomas Conrad TC6142",
+	"PNP80FE", "Thomas Conrad TC6145",
+	"PNP80FF", "Thomas Conrad TC6242",
+	"PNP8100", "Thomas Conrad TC6245",
+	"PNP8105", "DCA 10 MB",
+	"PNP8106", "DCA 10 MB Fiber Optic",
+	"PNP8107", "DCA 10 MB Twisted Pair",
+	"PNP8113", "Racal NI6510",
+	"PNP811C", "Ungermann-Bass NIUpc",
+	"PNP8120", "Ungermann-Bass NIUpc/EOTP",
+	"PNP8123", "SMC StarCard PLUS (WD/8003S)",
+	"PNP8124", "SMC StarCard PLUS With On Board Hub (WD/8003SH)",
+	"PNP8125", "SMC EtherCard PLUS (WD/8003E)",
+	"PNP8126", "SMC EtherCard PLUS With Boot ROM Socket (WD/8003EBT)",
+	"PNP8127", "SMC EtherCard PLUS With Boot ROM Socket (WD/8003EB)",
+	"PNP8128", "SMC EtherCard PLUS TP (WD/8003WT)",
+	"PNP812A", "SMC EtherCard PLUS 16 With Boot ROM Socket (WD/8013EBT)",
+	"PNP812D", "Intel EtherExpress 16 or 16TP",
+	"PNP812F", "Intel TokenExpress 16/4",
+	"PNP8130", "Intel TokenExpress MCA 16/4",
+	"PNP8132", "Intel EtherExpress 16 (MCA)",
+	"PNP8137", "Artisoft AE-1",
+	"PNP8138", "Artisoft AE-2 or AE-3",
+	"PNP8141", "Amplicard AC 210/XT",
+	"PNP8142", "Amplicard AC 210/AT",
+	"PNP814B", "Everex SpeedLink /PC16 (EV2027)",
+	"PNP8155", "HP PC LAN Adapter/8 TP (HP27245)",
+	"PNP8156", "HP PC LAN Adapter/16 TP (HP27247A)",
+	"PNP8157", "HP PC LAN Adapter/8 TL (HP27250)",
+	"PNP8158", "HP PC LAN Adapter/16 TP Plus (HP27247B)",
+	"PNP8159", "HP PC LAN Adapter/16 TL Plus (HP27252)",
+	"PNP815F", "National Semiconductor Ethernode *16AT",
+	"PNP8160", "National Semiconductor AT/LANTIC EtherNODE 16-AT3",
+	"PNP816A", "NCR Token-Ring 4 Mbs ISA",
+	"PNP816D", "NCR Token-Ring 16/4 Mbs ISA",
+	"PNP8191", "Olicom 16/4 Token-Ring Adapter",
+	"PNP81C3", "SMC EtherCard PLUS Elite (WD/8003EP)",
+	"PNP81C4", "SMC EtherCard PLUS 10T (WD/8003W)",
+	"PNP81C5", "SMC EtherCard PLUS Elite 16 (WD/8013EP)",
+	"PNP81C6", "SMC EtherCard PLUS Elite 16T (WD/8013W)",
+	"PNP81C7", "SMC EtherCard PLUS Elite 16 Combo (WD/8013EW or 8013EWC)",
+	"PNP81C8", "SMC EtherElite Ultra 16",
+	"PNP81E4", "Pure Data PDI9025-32 (Token Ring)",
+	"PNP81E6", "Pure Data PDI508+ (ArcNet)",
+	"PNP81E7", "Pure Data PDI516+ (ArcNet)",
+	"PNP81EB", "Proteon Token Ring (P1390)",
+	"PNP81EC", "Proteon Token Ring (P1392)",
+	"PNP81ED", "Proteon Token Ring ISA (P1340)",
+	"PNP81EE", "Proteon Token Ring ISA (P1342)",
+	"PNP81EF", "Proteon Token Ring ISA (P1346)",
+	"PNP81F0", "Proteon Token Ring ISA (P1347)",
+	"PNP81FF", "Cabletron E2000 Series DNI",
+	"PNP8200", "Cabletron E2100 Series DNI",
+	"PNP8209", "Zenith Data Systems Z-Note",
+	"PNP820A", "Zenith Data Systems NE2000-Compatible",
+	"PNP8213", "Xircom Pocket Ethernet II",
+	"PNP8214", "Xircom Pocket Ethernet I",
+	"PNP821D", "RadiSys EXM-10",
+	"PNP8227", "SMC 3000 Series",
+	"PNP8228", "SMC 91C2 controller",
+	"PNP8231", "AMD AM2100/AM1500T",
+	"PNP8263", "Tulip NCC-16",
+	"PNP8277", "Exos 105",
+	"PNP828A", "Intel '595 based Ethernet",
+	"PNP828B", "TI2000-style Token Ring",
+	"PNP828C", "AMD PCNet Family cards",
+	"PNP828D", "AMD PCNet32 (VL version)",
+	"PNP8294", "IrDA Infrared NDIS driver (Microsoft-supplied)",
+	"PNP82BD", "IBM PCMCIA-NIC",
+	"PNP82C2", "Xircom CE10",
+	"PNP82C3", "Xircom CEM2",
+	"PNP8321", "DEC Ethernet (All Types)",
+	"PNP8323", "SMC EtherCard (All Types except 8013/A)",
+	"PNP8324", "ARCNET Compatible",
+	"PNP8326", "Thomas Conrad (All Arcnet Types)",
+	"PNP8327", "IBM Token Ring (All Types)",
+	"PNP8385", "Remote Network Access [RNA] Driver",
+	"PNP8387", "Remote Network Access [RNA] PPP Driver",
+	"PNP8388", "Reserved for Microsoft Networking components",
+	"PNP8389", "Peer IrLAN infrared driver (Microsoft-supplied)",
+	"PNPA002", "Future Domain 16-700 compatible controller",
+	"PNPA003", "Mitsumi CD-ROM adapter (Panasonic spec., used on SBPro/SB16)",
+	"PNPA01B", "Trantor 128 SCSI Controller",
+	"PNPA01D", "Trantor T160 SCSI Controller",
+	"PNPA01E", "Trantor T338 Parallel SCSI controller",
+	"PNPA01F", "Trantor T348 Parallel SCSI controller",
+	"PNPA020", "Trantor Media Vision SCSI controller",
+	"PNPA022", "Always IN-2000 SCSI controller",
+	"PNPA02B", "Sony proprietary CD-ROM controller",
+	"PNPA02D", "Trantor T13b 8-bit SCSI controller",
+	"PNPA02F", "Trantor T358 Parallel SCSI controller",
+	"PNPA030", "Mitsumi LU-005 Single Speed CD-ROM controller + drive",
+	"PNPA031", "Mitsumi FX-001 Single Speed CD-ROM controller + drive",
+	"PNPA032", "Mitsumi FX-001 Double Speed CD-ROM controller + drive",
+	"PNPB000", "Creative Labs Sound Blaster 1.5 (or compatible sound device)",
+	"PNPB001", "Creative Labs Sound Blaster 2.0 (or compatible sound device)",
+	"PNPB002", "Creative Labs Sound Blaster Pro (or compatible sound device)",
+	"PNPB003", "Creative Labs Sound Blaster 16 (or compatible sound device)",
+	"PNPB004", "MediaVision Thunderboard (or compatible sound device)",
+	"PNPB005", "Adlib-compatible FM synthesizer device",
+	"PNPB006", "MPU401 compatible",
+	"PNPB007", "Microsoft Windows Sound System-compatible sound device",
+	"PNPB008", "Compaq Business Audio",
+	"PNPB009", "Plug and Play Microsoft Windows Sound System Device",
+	"PNPB00A", "MediaVision Pro Audio Spectrum (Trantor SCSI enabled, Thunder Chip Disabled)",
+	"PNPB00B", "MediaVision Pro Audio 3D",
+	"PNPB00C", "MusicQuest MQX-32M",
+	"PNPB00D", "MediaVision Pro Audio Spectrum Basic (No Trantor SCSI, Thunder Chip Enabled)",
+	"PNPB00E", "MediaVision Pro Audio Spectrum (Trantor SCSI enabled, Thunder Chip Disabled)",
+	"PNPB00F", "MediaVision Jazz-16 chipset (OEM Versions)",
+	"PNPB010", "Orchid Videola - Auravision VxP500 chipset",
+	"PNPB018", "MediaVision Pro Audio Spectrum 8-bit",
+	"PNPB019", "MediaVision Pro Audio Spectrum Basic (No Trantor SCSI, Thunder Chip Enabled)",
+	"PNPB020", "Yamaha OPL3-compatible FM synthesizer device",
+	"PNPB02F", "Joystick/Game port",
+	"PNPC000", "Compaq 14400 Modem (TBD)",
+	"PNPC001", "Compaq 2400/9600 Modem (TBD)",
+	NULL
+};
+
+
+void
+ids_find_pnp (const char *pnp_id, char **pnp_description)
+{
+	unsigned int i;
+
+	/* OK, so someone should optimize this lookup - send me patches */
+	for (i = 0; pnp_ids_list[2*i] != NULL; i++) {
+		if (strcmp (pnp_id, pnp_ids_list[2*i]) == 0) {
+			*pnp_description = pnp_ids_list[2*i + 1];
+			return;
+		}
+	}
+
+	*pnp_description = NULL;
+}

Index: ids.h
===================================================================
RCS file: /cvs/hal/hal/hald/linux2/ids.h,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -d -r1.1 -r1.2
--- ids.h	18 Jan 2005 19:48:13 -0000	1.1
+++ ids.h	22 Jan 2005 20:13:42 -0000	1.2
@@ -40,5 +40,8 @@
 ids_find_usb (int vendor_id, int product_id,
 	      char **vendor_name, char **product_name);
 
+void
+ids_find_pnp (const char *pnp_id, char **pnp_description);
+
 
 #endif /* IDS_H */

--- NEW FILE: pcmcia_cs.h ---
/***************************************************************************
 * CVSID: $Id: pcmcia_cs.h,v 1.1 2005/01/22 20:13:42 david Exp $
 *
 * PCMCIA Card utilities
 *
 * Copyright (C) 2003 Dan Williams <dcbw at redhat.com>
 *
 * Licensed under the Academic Free License version 2.0
 *
 * Most of this code was derived from pcmcia-cs code, originally
 * developed by David A. Hinds <dahinds at users.sourceforge.net>.
 * Portions created by David A. Hinds are Copyright (C) 1999 David A. Hinds.
 * All Rights Reserved.  It has been modified for integration into HAL
 * by Dan Williams and is covered by the GPL version 2 license.
 *
 * 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 Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 *
 **************************************************************************/

#ifndef PCMCIA_CS_H
#define PCMCIA_CS_H

#include <sys/types.h>

/* cs_types.h */
typedef u_short	ioaddr_t;
typedef u_short	socket_t;
typedef u_int	event_t;
typedef u_char	cisdata_t;
typedef u_short	page_t;

struct client_t;
typedef struct client_t *client_handle_t;

struct window_t;
typedef struct window_t *window_handle_t;

struct region_t;
typedef struct region_t *memory_handle_t;

struct eraseq_t;
typedef struct eraseq_t *eraseq_handle_t;

#ifndef DEV_NAME_LEN
#define DEV_NAME_LEN 32
#endif

typedef char dev_info_t[DEV_NAME_LEN];

/* cs.h */

/* For AccessConfigurationRegister */
typedef struct conf_reg_t {
    u_char	Function;
    u_int	Action;
    off_t	Offset;
    u_int	Value;
} conf_reg_t;

/* Actions */
#define CS_READ		1
#define CS_WRITE	2

/* for AdjustResourceInfo */
typedef struct adjust_t {
    u_int	Action;
    u_int	Resource;
    u_int	Attributes;
    union {
	struct memory {
	    u_long	Base;
	    u_long	Size;
	} memory;
	struct io {
	    ioaddr_t	BasePort;
	    ioaddr_t	NumPorts;
	    u_int	IOAddrLines;
	} io;
	struct irq {
	    u_int	IRQ;
	} irq;
    } resource;
} adjust_t;

typedef struct servinfo_t {
    char	Signature[2];
    u_int	Count;
    u_int	Revision;
    u_int	CSLevel;
    char	*VendorString;
} servinfo_t;

typedef struct event_callback_args_t {
    client_handle_t client_handle;
    void	*info;
    void	*mtdrequest;
    void	*buffer;
    void	*misc;
    void	*client_data;
    struct bus_operations *bus;
} event_callback_args_t;

/* for GetConfigurationInfo */
typedef struct config_info_t {
    u_char	Function;
    u_int	Attributes;
    u_int	Vcc, Vpp1, Vpp2;
    u_int	IntType;
    u_int	ConfigBase;
    u_char	Status, Pin, Copy, Option, ExtStatus;
    u_int	Present;
    u_int	CardValues;
    u_int	AssignedIRQ;
    u_int	IRQAttributes;
    ioaddr_t	BasePort1;
    ioaddr_t	NumPorts1;
    u_int	Attributes1;
    ioaddr_t	BasePort2;
    ioaddr_t	NumPorts2;
    u_int	Attributes2;
    u_int	IOAddrLines;
} config_info_t;

/* For GetFirst/NextClient */
typedef struct client_req_t {
    socket_t	Socket;
    u_int	Attributes;
} client_req_t;

#define CLIENT_THIS_SOCKET	0x01

/* For RegisterClient */
typedef struct client_reg_t {
    dev_info_t	*dev_info;
    u_int	Attributes;
    u_int	EventMask;
    int		(*event_handler)(event_t event, int priority,
				 event_callback_args_t *);
    event_callback_args_t event_callback_args;
    u_int	Version;
} client_reg_t;

/* IntType field */
#define INT_CARDBUS		0x04

/* For GetMemPage, MapMemPage */
typedef struct memreq_t {
    u_int	CardOffset;
    page_t	Page;
} memreq_t;

/* For ModifyWindow */
typedef struct modwin_t {
    u_int	Attributes;
    u_int	AccessSpeed;
} modwin_t;

/* For RequestWindow */
typedef struct win_req_t {
    u_int	Attributes;
    u_long	Base;
    u_int	Size;
    u_int	AccessSpeed;
} win_req_t;

typedef struct cs_status_t {
    u_char	Function;
    event_t 	CardState;
    event_t	SocketState;
} cs_status_t;

typedef struct error_info_t {
    int		func;
    int		retcode;
} error_info_t;

/* Special stuff for binding drivers to sockets */
typedef struct bind_req_t {
    socket_t	Socket;
    u_char	Function;
    dev_info_t	*dev_info;
} bind_req_t;

/* Flag to bind to all functions */
#define BIND_FN_ALL	0xff

typedef struct mtd_bind_t {
    socket_t	Socket;
    u_int	Attributes;
    u_int	CardOffset;
    dev_info_t	*dev_info;
} mtd_bind_t;


/* cistpl.h */

#define CISTPL_VERS_1		0x15
#define CISTPL_MANFID		0x20
#define CISTPL_FUNCID		0x21

typedef struct cistpl_longlink_t {
    u_int	addr;
} cistpl_longlink_t;

typedef struct cistpl_checksum_t {
    u_short	addr;
    u_short	len;
    u_char	sum;
} cistpl_checksum_t;

#define CISTPL_MAX_FUNCTIONS	8

typedef struct cistpl_longlink_mfc_t {
    u_char	nfn;
    struct {
	u_char	space;
	u_int	addr;
    } fn[CISTPL_MAX_FUNCTIONS];
} cistpl_longlink_mfc_t;

#define CISTPL_MAX_ALTSTR_STRINGS	4

typedef struct cistpl_altstr_t {
    u_char	ns;
    u_char	ofs[CISTPL_MAX_ALTSTR_STRINGS];
    char	str[254];
} cistpl_altstr_t;

#define CISTPL_MAX_DEVICES	4

typedef struct cistpl_device_t {
    u_char	ndev;
    struct {
	u_char 	type;
	u_char	wp;
	u_int	speed;
	u_int	size;
    } dev[CISTPL_MAX_DEVICES];
} cistpl_device_t;

typedef struct cistpl_device_o_t {
    u_char		flags;
    cistpl_device_t	device;
} cistpl_device_o_t;

#define CISTPL_VERS_1_MAX_PROD_STRINGS	4

typedef struct cistpl_vers_1_t {
    u_char	major;
    u_char	minor;
    u_char	ns;
    u_char	ofs[CISTPL_VERS_1_MAX_PROD_STRINGS];
    char	str[254];
} cistpl_vers_1_t;

typedef struct cistpl_jedec_t {
    u_char	nid;
    struct {
	u_char	mfr;
	u_char	info;
    } id[CISTPL_MAX_DEVICES];
} cistpl_jedec_t;

typedef struct cistpl_manfid_t {
    u_short	manf;
    u_short	card;
} cistpl_manfid_t;

typedef struct cistpl_funcid_t {
    u_char	func;
    u_char	sysinit;
} cistpl_funcid_t;

typedef struct cistpl_funce_t {
    u_char	type;
    u_char	data[0];
} cistpl_funce_t;

typedef struct cistpl_bar_t {
    u_char	attr;
    u_int	size;
} cistpl_bar_t;

typedef struct cistpl_config_t {
    u_char	last_idx;
    u_int	base;
    u_int	rmask[4];
    u_char	subtuples;
} cistpl_config_t;

typedef struct cistpl_power_t {
    u_char	present;
    u_char	flags;
    u_int	param[7];
} cistpl_power_t;

typedef struct cistpl_timing_t {
    u_int	wait, waitscale;
    u_int	ready, rdyscale;
    u_int	reserved, rsvscale;
} cistpl_timing_t;

#define CISTPL_IO_MAX_WIN	16

typedef struct cistpl_io_t {
    u_char	flags;
    u_char	nwin;
    struct {
	u_int	base;
	u_int	len;
    } win[CISTPL_IO_MAX_WIN];
} cistpl_io_t;

typedef struct cistpl_irq_t {
    u_int	IRQInfo1;
    u_int	IRQInfo2;
} cistpl_irq_t;

#define CISTPL_MEM_MAX_WIN	8

typedef struct cistpl_mem_t {
    u_char	flags;
    u_char	nwin;
    struct {
	u_int	len;
	u_int	card_addr;
	u_int	host_addr;
    } win[CISTPL_MEM_MAX_WIN];
} cistpl_mem_t;

typedef struct cistpl_cftable_entry_t {
    u_char		index;
    u_short		flags;
    u_char		interface;
    cistpl_power_t	vcc, vpp1, vpp2;
    cistpl_timing_t	timing;
    cistpl_io_t		io;
    cistpl_irq_t	irq;
    cistpl_mem_t	mem;
    u_char		subtuples;
} cistpl_cftable_entry_t;

typedef struct cistpl_cftable_entry_cb_t {
    u_char		index;
    u_int		flags;
    cistpl_power_t	vcc, vpp1, vpp2;
    u_char		io;
    cistpl_irq_t	irq;
    u_char		mem;
    u_char		subtuples;
} cistpl_cftable_entry_cb_t;

typedef struct cistpl_device_geo_t {
    u_char		ngeo;
    struct {
	u_char		buswidth;
	u_int		erase_block;
	u_int		read_block;
	u_int		write_block;
	u_int		partition;
	u_int		interleave;
    } geo[CISTPL_MAX_DEVICES];
} cistpl_device_geo_t;

typedef struct cistpl_vers_2_t {
    u_char	vers;
    u_char	comply;
    u_short	dindex;
    u_char	vspec8, vspec9;
    u_char	nhdr;
    u_char	vendor, info;
    char	str[244];
} cistpl_vers_2_t;

typedef struct cistpl_org_t {
    u_char	data_org;
    char	desc[30];
} cistpl_org_t;

typedef struct cistpl_format_t {
    u_char	type;
    u_char	edc;
    u_int	offset;
    u_int	length;
} cistpl_format_t;

typedef union cisparse_t {
    cistpl_device_t		device;
    cistpl_checksum_t		checksum;
    cistpl_longlink_t		longlink;
    cistpl_longlink_mfc_t	longlink_mfc;
    cistpl_vers_1_t		version_1;
    cistpl_altstr_t		altstr;
    cistpl_jedec_t		jedec;
    cistpl_manfid_t		manfid;
    cistpl_funcid_t		funcid;
    cistpl_funce_t		funce;
    cistpl_bar_t		bar;
    cistpl_config_t		config;
    cistpl_cftable_entry_t	cftable_entry;
    cistpl_cftable_entry_cb_t	cftable_entry_cb;
    cistpl_device_geo_t		device_geo;
    cistpl_vers_2_t		vers_2;
    cistpl_org_t		org;
    cistpl_format_t		format;
} cisparse_t;

typedef struct tuple_t {
    u_int	Attributes;
    cisdata_t 	DesiredTuple;
    u_int	Flags;		/* internal use */
    u_int	LinkOffset;	/* internal use */
    u_int	CISOffset;	/* internal use */
    cisdata_t	TupleCode;
    cisdata_t	TupleLink;
    cisdata_t	TupleOffset;
    cisdata_t	TupleDataMax;
    cisdata_t	TupleDataLen;
    cisdata_t	*TupleData;
} tuple_t;

#define TUPLE_RETURN_COMMON	0x02

/* For ValidateCIS */
typedef struct cisinfo_t {
    u_int	Chains;
} cisinfo_t;

#define CISTPL_MAX_CIS_SIZE	0x200

/* For ReplaceCIS */
typedef struct cisdump_t {
    u_int	Length;
    cisdata_t	Data[CISTPL_MAX_CIS_SIZE];
} cisdump_t;

/* bulkmem.h */

typedef struct region_info_t {
    u_int		Attributes;
    u_int		CardOffset;
    u_int		RegionSize;
    u_int		AccessSpeed;
    u_int		BlockSize;
    u_int		PartMultiple;
    u_char		JedecMfr, JedecInfo;
    memory_handle_t	next;
} region_info_t;


/* ds.h */

typedef struct tuple_parse_t {
    tuple_t		tuple;
    cisdata_t		data[255];
    cisparse_t		parse;
} tuple_parse_t;

typedef struct win_info_t {
    window_handle_t	handle;
    win_req_t		window;
    memreq_t		map;
} win_info_t;
    
typedef struct bind_info_t {
    dev_info_t		dev_info;
    u_char		function;
    struct dev_link_t	*instance;
    char		name[DEV_NAME_LEN];
    u_short		major, minor;
    void		*next;
} bind_info_t;

typedef struct mtd_info_t {
    dev_info_t		dev_info;
    u_int		Attributes;
    u_int		CardOffset;
} mtd_info_t;

typedef union ds_ioctl_arg_t {
    servinfo_t		servinfo;
    adjust_t		adjust;
    config_info_t	config;
    tuple_t		tuple;
    tuple_parse_t	tuple_parse;
    client_req_t	client_req;
    cs_status_t		status;
    conf_reg_t		conf_reg;
    cisinfo_t		cisinfo;
    region_info_t	region;
    bind_info_t		bind_info;
    mtd_info_t		mtd_info;
    win_info_t		win_info;
    cisdump_t		cisdump;
} ds_ioctl_arg_t;

#define DS_GET_CONFIGURATION_INFO	_IOWR('d', 3, config_info_t)
#define DS_GET_FIRST_TUPLE		_IOWR('d', 4, tuple_t)
#define DS_GET_TUPLE_DATA		_IOWR('d', 6, tuple_parse_t)
#define DS_PARSE_TUPLE			_IOWR('d', 7, tuple_parse_t)


#endif

--- NEW FILE: pcmcia_utils.c ---
/***************************************************************************
 * CVSID: $Id: pcmcia_utils.c,v 1.1 2005/01/22 20:13:42 david Exp $
 *
 * PCMCIA Card utilities
 *
 * Copyright (C) 2003 Dan Williams <dcbw at redhat.com>
 *
 * Licensed under the Academic Free License version 2.0
 *
 * Some of this code was derived from pcmcia-cs code, originally
 * developed by David A. Hinds <dahinds at users.sourceforge.net>.
 * Portions created by David A. Hinds are Copyright (C) 1999 David A. Hinds.
 * All Rights Reserved.  It has been modified for integration into HAL
 * by Dan Williams and is covered by the GPL version 2 license.
 *
 * 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 Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 *
 **************************************************************************/

#ifdef HAVE_CONFIG_H
#  include <config.h>
#endif

#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <stdlib.h>

#include "pcmcia_utils.h"

static char *pcmcia_card_types[] = {
	"multifunction", "memory", "serial", "parallel",
	"fixed disk", "video", "network", "AIMS", "SCSI"
};

static int pcmcia_major = -1;

static int pcmcia_lookup_dev(void)
{
	FILE *f;
	int n;
	char s[32], t[32];
    
	f = fopen("/proc/devices", "r");
	if (f == NULL)
		return -errno;
	while (fgets(s, 32, f) != NULL) {
		if (sscanf(s, "%d %s", &n, t) == 2)
			if (strcmp("pcmcia", t) == 0)
				break;
	}
	fclose(f);
	if (strcmp ("pcmcia", t) == 0)
		return n;
	else
		return -ENODEV;
}

int pcmcia_socket_open (int socket)
{
	static char *paths[] = {
		"/dev", "/var/run", "/tmp", NULL
	};
	int fd;
	char **p, fn[64];
	dev_t dev;

	if ((socket < 0) || (socket > PCMCIA_MAX_SOCKETS))
		return -1;

	if (pcmcia_major < 0)
	{
		pcmcia_major = pcmcia_lookup_dev();
		if (pcmcia_major < 0) {
			if (pcmcia_major == -ENODEV)
				fprintf (stderr, "no pcmcia driver in /proc/devices\n");
			else
				fprintf (stderr, "could not open /proc/devices");
		}
	}
	dev = (pcmcia_major<<8) + socket;

	for (p = paths; *p; p++) {
		sprintf(fn, "%s/hal-%d", *p, getpid());
		if (mknod(fn, (S_IFCHR | S_IREAD | S_IWRITE), dev) == 0) {
			fd = open(fn, O_RDONLY);
			unlink(fn);
			if (fd >= 0)
				return fd;
			if (errno == ENODEV)
				break;
		}
	}
	return -1;
}


int pcmcia_get_tuple(int fd, cisdata_t code, ds_ioctl_arg_t *arg)
{
	arg->tuple.DesiredTuple = code;
	arg->tuple.Attributes = TUPLE_RETURN_COMMON;
	arg->tuple.TupleOffset = 0;
	if (    (ioctl(fd, DS_GET_FIRST_TUPLE, arg) == 0)
		&& (ioctl(fd, DS_GET_TUPLE_DATA, arg) == 0)
		&& (ioctl(fd, DS_PARSE_TUPLE, arg) == 0))
		return 0;
	else
		return -1;
}


pcmcia_card_info *pcmcia_card_info_get (int socket)
{
	int fd;
	pcmcia_card_info *info = NULL;

	if ((socket < 0) || (socket > PCMCIA_MAX_SOCKETS))
		return NULL;

	fd = pcmcia_socket_open (socket);
	if (fd >= 0) {
		ds_ioctl_arg_t   arg;
		cistpl_vers_1_t *vers = &arg.tuple_parse.parse.version_1;
		cistpl_manfid_t *manfid = &arg.tuple_parse.parse.manfid;
		cistpl_funcid_t *funcid = &arg.tuple_parse.parse.funcid;
		config_info_t    config;

		/* Ignore CardBus cards and empty slots */
		if (ioctl(fd, DS_GET_CONFIGURATION_INFO, &config) == 0)
			goto out;
		if (config.IntType == INT_CARDBUS)
			goto out;

		if (pcmcia_get_tuple(fd, CISTPL_VERS_1, &arg) != 0)
			goto out;

		if (!(info = calloc (1, sizeof (pcmcia_card_info))))
			goto out;

		info->socket = socket;

		if (vers->ns >= 1)
			info->productid_1 = strdup (vers->str+vers->ofs[0]);
		if (vers->ns >= 2)
			info->productid_2 = strdup (vers->str+vers->ofs[1]);
		if (vers->ns >= 3)
			info->productid_3 = strdup (vers->str+vers->ofs[2]);
		if (vers->ns >= 4)
			info->productid_4 = strdup (vers->str+vers->ofs[3]);

		if (pcmcia_get_tuple(fd, CISTPL_FUNCID, &arg) == 0)
			info->type = funcid->func;

		if (pcmcia_get_tuple(fd, CISTPL_MANFID, &arg) == 0) {
			info->manfid_1 = manfid->manf;
			info->manfid_2 = manfid->card;
		}
		close (fd);
	}

out:
	return (info);
}


void pcmcia_card_info_free (pcmcia_card_info *info)
{
	if (!info) return;

	info->socket = -1;
	info->type = PCMCIA_TYPE_INVALID;
	free (info->productid_1);
	free (info->productid_2);
	free (info->productid_3);
	free (info->productid_4);
	info->manfid_1 = -1;
	info->manfid_2 = -1;
}

const char *pcmcia_card_type_string_from_type (const PCMCIA_card_type type)
{
	/* basically, ensure we don't go out of the array's bounds */
	if ((type < PCMCIA_TYPE_MULTIFUNCTION) || (type >= PCMCIA_TYPE_INVALID)) return NULL;

	return pcmcia_card_types[type];
}

PCMCIA_card_type pcmcia_card_type_from_type_string (const char *string)
{
	PCMCIA_card_type i;

	if (!string) return PCMCIA_TYPE_INVALID;

	for (i = PCMCIA_TYPE_MULTIFUNCTION; i < PCMCIA_TYPE_INVALID; i++) {
		if (!strcmp (string, pcmcia_card_types[i]))
			return i;
	}
	return PCMCIA_TYPE_INVALID;
}


static inline int whack_newline (char *buf)
{
	int len;

	if (!buf)
		return 0;

	len = strlen (buf);
	if ((buf[len-1] == '\n') || (buf[len-1] == '\r')) {
		buf[len-1] = '\0';
		len--;
	}

	return len;
}


pcmcia_stab_entry *pcmcia_stab_entry_get (int socket)
{
	FILE *f;
	pcmcia_stab_entry *entry = NULL;

	if ((socket < 0) || (socket > PCMCIA_MAX_SOCKETS))
		return NULL;

	if ((f = fopen (PCMCIA_STAB_FILE, "r"))) {
		char	buf[200];

		while (fgets (buf, 200, f) && !feof (f)) {
			char match[50];

			buf[199] = '\0';
			whack_newline (buf);

			snprintf (match, 49, "Socket %d", socket);
			if (!strncmp (buf, match, strlen (match))) {
				/* Ok, found our socket */
				if (fgets (buf, 200, f) && !feof (f)) {
					buf[199] = '\0';
					whack_newline (buf);
					if (strncmp (buf, "Socket", 6)) {
						/* Got our card */
						int s;
						char func[50];
						char driver[50];
						int g;
						char dev[50];

						if (sscanf (buf, "%d\t%s\t%s\t%d\t%s", &s, &func, &driver, &g, &dev) == 5) {
							PCMCIA_card_type t = pcmcia_card_type_from_type_string (func);
							if (t != PCMCIA_TYPE_INVALID) {
								entry = calloc (1, sizeof (pcmcia_stab_entry));
								entry->socket = s;
								entry->type = t;
								entry->driver = strdup (driver);
								entry->dev = strdup (dev);
							}
							break;
						}
					}
				}
			}
		}
		fclose (f);
	}

	return (entry);
}


void pcmcia_stab_entry_free (pcmcia_stab_entry *entry)
{
	if (!entry) return;

	entry->socket = -1;
	entry->type = PCMCIA_TYPE_INVALID;
	free (entry->driver);
	free (entry->dev);
}


pcmcia_stab_entry *pcmcia_get_stab_entry_for_device (const char *interface)
{
	pcmcia_stab_entry *entry = NULL;
	int i;

	if (!interface) return 0;

	for (i = 0; i < PCMCIA_MAX_SOCKETS; i++)
	{
		if ((entry = pcmcia_stab_entry_get (i)))
		{
			if (!strcmp (interface, entry->dev))
				break;
			pcmcia_stab_entry_free (entry);
		}
	}

	return (entry);
}


--- NEW FILE: pcmcia_utils.h ---
/***************************************************************************
 * CVSID: $Id: pcmcia_utils.h,v 1.1 2005/01/22 20:13:42 david Exp $
 *
 * PCMCIA Card utilities
 *
 * Copyright (C) 2003 Dan Williams <dcbw at redhat.com>
 *
 * Licensed under the Academic Free License version 2.0
 *
 * 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 Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 *
 **************************************************************************/

#ifndef PCMCIA_UTILS_H
#define PCMCIA_UTILS_H

#ifdef HAVE_CONFIG_H
#  include <config.h>
#endif

#include <fcntl.h>
#include <errno.h>
#include <sys/time.h>
#include <sys/ioctl.h>
#include <sys/stat.h>
#include <sys/types.h>

#include "pcmcia_cs.h"

#define PCMCIA_MAX_SOCKETS 8


typedef enum PCMCIA_card_type {
	PCMCIA_TYPE_MULTIFUNCTION = 0,
	PCMCIA_TYPE_MEMORY,
	PCMCIA_TYPE_SERIAL,
	PCMCIA_TYPE_PARALLEL,
	PCMCIA_TYPE_FIXED_DISK,
	PCMCIA_TYPE_VIDEO,
	PCMCIA_TYPE_NETWORK,
	PCMCIA_TYPE_AIMS,
	PCMCIA_TYPE_SCSI,
	PCMCIA_TYPE_INVALID	/* should always be last */
} PCMCIA_card_type;


typedef struct pcmcia_stab_entry {
	int				socket;
	PCMCIA_card_type	type;
	char				*driver;
	char				*dev;
} pcmcia_stab_entry;

typedef struct pcmcia_card_info {
	int				socket;
	PCMCIA_card_type	type;
	char				*productid_1;
	char				*productid_2;
	char				*productid_3;
	char				*productid_4;
	int				manfid_1;
	int				manfid_2;
} pcmcia_card_info;


int pcmcia_socket_open (int socket);
int pcmcia_get_tuple(int fd, cisdata_t code, ds_ioctl_arg_t *arg);

const char *pcmcia_card_type_string_from_type (const PCMCIA_card_type type);
PCMCIA_card_type pcmcia_card_type_from_type_string (const char *string);

pcmcia_stab_entry *pcmcia_stab_entry_get (int socket);
void pcmcia_stab_entry_free (pcmcia_stab_entry *entry);
pcmcia_stab_entry *pcmcia_get_stab_entry_for_device (const char *interface);

pcmcia_card_info *pcmcia_card_info_get (int socket);
void pcmcia_card_info_free (pcmcia_card_info *info);

#endif

Index: physdev.c
===================================================================
RCS file: /cvs/hal/hal/hald/linux2/physdev.c,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -d -r1.1 -r1.2
--- physdev.c	18 Jan 2005 19:48:13 -0000	1.1
+++ physdev.c	22 Jan 2005 20:13:42 -0000	1.2
@@ -58,12 +58,15 @@
 
 #include "ids.h"
 
-static gboolean
-pci_add (const gchar *sysfs_path, HalDevice *parent, void *end_token)
+#include "pcmcia_utils.h"
+
+/*--------------------------------------------------------------------------------------------------------------*/
+
+static HalDevice *
+pci_add (const gchar *sysfs_path, HalDevice *parent)
 {
 	HalDevice *d;
 	gint device_class;
-	gchar udi[256];
 
 	d = hal_device_new ();
 	hal_device_property_set_string (d, "linux.sysfs_path_device", sysfs_path);
@@ -137,15 +140,14 @@
 		}
 	}
 
-	/* Add to temporary device store */
-	hal_device_store_add (hald_get_tdl (), d);
-
-	/* Merge properties from .fdi files */
-	di_search_and_merge (d);
+	return d;
+}
 
-	/* TODO: Run callouts */
+static gboolean
+pci_compute_udi (HalDevice *d)
+{
+	gchar udi[256];
 
-	/* Compute UDI */
 	hal_util_compute_udi (hald_get_gdl (), udi, sizeof (udi),
 			      "/org/freedesktop/Hal/devices/pci_%x_%x",
 			      hal_device_property_get_int (d, "pci.vendor_id"),
@@ -153,14 +155,11 @@
 	hal_device_set_udi (d, udi);
 	hal_device_property_set_string (d, "info.udi", udi);
 
-	/* Move from temporary to global device store */
-	hal_device_store_remove (hald_get_tdl (), d);
-	hal_device_store_add (hald_get_gdl (), d);
-	
-	hotplug_event_end (end_token);
 	return TRUE;
 }
 
+/*--------------------------------------------------------------------------------------------------------------*/
+
 static void 
 usbif_set_name (HalDevice *d, int ifclass, int ifsubclass, int ifprotocol)
 {
@@ -225,12 +224,11 @@
 	hal_device_property_set_string (d, "info.product", name);
 }
 
-static gboolean
-usb_add (const gchar *sysfs_path, HalDevice *parent, void *end_token)
+static HalDevice *
+usb_add (const gchar *sysfs_path, HalDevice *parent)
 {
 	HalDevice *d;
 	const gchar *bus_id;
-	gchar udi[256];
 
 	d = hal_device_new ();
 	hal_device_property_set_string (d, "linux.sysfs_path_device", sysfs_path);
@@ -317,29 +315,6 @@
 
 		/* TODO:  .level_number .parent_number  */
 
-		/* Add to temporary device store */
-		hal_device_store_add (hald_get_tdl (), d);
-
-		/* Merge properties from .fdi files */
-		di_search_and_merge (d);
-		
-		/* TODO: Run callouts */
-		
-		/* Compute UDI */
-		hal_util_compute_udi (hald_get_gdl (), udi, sizeof (udi),
-				      "/org/freedesktop/Hal/devices/usb_device_%x_%x_%s",
-				      hal_device_property_get_int (d, "usb_device.vendor_id"),
-				      hal_device_property_get_int (d, "usb_device.product_id"),
-				      hal_device_has_property (d, "usb_device.serial") ?
-				        hal_device_property_get_string (d, "usb_device.serial") :
-				        "noserial");
-		hal_device_set_udi (d, udi);
-		hal_device_property_set_string (d, "info.udi", udi);
-		
-		/* Move from temporary to global device store */
-		hal_device_store_remove (hald_get_tdl (), d);
-		hal_device_store_add (hald_get_gdl (), d);
-
 	} else {
 		hal_device_property_set_string (d, "info.bus", "usb");
 
@@ -358,69 +333,355 @@
 				hal_device_property_get_int (d, "usb.interface.class"),
 				hal_device_property_get_int (d, "usb.interface.subclass"),
 				hal_device_property_get_int (d, "usb.interface.protocol"));
+	}
 
-		/* Add to temporary device store */
-		hal_device_store_add (hald_get_tdl (), d);
-		
-		/* Merge properties from .fdi files */
-		di_search_and_merge (d);
-		
-		/* TODO: Run callouts */
-		
-		/* Compute UDI */
+	return d;
+}
+
+static gboolean
+usb_compute_udi (HalDevice *d)
+{
+	gchar udi[256];
+
+	if (hal_device_has_property (d, "usb.interface.number")) {
 		hal_util_compute_udi (hald_get_gdl (), udi, sizeof (udi),
 				      "%s_if%d",
 				      hal_device_property_get_string (d, "info.parent"),
 				      hal_device_property_get_int (d, "usb.interface.number"));
 		hal_device_set_udi (d, udi);
 		hal_device_property_set_string (d, "info.udi", udi);
-		
-		/* Move from temporary to global device store */
-		hal_device_store_remove (hald_get_tdl (), d);
-		hal_device_store_add (hald_get_gdl (), d);
+	} else {
+		hal_util_compute_udi (hald_get_gdl (), udi, sizeof (udi),
+				      "/org/freedesktop/Hal/devices/usb_device_%x_%x_%s",
+				      hal_device_property_get_int (d, "usb_device.vendor_id"),
+				      hal_device_property_get_int (d, "usb_device.product_id"),
+				      hal_device_has_property (d, "usb_device.serial") ?
+				        hal_device_property_get_string (d, "usb_device.serial") :
+				        "noserial");
+		hal_device_set_udi (d, udi);
+		hal_device_property_set_string (d, "info.udi", udi);
 	}
 
-	hotplug_event_end (end_token);
 	return TRUE;
 }
 
+/*--------------------------------------------------------------------------------------------------------------*/
+
+static HalDevice *
+ide_add (const gchar *sysfs_path, HalDevice *parent)
+{
+	HalDevice *d;
+	const gchar *bus_id;
+	guint host, channel;
+
+	d = hal_device_new ();
+	hal_device_property_set_string (d, "linux.sysfs_path_device", sysfs_path);
+	hal_device_property_set_string (d, "info.bus", "ide");
+	if (parent != NULL) {
+		hal_device_property_set_string (d, "info.parent", parent->udi);
+	} else {
+		hal_device_property_set_string (d, "info.parent", "/org/freedesktop/Hal/devices/computer");
+	}
+
+	bus_id = hal_util_get_last_element (sysfs_path);
+
+	sscanf (bus_id, "%d.%d", &host, &channel);
+	hal_device_property_set_int (d, "ide.host", host);
+	hal_device_property_set_int (d, "ide.channel", channel);
+
+	if (channel == 0) {
+		hal_device_property_set_string (d, "info.product", "IDE device (master)");
+	} else {
+		hal_device_property_set_string (d, "info.product", "IDE device (slave)");
+	}
+	
+	return d;
+}
+
+static gboolean
+ide_compute_udi (HalDevice *d)
+{
+	gchar udi[256];
+
+	hal_util_compute_udi (hald_get_gdl (), udi, sizeof (udi),
+			      "%s_ide_%d_%d",
+			      hal_device_property_get_string (d, "info.parent"),
+			      hal_device_property_get_int (d, "ide.host"),
+			      hal_device_property_get_int (d, "ide.channel"));
+	hal_device_set_udi (d, udi);
+	hal_device_property_set_string (d, "info.udi", udi);
+
+	return TRUE;
+
+}
+
+/*--------------------------------------------------------------------------------------------------------------*/
+
+static HalDevice *
+pnp_add (const gchar *sysfs_path, HalDevice *parent)
+{
+	HalDevice *d;
+
+	d = hal_device_new ();
+	hal_device_property_set_string (d, "linux.sysfs_path_device", sysfs_path);
+	hal_device_property_set_string (d, "info.bus", "pnp");
+	if (parent != NULL) {
+		hal_device_property_set_string (d, "info.parent", parent->udi);
+	} else {
+		hal_device_property_set_string (d, "info.parent", "/org/freedesktop/Hal/devices/computer");
+	}
+
+	hal_util_set_string_from_file (d, "pnp.id", sysfs_path, "id");
+	if (hal_device_has_property (d, "pnp.id")) {
+		gchar *pnp_description;
+		ids_find_pnp (hal_device_property_get_string (d, "pnp.id"), &pnp_description);
+		if (pnp_description != NULL) {
+			hal_device_property_set_string (d, "pnp.description", pnp_description);
+			hal_device_property_set_string (d, "info.product", pnp_description);
+		}
+	}
+
+	if (!hal_device_has_property (d, "info.product")) {
+		gchar buf[64];
+		g_snprintf (buf, sizeof (buf), "PnP Device (%s)", hal_device_property_get_string (d, "pnp.id"));
+		hal_device_property_set_string (d, "info.product", buf);
+	}
+
+	
+	return d;
+}
+
 static gboolean
-physdev_remove (HalDevice *d, void *end_token)
+pnp_compute_udi (HalDevice *d)
+{
+	gchar udi[256];
+
+	hal_util_compute_udi (hald_get_gdl (), udi, sizeof (udi),
+			      "/org/freedesktop/Hal/devices/pnp_%s",
+			      hal_device_property_get_string (d, "pnp.id"));
+	hal_device_set_udi (d, udi);
+	hal_device_property_set_string (d, "info.udi", udi);
+
+	return TRUE;
+
+}
+
+/*--------------------------------------------------------------------------------------------------------------*/
+
+static HalDevice *
+serio_add (const gchar *sysfs_path, HalDevice *parent)
+{
+	HalDevice *d;
+	const gchar *bus_id;
+
+	d = hal_device_new ();
+	hal_device_property_set_string (d, "linux.sysfs_path_device", sysfs_path);
+	hal_device_property_set_string (d, "info.bus", "serio");
+	if (parent != NULL) {
+		hal_device_property_set_string (d, "info.parent", parent->udi);
+	} else {
+		hal_device_property_set_string (d, "info.parent", "/org/freedesktop/Hal/devices/computer");
+	}
+
+	bus_id = hal_util_get_last_element (sysfs_path);
+	hal_device_property_set_string (d, "serio.id", bus_id);
+	if (!hal_util_set_string_from_file (d, "serio.description", sysfs_path, "description")) {
+		hal_device_property_set_string (d, "serio.description", hal_device_property_get_string (d, "serio.id"));
+	}
+	hal_device_property_set_string (d, "info.product", hal_device_property_get_string (d, "serio.description"));
+	
+	return d;
+}
+
+static gboolean
+serio_compute_udi (HalDevice *d)
+{
+	gchar udi[256];
+
+	hal_util_compute_udi (hald_get_gdl (), udi, sizeof (udi),
+			      "%s_%s",
+			      hal_device_property_get_string (d, "info.parent"),
+			      hal_device_property_get_string (d, "serio.description"));
+	hal_device_set_udi (d, udi);
+	hal_device_property_set_string (d, "info.udi", udi);
+	return TRUE;
+
+}
+
+/*--------------------------------------------------------------------------------------------------------------*/
+
+static HalDevice *
+pcmcia_add (const gchar *sysfs_path, HalDevice *parent)
+{
+	HalDevice *d;
+	const gchar *bus_id;
+	guint socket, function;
+
+	d = hal_device_new ();
+	hal_device_property_set_string (d, "linux.sysfs_path_device", sysfs_path);
+	hal_device_property_set_string (d, "info.bus", "pcmcia");
+	if (parent != NULL) {
+		hal_device_property_set_string (d, "info.parent", parent->udi);
+	} else {
+		hal_device_property_set_string (d, "info.parent", "/org/freedesktop/Hal/devices/computer");
+	}
+
+	bus_id = hal_util_get_last_element (sysfs_path);
+
+	/* not sure if %d.%d means socket function - need to revisit */
+	sscanf (bus_id, "%d.%d", &socket, &function);
+	hal_device_property_set_int (d, "pcmcia.socket_number", socket);
+
+	/* TODO: need to read this from sysfs instead of relying on stab */
+	{
+		pcmcia_card_info *info;
+
+		info = pcmcia_card_info_get (socket);
+		if (info != NULL) {
+			const char *type;
+
+			if (info->productid_1 != NULL && strlen (info->productid_1) > 0)
+				hal_device_property_set_string (d, "pcmcia.productid_1", info->productid_1);
+			else
+				hal_device_property_set_string (d, "pcmcia.productid_1", "");
+			if (info->productid_2 != NULL && strlen (info->productid_2) > 0)
+				hal_device_property_set_string (d, "pcmcia.productid_2", info->productid_2);
+			else
+				hal_device_property_set_string (d, "pcmcia.productid_2", "");
+			if (info->productid_3 != NULL && strlen (info->productid_3) > 0)
+				hal_device_property_set_string (d, "pcmcia.productid_3", info->productid_3);
+			else
+				hal_device_property_set_string (d, "pcmcia.productid_3", "");
+			if (info->productid_4 != NULL && strlen (info->productid_4) > 0)
+				hal_device_property_set_string (d, "pcmcia.productid_4", info->productid_4);
+			else
+				hal_device_property_set_string (d, "pcmcia.productid_4", "");
+
+			if ((type = pcmcia_card_type_string_from_type (info->type)))
+				hal_device_property_set_string (d, "pcmcia.function", type);
+			else
+				hal_device_property_set_string (d, "pcmcia.function", "");
+
+			hal_device_property_set_int (d, "pcmcia.manfid1", info->manfid_1);
+			hal_device_property_set_int (d, "pcmcia.manfid2", info->manfid_2);
+
+			/* Provide best-guess of vendor, goes in Vendor property */
+			if (info->productid_1 != NULL) {
+				hal_device_property_set_string (d, "info.vendor", info->productid_1);
+			} else {
+				gchar buf[50];
+				g_snprintf (buf, sizeof(buf), "Unknown (0x%04x)", info->manfid_1);
+				hal_device_property_set_string (d, "info.vendor", buf);
+			}
+
+			/* Provide best-guess of name, goes in Product property */
+			if (info->productid_2 != NULL) {
+				hal_device_property_set_string (d, "info.product", info->productid_2);
+			} else {
+				gchar buf[50];
+				g_snprintf (buf, sizeof(buf), "Unknown (0x%04x)", info->manfid_2);
+				hal_device_property_set_string (d, "info.product", buf);
+			}
+
+			pcmcia_card_info_free (info);
+		}
+	}
+
+
+	return d;
+}
+
+static gboolean
+pcmcia_compute_udi (HalDevice *d)
+{
+	gchar udi[256];
+
+	hal_util_compute_udi (hald_get_gdl (), udi, sizeof (udi),
+			      "/org/freedesktop/Hal/devices/pcmcia_%d_%d",
+			      hal_device_property_get_int (d, "pcmcia.manfid1"),
+			      hal_device_property_get_int (d, "pcmcia.manfid2"));
+	hal_device_set_udi (d, udi);
+	hal_device_property_set_string (d, "info.udi", udi);
+	return TRUE;
+
+}
+
+/*--------------------------------------------------------------------------------------------------------------*/
+
+static gboolean
+physdev_remove (HalDevice *d)
 {
 	if (!hal_device_store_remove (hald_get_gdl (), d)) {
 		HAL_WARNING (("Error removing device"));
 	}
 
-	hotplug_event_end (end_token);
 	return TRUE;
 }
 
+/*--------------------------------------------------------------------------------------------------------------*/
+
 typedef struct
 {
 	const gchar *subsystem;
-	gboolean (*add) (const gchar *sysfs_path, HalDevice *parent, void *end_token);
-	gboolean (*remove) (HalDevice *d, void *end_token);
+	HalDevice *(*add) (const gchar *sysfs_path, HalDevice *parent);
+	gboolean (*compute_udi) (HalDevice *d);
+	gboolean (*remove) (HalDevice *d);
 } PhysDevHandler;
 
 static PhysDevHandler physdev_handler_pci = { 
-	"pci",
-	pci_add,
-	physdev_remove
+	.subsystem   = "pci",
+	.add         = pci_add,
+	.compute_udi = pci_compute_udi,
+	.remove      = physdev_remove
 };
 
 static PhysDevHandler physdev_handler_usb = { 
-	"usb",
-	usb_add,
-	physdev_remove
+	.subsystem   = "usb",
+	.add         = usb_add,
+	.compute_udi = usb_compute_udi,
+	.remove      = physdev_remove
+};
+
+static PhysDevHandler physdev_handler_ide = { 
+	.subsystem   = "ide",
+	.add         = ide_add,
+	.compute_udi = ide_compute_udi,
+	.remove      = physdev_remove
+};
+
+static PhysDevHandler physdev_handler_pnp = { 
+	.subsystem   = "pnp",
+	.add         = pnp_add,
+	.compute_udi = pnp_compute_udi,
+	.remove      = physdev_remove
+};
+
+static PhysDevHandler physdev_handler_serio = { 
+	.subsystem   = "serio",
+	.add         = serio_add,
+	.compute_udi = serio_compute_udi,
+	.remove      = physdev_remove
+};
+
+static PhysDevHandler physdev_handler_pcmcia = { 
+	.subsystem   = "pcmcia",
+	.add         = pcmcia_add,
+	.compute_udi = pcmcia_compute_udi,
+	.remove      = physdev_remove
 };
 	
 
 static PhysDevHandler *phys_handlers[] = {
 	&physdev_handler_pci,
 	&physdev_handler_usb,
+	&physdev_handler_ide,
+	&physdev_handler_pnp,
+	&physdev_handler_serio,
+	&physdev_handler_pcmcia,
 	NULL
 };
 
+/*--------------------------------------------------------------------------------------------------------------*/
 
 void
 hotplug_event_begin_add_physdev (const gchar *subsystem, const gchar *sysfs_path, HalDevice *parent, void *end_token)
@@ -434,13 +695,39 @@
 
 		handler = phys_handlers[i];
 		if (strcmp (handler->subsystem, subsystem) == 0) {
-			if (handler->add (sysfs_path, parent, end_token)) {
-				/* let the handler end the event */
+			HalDevice *d;
+
+			d = handler->add (sysfs_path, parent);
+			if (d == NULL) {
+				/* didn't find anything - thus, ignore this hotplug event */
+				hotplug_event_end (end_token);
 				goto out;
 			}
+
+			/* Add to temporary device store */
+			hal_device_store_add (hald_get_tdl (), d);
+
+			/* Merge properties from .fdi files */
+			di_search_and_merge (d);
+
+			/* TODO: Run callouts */
+			
+			/* Compute UDI */
+			if (!handler->compute_udi (d)) {
+				hal_device_store_remove (hald_get_tdl (), d);
+				hotplug_event_end (end_token);
+				goto out;
+			}
+
+			/* Move from temporary to global device store */
+			hal_device_store_remove (hald_get_tdl (), d);
+			hal_device_store_add (hald_get_gdl (), d);
+			
+			hotplug_event_end (end_token);
+			goto out;
 		}
 	}
-
+	
 	/* didn't find anything - thus, ignore this hotplug event */
 	hotplug_event_end (end_token);
 out:
@@ -468,8 +755,8 @@
 
 		handler = phys_handlers[i];
 		if (strcmp (handler->subsystem, subsystem) == 0) {
-			if (handler->remove (d, end_token)) {
-				/* let the handler end the event */
+			if (handler->remove (d)) {
+				hotplug_event_end (end_token);
 				goto out2;
 			}
 		}




More information about the hal-commit mailing list