Revision: 116 http://svn.sourceforge.net/mactel-linux/?rev=116&view=rev Author: nboichat Date: 2007-04-15 20:11:46 -0700 (Sun, 15 Apr 2007)
Log Message: ----------- Fix appleir patch (CodingStyle, etc...) Modified Paths: -------------- trunk/kernel/mactel-patches-2.6.21/0002-appleir.patch Modified: trunk/kernel/mactel-patches-2.6.21/0002-appleir.patch =================================================================== --- trunk/kernel/mactel-patches-2.6.21/0002-appleir.patch 2007-04-12 16:38:57 UTC (rev 115) +++ trunk/kernel/mactel-patches-2.6.21/0002-appleir.patch 2007-04-16 03:11:46 UTC (rev 116) @@ -7,8 +7,8 @@ drivers/usb/input/Kconfig | 4 drivers/usb/input/Makefile | 1 - drivers/usb/input/appleir.c | 390 +++++++++++++++++++++++++++++++++++++++++++ - 3 files changed, 395 insertions(+), 0 deletions(-) + drivers/usb/input/appleir.c | 384 +++++++++++++++++++++++++++++++++++++++++++ + 3 files changed, 389 insertions(+), 0 deletions(-) diff --git a/drivers/usb/input/Kconfig b/drivers/usb/input/Kconfig index 69a9f3b..f88c132 100644 @@ -39,10 +39,29 @@ obj-$(CONFIG_USB_MTOUCH) += mtouchusb.o diff --git a/drivers/usb/input/appleir.c b/drivers/usb/input/appleir.c new file mode 100644 -index 0000000..dc5f604 +index 0000000..5f049c7 --- /dev/null +++ b/drivers/usb/input/appleir.c -@@ -0,0 +1,390 @@ +@@ -0,0 +1,384 @@ ++/* ++ * drivers/usb/input/appleir.c - driver for Apple Intel-based Macs IR Receiver ++ * ++ * Copyright (C) 2006 James McKenzie <[EMAIL PROTECTED]> ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License v2 as published by the ++ * Free Software Foundation. ++ * ++ * 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., ++ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA ++ */ ++ +#include <linux/kernel.h> +#include <linux/slab.h> +#include <linux/input.h> @@ -50,386 +69,361 @@ +#include <linux/init.h> +#include <linux/usb.h> +#include <linux/usb/input.h> ++#include <linux/mutex.h> +#include <asm/unaligned.h> +#include <asm/byteorder.h> + -+/* -+ * Version Information -+ * -+ */ -+ -+#if 0 -+#define DUMP_PACKETS -+#else -+#undef DUMP_PACKETS -+#endif -+ -+#define DRIVER_VERSION "v1.1" ++#define DRIVER_VERSION "v1.2" +#define DRIVER_AUTHOR "James McKenzie" -+#define DRIVER_DESC "USB Apple MacMini IR Receiver driver" ++#define DRIVER_DESC "USB Apple MacIntel IR Receiver driver" +#define DRIVER_LICENSE "GPL" + -+MODULE_AUTHOR (DRIVER_AUTHOR); -+MODULE_DESCRIPTION (DRIVER_DESC); -+MODULE_LICENSE (DRIVER_LICENSE); ++MODULE_AUTHOR(DRIVER_AUTHOR); ++MODULE_DESCRIPTION(DRIVER_DESC); ++MODULE_LICENSE(DRIVER_LICENSE); + -+#ifndef USB_VENDOR_ID_APPLE +#define USB_VENDOR_ID_APPLE 0x05ac -+#endif -+#ifndef USB_DEVICE_ID_APPLE_IR +#define USB_DEVICE_ID_APPLE_IR 0x8240 -+#endif + +#define URB_SIZE 32 + +#define MAX_KEYS 8 -+#define MAX_KEYS_MASK (MAX_KEYS - 1 ) ++#define MAX_KEYS_MASK (MAX_KEYS - 1) + -+struct appleir -+{ -+ struct input_dev *dev; -+ uint8_t *data; -+ dma_addr_t dma_buf; -+ struct usb_device *usbdev; -+ struct urb *urb; -+ int timer_initted; -+ struct timer_list key_up_timer; -+ int current_key; -+ char phys[32]; ++static int debug = 0; ++ ++struct appleir { ++ struct input_dev *dev; ++ uint8_t *data; ++ dma_addr_t dma_buf; ++ struct usb_device *usbdev; ++ struct urb *urb; ++ struct timer_list key_up_timer; ++ int current_key; ++ struct mutex current_key_lock; ++ char phys[32]; +}; + + +static struct usb_device_id appleir_ids[] = { -+ {USB_DEVICE (USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_IR),.driver_info = 0}, -+ {} ++ { ++ USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_IR), ++ .driver_info = 0 ++ }, ++ {} +}; + -+MODULE_DEVICE_TABLE (usb, appleir_ids); ++MODULE_DEVICE_TABLE(usb, appleir_ids); + ++/* ++ * Devices report the following, where XX depends on the remote and/or the ++ * receiver (at least 83, ca, ee have been reported as possible values). ++ * The fifth byte's LSB also depends on the hardware. ++ * 25 87 ee XX 0a/0b + ++ * 25 87 ee XX 0c/0d - ++ * 25 87 ee XX 09/08 << ++ * 25 87 ee XX 06/07 >> ++ * 25 87 ee XX 05/04 >" ++ * 25 87 ee 83 03/02 menu ++ * 26 00 00 00 00 for key repeat ++ * ++ * Thomas Glanzmann also observes the following event sometimes sent after a key ++ * is released, which I interpret as a flat battery message: ++ * 25 87 e0 ca 06 flat battery ++ */ + -+/* I have two devices both of which report the following */ -+/* 25 87 ee 83 0a + */ -+/* 25 87 ee 83 0c - */ -+/* 25 87 ee 83 09 << */ -+/* 25 87 ee 83 06 >> */ -+/* 25 87 ee 83 05 >" */ -+/* 25 87 ee 83 03 menu */ -+/* 26 00 00 00 00 for key repeat*/ -+ -+/* Thomas Glanzmann reports the following responses */ -+/* 25 87 ee ca 0b + */ -+/* 25 87 ee ca 0d - */ -+/* 25 87 ee ca 08 << */ -+/* 25 87 ee ca 07 >> */ -+/* 25 87 ee ca 04 >" */ -+/* 25 87 ee ca 02 menu */ -+/* 26 00 00 00 00 for key repeat*/ -+/* He also observes the following event sometimes */ -+/* sent after a key is release, which I interpret */ -+/* as a flat battery message */ -+/* 25 87 e0 ca 06 flat battery */ -+ -+ +static int keymap[MAX_KEYS] = { -+ KEY_RESERVED, KEY_MENU, -+ KEY_PLAYPAUSE, KEY_NEXTSONG, -+ KEY_PREVIOUSSONG, KEY_VOLUMEUP, -+ KEY_VOLUMEDOWN, KEY_RESERVED ++ KEY_RESERVED, KEY_MENU, ++ KEY_PLAYPAUSE, KEY_NEXTSONG, ++ KEY_PREVIOUSSONG, KEY_VOLUMEUP, ++ KEY_VOLUMEDOWN, KEY_RESERVED +}; + -+static void -+dump_packet (struct appleir *appleir, char *msg, uint8_t * data, int len) ++static void dump_packet(struct appleir *appleir, char *msg, ++ uint8_t * data, int len) +{ -+ int i; ++ int i; + -+ printk (KERN_ERR "appleir: %s (%d bytes)", msg, len); ++ printk(KERN_ERR "appleir: %s (%d bytes)", msg, len); + -+ for (i = 0; i < len; ++i) -+ { -+ printk (" %02x", data[i]); -+ } ++ for (i = 0; i < len; ++i) { ++ printk(" %02x", data[i]); ++ } + -+ printk ("\n"); ++ printk("\n"); +} + + -+static void -+key_up (struct appleir *appleir, int key) ++static void key_up(struct appleir *appleir, int key) +{ -+ //printk (KERN_ERR "key %d up\n", key); -+ input_report_key (appleir->dev, key, 0); -+ input_sync (appleir->dev); ++ if (debug) ++ printk (KERN_DEBUG "key %d up\n", key); ++ ++ input_report_key(appleir->dev, key, 0); ++ input_sync(appleir->dev); +} + -+static void -+key_down (struct appleir *appleir, int key) ++static void key_down(struct appleir *appleir, int key) +{ -+ //printk (KERN_ERR "key %d down\n", key); -+ input_report_key (appleir->dev, key, 1); -+ input_sync (appleir->dev); ++ if (debug) ++ printk (KERN_DEBUG "key %d down\n", key); ++ ++ input_report_key(appleir->dev, key, 1); ++ input_sync(appleir->dev); +} + -+static void -+battery_flat (struct appleir *appleir) ++static void battery_flat(struct appleir *appleir) +{ -+ printk (KERN_ERR "appleir: possible flat battery?\n"); ++ printk(KERN_WARNING "appleir: possible flat battery?\n"); +} + -+static void -+key_up_tick (unsigned long data) ++static void key_up_tick(unsigned long data) +{ -+ struct appleir *appleir = (struct appleir *) data; ++ struct appleir *apple_ir = (struct appleir*)data; + -+ if (appleir->current_key) -+ { -+ key_up (appleir, appleir->current_key); -+ appleir->current_key = 0; -+ } ++ mutex_lock(&apple_ir->current_key_lock); ++ if (apple_ir->current_key) { ++ key_up(apple_ir, apple_ir->current_key); ++ apple_ir->current_key = 0; ++ } ++ mutex_unlock(&apple_ir->current_key_lock); +} + -+static void -+new_data (struct appleir *appleir, uint8_t * data, int len) ++static void parse_data(struct appleir *apple_ir, uint8_t *data, int len) +{ -+ static const uint8_t keydown[] = { 0x25, 0x87, 0xee }; -+ static const uint8_t keyrepeat[] = { 0x26, 0x00, 0x00, 0x00, 0x00 }; -+ static const uint8_t flatbattery[] = { 0x25, 0x87, 0xe0 }; ++ static const uint8_t keydown[] = { 0x25, 0x87, 0xee }; ++ static const uint8_t keyrepeat[] = { 0x26, 0x00, 0x00, 0x00, 0x00 }; ++ static const uint8_t flatbattery[] = { 0x25, 0x87, 0xe0 }; + -+#ifdef DUMP_PACKETS -+ dump_packet (appleir, "received", data, len); -+#endif ++ if (debug) ++ dump_packet(apple_ir, "received", data, len); + -+ if (len != 5) -+ return; ++ if (len != 5) ++ return; + -+ if (!memcmp (data, keydown, sizeof (keydown))) -+ { -+ /*If we already have a key down, take it up before marking */ -+ /*this one down */ -+ if (appleir->current_key) -+ key_up (appleir, appleir->current_key); -+ appleir->current_key = keymap[(data[4] >> 1) & MAX_KEYS_MASK]; ++ if (!memcmp(data, keydown, sizeof(keydown))) { ++ /* ++ * If we already have a key down, take it up before marking ++ * this one down. ++ */ ++ mutex_lock(&apple_ir->current_key_lock); + -+ key_down (appleir, appleir->current_key); -+ /*remote doesn't do key up, either pull them up, in the test */ -+ /*above, or here set a timer which pulls them up after 1/8 s */ -+ mod_timer (&appleir->key_up_timer, jiffies + HZ / 8); ++ if (apple_ir->current_key) ++ key_up(apple_ir, apple_ir->current_key); ++ apple_ir->current_key = keymap[(data[4] >> 1) & MAX_KEYS_MASK]; + -+ return; -+ } ++ key_down(apple_ir, apple_ir->current_key); + -+ if (!memcmp (data, keyrepeat, sizeof (keyrepeat))) -+ { -+ key_down (appleir, appleir->current_key); -+ /*remote doesn't do key up, either pull them up, in the test */ -+ /*above, or here set a timer which pulls them up after 1/8 s */ -+ mod_timer (&appleir->key_up_timer, jiffies + HZ / 8); -+ return; -+ } ++ mutex_unlock(&apple_ir->current_key_lock); + -+ if (!memcmp (data, flatbattery, sizeof (flatbattery))) -+ { -+ battery_flat (appleir); -+ /*Fall through */ -+ } ++ /* ++ * Remote doesn't do key up, either pull them up, in the test ++ * above, or here set a timer which pulls them up after 1/8 s ++ */ ++ mod_timer(&apple_ir->key_up_timer, jiffies + HZ / 8); + -+ dump_packet (appleir, "unknown packet", data, len); ++ return; ++ } ++ ++ if (!memcmp(data, keyrepeat, sizeof(keyrepeat))) { ++ mutex_lock(&apple_ir->current_key_lock); ++ key_down(apple_ir, apple_ir->current_key); ++ mutex_unlock(&apple_ir->current_key_lock); ++ ++ /* ++ * Remote doesn't do key up, either pull them up, in the test ++ * above, or here set a timer which pulls them up after 1/8 s ++ */ ++ mod_timer(&apple_ir->key_up_timer, jiffies + HZ / 8); ++ return; ++ } ++ ++ if (!memcmp(data, flatbattery, sizeof(flatbattery))) { ++ battery_flat(apple_ir); ++ /* Fall through */ ++ } ++ ++ dump_packet(apple_ir, "unknown packet", data, len); +} + -+static void -+appleir_urb (struct urb *urb, struct pt_regs *regs) ++static void appleir_urb(struct urb *urb) +{ -+ struct appleir *appleir = urb->context; -+ int retval; ++ struct appleir *appleir = urb->context; ++ int retval; + -+ switch (urb->status) -+ { -+ case 0: -+ new_data (appleir, urb->transfer_buffer, urb->actual_length); -+ break; -+ case -ECONNRESET: -+ case -ENOENT: -+ case -ESHUTDOWN: -+ /* this urb is terminated, clean up */ -+ dbg ("%s - urb shutting down with status: %d", __FUNCTION__, -+ urb->status); -+ return; -+ default: -+ dbg ("%s - nonzero urb status received: %d", __FUNCTION__, urb->status); -+ } ++ switch (urb->status) { ++ case 0: ++ parse_data(appleir, urb->transfer_buffer, urb->actual_length); ++ break; ++ case -ECONNRESET: ++ case -ENOENT: ++ case -ESHUTDOWN: ++ /* this urb is terminated, clean up */ ++ dbg("%s - urb shutting down with status: %d", ++ __FUNCTION__, urb->status); ++ return; ++ default: ++ dbg("%s - nonzero urb status received: %d", ++ __FUNCTION__, urb->status); ++ } + -+ retval = usb_submit_urb (urb, GFP_ATOMIC); -+ if (retval) -+ err ("%s - usb_submit_urb failed with result %d", __FUNCTION__, retval); ++ retval = usb_submit_urb(urb, GFP_ATOMIC); ++ if (retval) ++ err("%s - usb_submit_urb failed with result %d", ++ __FUNCTION__, retval); +} + + -+static int -+appleir_open (struct input_dev *dev) ++static int appleir_open(struct input_dev *dev) +{ -+ struct appleir *appleir = dev->private; ++ struct appleir *appleir = dev->private; + -+ //appleir->urb->dev = appleir->usbdev; ++ if (usb_submit_urb(appleir->urb, GFP_KERNEL)) ++ return -EIO; + -+ if (usb_submit_urb (appleir->urb, GFP_KERNEL)) -+ return -EIO; -+ -+ return 0; ++ return 0; +} + -+static void -+appleir_close (struct input_dev *dev) ++static void appleir_close(struct input_dev *dev) +{ -+ struct appleir *appleir = dev->private; -+ usb_kill_urb (appleir->urb); -+ del_timer_sync (&appleir->key_up_timer); ++ struct appleir *appleir = dev->private; ++ usb_kill_urb(appleir->urb); ++ del_timer_sync(&appleir->key_up_timer); +} + -+ -+ -+ -+static int -+appleir_probe (struct usb_interface *intf, const struct usb_device_id *id) ++static int appleir_probe(struct usb_interface *intf, ++ const struct usb_device_id *id) +{ -+ struct usb_device *dev = interface_to_usbdev (intf); -+ struct usb_endpoint_descriptor *endpoint; -+ struct appleir *appleir = NULL; -+ struct input_dev *input_dev; -+ int i; ++ struct usb_device *dev = interface_to_usbdev(intf); ++ struct usb_endpoint_descriptor *endpoint; ++ struct appleir *appleir = NULL; ++ struct input_dev *input_dev; ++ int i; + -+ appleir = kzalloc (sizeof (struct appleir), GFP_KERNEL); -+ if (!appleir) -+ goto fail; ++ appleir = kzalloc(sizeof(struct appleir), GFP_KERNEL); ++ if (!appleir) ++ goto fail; + -+ memset (appleir, 0, sizeof (struct appleir)); ++ memset(appleir, 0, sizeof(struct appleir)); + ++ mutex_init(&appleir->current_key_lock); + -+ appleir->data = -+ usb_buffer_alloc (dev, URB_SIZE, GFP_KERNEL, &appleir->dma_buf); -+ if (!appleir->data) -+ goto fail; ++ appleir->data = ++ usb_buffer_alloc(dev, URB_SIZE, GFP_KERNEL, &appleir->dma_buf); ++ if (!appleir->data) ++ goto fail_appleir; + -+ appleir->urb = usb_alloc_urb (0, GFP_KERNEL); -+ if (!appleir->urb) -+ goto fail; ++ appleir->urb = usb_alloc_urb(0, GFP_KERNEL); ++ if (!appleir->urb) ++ goto fail_buffer; + -+ appleir->usbdev = dev; ++ appleir->usbdev = dev; + -+ input_dev = input_allocate_device (); -+ if (!input_dev) -+ goto fail; ++ input_dev = input_allocate_device(); ++ if (!input_dev) ++ goto fail_urb; + -+ appleir->dev = input_dev; ++ appleir->dev = input_dev; + ++ usb_make_path(dev, appleir->phys, sizeof(appleir->phys)); ++ strlcpy(appleir->phys, "/input0", sizeof(appleir->phys)); + -+ usb_make_path (dev, appleir->phys, sizeof (appleir->phys)); -+ strlcpy (appleir->phys, "/input0", sizeof (appleir->phys)); ++ input_dev->name = "Apple MacIntel infrared remote control driver"; ++ input_dev->phys = appleir->phys; ++ usb_to_input_id(dev, &input_dev->id); ++ input_dev->cdev.dev = &intf->dev; ++ input_dev->private = appleir; + -+ input_dev->name = "Apple Mac mini infrared remote control driver"; -+ input_dev->phys = appleir->phys; -+ usb_to_input_id (dev, &input_dev->id); -+ input_dev->cdev.dev = &intf->dev; -+ input_dev->private = appleir; ++ input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REP); ++ input_dev->ledbit[0] = 0; + -+ input_dev->evbit[0] = BIT (EV_KEY) | BIT (EV_REP); -+ input_dev->ledbit[0] = 0; ++ for (i = 0; i < MAX_KEYS; i++) { ++ set_bit(keymap[i], input_dev->keybit); ++ } + -+ for (i = 0; i < MAX_KEYS; i++) -+ { -+ set_bit (keymap[i], input_dev->keybit); -+ } ++ clear_bit(0, input_dev->keybit); + -+ clear_bit (0, input_dev->keybit); ++ input_dev->open = appleir_open; ++ input_dev->close = appleir_close; + -+ input_dev->open = appleir_open; -+ input_dev->close = appleir_close; ++ endpoint = &intf->cur_altsetting->endpoint[0].desc; + -+ endpoint = &intf->cur_altsetting->endpoint[0].desc; ++ usb_fill_int_urb(appleir->urb, dev, ++ usb_rcvintpipe(dev, endpoint->bEndpointAddress), ++ appleir->data, 8, ++ appleir_urb, appleir, endpoint->bInterval); + -+ usb_fill_int_urb (appleir->urb, dev, -+ usb_rcvintpipe (dev, endpoint->bEndpointAddress), -+ appleir->data, 8, -+ appleir_urb, appleir, endpoint->bInterval); ++ appleir->urb->transfer_dma = appleir->dma_buf; ++ appleir->urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; + -+ appleir->urb->transfer_dma = appleir->dma_buf; -+ appleir->urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; ++ usb_set_intfdata(intf, appleir); + -+ usb_set_intfdata (intf, appleir); ++ init_timer(&appleir->key_up_timer); + -+ init_timer (&appleir->key_up_timer); ++ appleir->key_up_timer.function = key_up_tick; ++ appleir->key_up_timer.data = (unsigned long) appleir; + -+ appleir->key_up_timer.function = key_up_tick; -+ appleir->key_up_timer.data = (unsigned long) appleir; ++ input_register_device(appleir->dev); + -+ appleir->timer_initted++; ++ return 0; + -+ input_register_device (appleir->dev); ++fail_timer: ++ del_timer_sync(&appleir->key_up_timer); + -+ return 0; ++fail_input_device: ++ input_free_device(appleir->dev); + -+fail: ++fail_urb: ++ usb_free_urb(appleir->urb); + -+ if (appleir) -+ { ++fail_buffer: ++ usb_buffer_free(dev, URB_SIZE, appleir->data, appleir->dma_buf); + ++fail_appleir: ++ kfree(appleir); + -+ if (appleir->data) -+ usb_buffer_free (dev, URB_SIZE, appleir->data, appleir->dma_buf); -+ -+ if (appleir->timer_initted) -+ del_timer_sync (&appleir->key_up_timer); -+ -+ if (appleir->dev) -+ input_free_device (appleir->dev); -+ -+ kfree (appleir); -+ } -+ -+ return -ENOMEM; ++fail: ++ return -ENOMEM; +} + -+static void -+appleir_disconnect (struct usb_interface *intf) ++static void appleir_disconnect(struct usb_interface *intf) +{ -+ struct appleir *appleir = usb_get_intfdata (intf); ++ struct appleir *appleir = usb_get_intfdata(intf); + -+ usb_set_intfdata (intf, NULL); -+ if (appleir) -+ { -+ input_unregister_device (appleir->dev); -+ if (appleir->timer_initted) -+ del_timer_sync (&appleir->key_up_timer); -+ usb_kill_urb (appleir->urb); -+ usb_free_urb (appleir->urb); -+ usb_buffer_free (interface_to_usbdev (intf), URB_SIZE, appleir->data, -+ appleir->dma_buf); -+ kfree (appleir); -+ } ++ usb_set_intfdata(intf, NULL); ++ if (appleir) { ++ input_unregister_device(appleir->dev); ++ del_timer_sync(&appleir->key_up_timer); ++ usb_kill_urb(appleir->urb); ++ usb_free_urb(appleir->urb); ++ usb_buffer_free(interface_to_usbdev(intf), URB_SIZE, ++ appleir->data, appleir->dma_buf); ++ kfree(appleir); ++ } +} + +static struct usb_driver appleir_driver = { -+ .name = "appleir", -+ .probe = appleir_probe, -+ .disconnect = appleir_disconnect, -+ .id_table = appleir_ids, ++ .name = "appleir", ++ .probe = appleir_probe, ++ .disconnect = appleir_disconnect, ++ .id_table = appleir_ids, +}; + -+static int __init -+appleir_init (void) ++static int __init appleir_init(void) +{ -+ int retval; -+ retval = usb_register (&appleir_driver); -+ if (retval) -+ goto out; -+ info (DRIVER_VERSION ":" DRIVER_DESC); -+out: -+ return retval; ++ int retval; ++ retval = usb_register(&appleir_driver); ++ if (retval) ++ goto out; ++ info(DRIVER_VERSION ":" DRIVER_DESC); ++ out: ++ return retval; +} + -+static void __exit -+appleir_exit (void) ++static void __exit appleir_exit(void) +{ -+ usb_deregister (&appleir_driver); ++ usb_deregister(&appleir_driver); +} + -+module_init (appleir_init); -+module_exit (appleir_exit); ++module_init(appleir_init); ++module_exit(appleir_exit); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. ------------------------------------------------------------------------- This SF.net email is sponsored by DB2 Express Download DB2 Express C - the FREE version of DB2 express and take control of your XML. No limits. Just data. Click to get it now. http://sourceforge.net/powerbar/db2/ _______________________________________________ Mactel-linux-devel mailing list Mactel-linux-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/mactel-linux-devel