[linux-usb-devel] [PATCH] iuu_phoenix - new release v0.4 - call for review/comments
In this release, the driver use the interrupt context. So no more latency problem. I still kfree the buffers provided by the usb-serial framework. All comments/remarks are welcome This driver seems very stable ( tested with 5 readers at the same time ) Alain code rewritten in interrupt mode Signed-off-by: Alain Degreffe [EMAIL PROTECTED] diff --git a/drivers/usb/serial/Kconfig b/drivers/usb/serial/Kconfig index 3efe670..c21dde2 100644 --- a/drivers/usb/serial/Kconfig +++ b/drivers/usb/serial/Kconfig @@ -272,6 +272,17 @@ config USB_SERIAL_IPW To compile this driver as a module, choose M here: the module will be called ipw. +config USB_SERIAL_IUU + tristate USB Infinity USB Unlimited Phoenix Driver (Experimental) + depends on USB_SERIAL EXPERIMENTAL + help + Say Y here if you want to use a IUU in phoenix mode and get + an extra ttyUSBx device. More information available on + http://eczema.ecze.com/iuu_phoenix.html + + To compile this driver as a module, choose M here: the + module will be called iuu_phoenix.o + config USB_SERIAL_KEYSPAN_PDA tristate USB Keyspan PDA Single Port Serial Driver depends on USB_SERIAL diff --git a/drivers/usb/serial/Makefile b/drivers/usb/serial/Makefile index 61166ad..cd26931 100644 --- a/drivers/usb/serial/Makefile +++ b/drivers/usb/serial/Makefile @@ -29,6 +29,7 @@ obj-$(CONFIG_USB_SERIAL_GARMIN) += garmin_gps.o obj-$(CONFIG_USB_SERIAL_HP4X) += hp4x.o obj-$(CONFIG_USB_SERIAL_IPAQ) += ipaq.o obj-$(CONFIG_USB_SERIAL_IPW) += ipw.o +obj-$(CONFIG_USB_SERIAL_IUU) += iuu_phoenix.o obj-$(CONFIG_USB_SERIAL_IR) += ir-usb.o obj-$(CONFIG_USB_SERIAL_KEYSPAN) += keyspan.o obj-$(CONFIG_USB_SERIAL_KEYSPAN_PDA) += keyspan_pda.o diff --git a/drivers/usb/serial/iuu_phoenix.c b/drivers/usb/serial/iuu_phoenix.c new file mode 100644 index 000..56110c4 --- /dev/null +++ b/drivers/usb/serial/iuu_phoenix.c @@ -0,0 +1,1417 @@ +/* + * Infinity Unlimited USB Phoenix driver + * + * Copyright (C) 2007 Alain Degreffe ([EMAIL PROTECTED]) + * + * + * Original code taken from iuutool ( Copyright (C) 2006 Juan Carlos Borrás ) + * + * 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. + * + * And tested with help of WB Electronics + * + */ + +#include linux/kernel.h +#include linux/errno.h +#include linux/init.h +#include linux/slab.h +#include linux/tty.h +#include linux/tty_driver.h +#include linux/tty_flip.h +#include linux/serial.h +#include linux/module.h +#include linux/moduleparam.h +#include linux/spinlock.h +#include linux/uaccess.h +#include linux/usb.h +#include linux/usb/serial.h +#include iuu_phoenix.h +#include linux/random.h + + +#ifdef CONFIG_USB_SERIAL_DEBUG +int debug = 1; +#else +int debug = 0; +#endif + +/* + * Version Information + */ +#define DRIVER_VERSION v0.4 +#define DRIVER_DESC Infinity USB Unlimited Phoenix driver + +static struct usb_device_id id_table[] = { + {USB_DEVICE(IUU_USB_VENDOR_ID, IUU_USB_PRODUCT_ID)}, + {} /* Terminating entry */ +}; + +MODULE_DEVICE_TABLE(usb, id_table); + +static struct usb_driver iuu_driver = { + .name = iuu_phoenix, + .probe = usb_serial_probe, + .disconnect = usb_serial_disconnect, + .id_table = id_table, + .no_dynamic_id = 1, +}; + +/* base functions */ +static int iuu_startup(struct usb_serial *serial); +static void iuu_shutdown(struct usb_serial *serial); + +static int iuu_open(struct usb_serial_port *port, struct file *filp); +static void iuu_close(struct usb_serial_port *port, struct file *filp); + +static int iuu_uart_flush(struct usb_serial_port *port); + +/* non interrupt context functions */ + +static int read_immediate(struct usb_serial_port *port, u8 * buf, u8 count); +static int iuu_uart_baud(struct usb_serial_port *port, u_int32_t baud, + u_int32_t *actual, u_int8_t parity); +static int bulk_immediate(struct usb_serial_port *port, u8 * buf, u8 count); + +static int iuu_ioctl(struct usb_serial_port *port, struct file *file, + unsigned int cmd, unsigned long arg); +static int iuu_tiocmset(struct usb_serial_port *port, struct file *file, + unsigned int set, unsigned int clear); +static int iuu_tiocmget(struct usb_serial_port *port, struct file *file); + +static int iuu_uart_write(struct usb_serial_port *port, + const u8 * buf, int count); + +static int iuu_uart_on(struct usb_serial_port *port); +static int iuu_uart_off(struct usb_serial_port *port); + +/* polled functions (interrupt context) */ + + +static void iuu_uart_read_callback(struct urb *urb); +static int iuu_read_buf(struct usb_serial_port *port, int len); +static void read_buf_callback(struct urb *urb); + +static int iuu_bulk_write(struct usb_serial_port *port); + +static void iuu_rxcmd(struct urb *urb); +static void read_rxcmd_callback(struct urb *urb); + +static int iuu_status(struct usb_serial_port *port);
Re: [linux-usb-devel] [PATCH] USB Pegasus driver - avoid a potential NULL pointer dereference.
Forget this :-) All my problem came from the usage of a buffer inialized by usb-serial.c that is too small for my module.. So I was writing or reading outside the memory allocation dedicated to the urb structure Alain -Message d'origine- De : Oliver Neukum [mailto:[EMAIL PROTECTED] Envoyé : dimanche 29 juillet 2007 21:42 À : linux-usb-devel@lists.sourceforge.net Cc : [EMAIL PROTECTED] Objet : Re: [linux-usb-devel] [PATCH] USB Pegasus driver - avoid a potential NULL pointer dereference. Am Sonntag 29 Juli 2007 schrieb [EMAIL PROTECTED]: I have the same problem in my development.. Somewhere in my code: unsigned char *data = urb-transfer_buffer ; if ( data == NULL ) dbg(%s - data is NULL !!!,__FUNCTION__ ); if ( urb-actual_length == 1 data != NULL ) len = (int) data[0]; If I don’t do this check in a usb callback function, I have kernel panic deference to null pointer ! But the fun stuff in this story is that I never see the debug data is NULL !!! so This never happen if I do this check urb-transfer_buffer is set by the caller. Usbcore should never change it. What do you set it to? Regards Oliver - This SF.net email is sponsored by: Splunk Inc. Still grepping through log files to find problems? Stop. Now Search log events and configuration files using AJAX and a browser. Download your FREE copy of Splunk now http://get.splunk.com/ ___ linux-usb-devel@lists.sourceforge.net To unsubscribe, use the last form field at: https://lists.sourceforge.net/lists/listinfo/linux-usb-devel
Re: [linux-usb-devel] usb-serial.c question - potential Memory fault
This is quite dangerous :-) You can't apply a user requested buffer_size to interrupt_buffer ! The API should only apply the buffer size to bulk buffers... Alain -Message d'origine- De : Oliver Neukum [mailto:[EMAIL PROTECTED] Envoyé : lundi 30 juillet 2007 12:45 À : linux-usb-devel@lists.sourceforge.net Cc : [EMAIL PROTECTED]; 'Greg KH' Objet : Re: [linux-usb-devel] usb-serial.c question - potential Memory fault Am Montag 30 Juli 2007 schrieb [EMAIL PROTECTED]: Hi Greg, After a new complete reading of my code against usb-serial.c, I finally found ( I hope ) my problem. In usb-serial.c, when bulk_in/out buffers are initialized, each buffer size are the same as the wMaxPacketSize given by the endpoint. So, in my case, my device have a value of 64 bytes and I send and receive bulk data that might have 256 bytes length !!! And like pl2303, I just copy the user data to port-write_urb-transfer_buffer. You have a problem. Does this extension of the API help you? Regards Oliver -- --- a/include/linux/usb/serial.h2007-07-30 12:19:39.0 +0200 +++ b/include/linux/usb/serial.h2007-07-30 12:19:46.0 +0200 @@ -201,6 +201,7 @@ static inline void usb_set_serial_data ( struct usb_serial_driver { const char *description; const struct usb_device_id *id_table; + int buffer_size; charnum_interrupt_in; charnum_interrupt_out; charnum_bulk_in; --- a/drivers/usb/serial/usb-serial.c 2007-07-30 12:20:11.0 +0200 +++ b/drivers/usb/serial/usb-serial.c 2007-07-30 12:20:15.0 +0200 @@ -866,7 +866,7 @@ int usb_serial_probe(struct usb_interfac dev_err(interface-dev, No free urbs available\n); goto probe_error; } - buffer_size = le16_to_cpu(endpoint-wMaxPacketSize); + buffer_size = type-buffer_size ? type-buffer_size : le16_to_cpu(endpoint-wMaxPacketSize); port-bulk_in_size = buffer_size; port-bulk_in_endpointAddress = endpoint-bEndpointAddress; port-bulk_in_buffer = kmalloc (buffer_size, GFP_KERNEL); @@ -890,7 +890,7 @@ int usb_serial_probe(struct usb_interfac dev_err(interface-dev, No free urbs available\n); goto probe_error; } - buffer_size = le16_to_cpu(endpoint-wMaxPacketSize); + buffer_size = type-buffer_size ? type-buffer_size : le16_to_cpu(endpoint-wMaxPacketSize); port-bulk_out_size = buffer_size; port-bulk_out_endpointAddress = endpoint-bEndpointAddress; port-bulk_out_buffer = kmalloc (buffer_size, GFP_KERNEL); @@ -915,7 +915,7 @@ int usb_serial_probe(struct usb_interfac dev_err(interface-dev, No free urbs available\n); goto probe_error; } - buffer_size = le16_to_cpu(endpoint-wMaxPacketSize); + buffer_size = type-buffer_size ? type-buffer_size : le16_to_cpu(endpoint-wMaxPacketSize); port-interrupt_in_endpointAddress = endpoint-bEndpointAddress; port-interrupt_in_buffer = kmalloc (buffer_size, GFP_KERNEL); if (!port-interrupt_in_buffer) { @@ -942,7 +942,7 @@ int usb_serial_probe(struct usb_interfac dev_err(interface-dev, No free urbs available\n); goto probe_error; } - buffer_size = le16_to_cpu(endpoint-wMaxPacketSize); + buffer_size = type-buffer_size ? type-buffer_size : le16_to_cpu(endpoint-wMaxPacketSize); port-interrupt_out_size = buffer_size; port-interrupt_out_endpointAddress = endpoint-bEndpointAddress; port-interrupt_out_buffer = kmalloc (buffer_size, GFP_KERNEL); - This SF.net email is sponsored by: Splunk Inc. Still grepping through log files to find problems? Stop. Now Search log events and configuration files using AJAX and a browser. Download your FREE copy of Splunk now http://get.splunk.com/ ___ linux-usb-devel@lists.sourceforge.net To unsubscribe, use the last form field at: https://lists.sourceforge.net/lists/listinfo/linux-usb-devel
Re: [linux-usb-devel] usb-serial.c question - potential Memory fault
No need to split. This is just what I need :-) Thanks a lot. Alain -Message d'origine- De : Oliver Neukum [mailto:[EMAIL PROTECTED] Envoyé : lundi 30 juillet 2007 14:18 À : [EMAIL PROTECTED] Cc : linux-usb-devel@lists.sourceforge.net Objet : Re: [linux-usb-devel] usb-serial.c question - potential Memory fault Am Montag 30 Juli 2007 schrieb [EMAIL PROTECTED]: This is quite dangerous :-) You can't apply a user requested buffer_size to interrupt_buffer ! The API should only apply the buffer size to bulk buffers... Right you are. What about this? Or do you need split sizes for input and output? Regards Oliver --- --- a/include/linux/usb/serial.h2007-07-30 12:19:39.0 +0200 +++ b/include/linux/usb/serial.h2007-07-30 12:19:46.0 +0200 @@ -201,6 +201,7 @@ static inline void usb_set_serial_data ( struct usb_serial_driver { const char *description; const struct usb_device_id *id_table; + int buffer_size; charnum_interrupt_in; charnum_interrupt_out; charnum_bulk_in; --- a/drivers/usb/serial/usb-serial.c 2007-07-30 12:20:11.0 +0200 +++ b/drivers/usb/serial/usb-serial.c 2007-07-30 12:20:15.0 +0200 @@ -866,7 +866,7 @@ int usb_serial_probe(struct usb_interfac dev_err(interface-dev, No free urbs available\n); goto probe_error; } - buffer_size = le16_to_cpu(endpoint-wMaxPacketSize); + buffer_size = type-buffer_size ? type-buffer_size : le16_to_cpu(endpoint-wMaxPacketSize); port-bulk_in_size = buffer_size; port-bulk_in_endpointAddress = endpoint-bEndpointAddress; port-bulk_in_buffer = kmalloc (buffer_size, GFP_KERNEL); @@ -890,7 +890,7 @@ int usb_serial_probe(struct usb_interfac dev_err(interface-dev, No free urbs available\n); goto probe_error; } - buffer_size = le16_to_cpu(endpoint-wMaxPacketSize); + buffer_size = type-buffer_size ? type-buffer_size : le16_to_cpu(endpoint-wMaxPacketSize); port-bulk_out_size = buffer_size; port-bulk_out_endpointAddress = endpoint-bEndpointAddress; port-bulk_out_buffer = kmalloc (buffer_size, GFP_KERNEL); - This SF.net email is sponsored by: Splunk Inc. Still grepping through log files to find problems? Stop. Now Search log events and configuration files using AJAX and a browser. Download your FREE copy of Splunk now http://get.splunk.com/ ___ linux-usb-devel@lists.sourceforge.net To unsubscribe, use the last form field at: https://lists.sourceforge.net/lists/listinfo/linux-usb-devel
Re: [linux-usb-devel] usb-serial.c question - potential Memory fault
Greg, It is a problem because I use the pre-allocated buffer given by the layer usb-serial. Of course, I can create a new urb structure with a bigger buffer but I just suggest that using the buffer stored in the usb_serial_device seems to be logic and like a said, other driver use it without checking the buffer_size. Are you sure that the pl2303 is well protected against a buffer overflow ? What happens if a pl2303 device give a maxsize of 64 bytes like my device ? The driver will then make a buffer overflow and a kernel panic may occur. This was the module I used to study and write my own driver. So I agree with the proposition of Oliver to add a buffer_size in the usb_serial_driver structure. This is very useful to prepare a buffer able to make bulk transfer. Regards, Alain -Message d'origine- De : Greg KH [mailto:[EMAIL PROTECTED] Envoyé : lundi 30 juillet 2007 17:04 À : [EMAIL PROTECTED] Cc : linux-usb-devel@lists.sourceforge.net Objet : Re: usb-serial.c question - potential Memory fault On Mon, Jul 30, 2007 at 07:10:55AM +0200, [EMAIL PROTECTED] wrote: Hi Greg, After a new complete reading of my code against usb-serial.c, I finally found ( I hope ) my problem. In usb-serial.c, when bulk_in/out buffers are initialized, each ?buffer size are the same as the wMaxPacketSize given by the endpoint. So, in my case, my device have a value of 64 bytes and I send and receive bulk data that might have 256 bytes length !!! And like pl2303, I just copy the user data to port-write_urb-transfer_buffer. For all driver that use usb-serial for the probe function, this can be a problem (like for me). I have checked for example the pl2303 that never check this value before the memcpy. Why is this a problem for you? You can use any size buffer you want if you wish to send more data than what the usb-serial core provides for you. Lots of other drivers do that today. thanks, greg k-h - This SF.net email is sponsored by: Splunk Inc. Still grepping through log files to find problems? Stop. Now Search log events and configuration files using AJAX and a browser. Download your FREE copy of Splunk now http://get.splunk.com/ ___ linux-usb-devel@lists.sourceforge.net To unsubscribe, use the last form field at: https://lists.sourceforge.net/lists/listinfo/linux-usb-devel
Re: [linux-usb-devel] [PATCH] USB Pegasus driver - avoid a potential NULL pointer dereference.
I have the same problem in my development.. Somewhere in my code: unsigned char *data = urb-transfer_buffer ; if ( data == NULL ) dbg(%s - data is NULL !!!,__FUNCTION__ ); if ( urb-actual_length == 1 data != NULL ) len = (int) data[0]; If I dont do this check in a usb callback function, I have kernel panic deference to null pointer ! But the fun stuff in this story is that I never see the debug data is NULL !!! so This never happen if I do this check Any idea ? Alain -Message d'origine- De : [EMAIL PROTECTED] [mailto:[EMAIL PROTECTED] De la part de Satyam Sharma Envoyé : dimanche 29 juillet 2007 20:18 À : Oliver Neukum Cc : linux-usb-devel@lists.sourceforge.net; Petko Manolov; Greg Kroah-Hartman; Jesper Juhl; Linux Kernel Mailing List; [EMAIL PROTECTED] Objet : Re: [linux-usb-devel] [PATCH] USB Pegasus driver - avoid a potential NULL pointer dereference. On Sun, 29 Jul 2007, Oliver Neukum wrote: Am Sonntag 29 Juli 2007 schrieb Jesper Juhl: On 29/07/07, Satyam Sharma [EMAIL PROTECTED] wrote: Hi, On 7/29/07, Jesper Juhl [EMAIL PROTECTED] wrote: Hello, This patch makes sure we don't dereference a NULL pointer in drivers/net/usb/pegasus.c::write_bulk_callback() in the initial struct net_device *net = pegasus-net; assignment. The existing code checks if 'pegasus' is NULL and bails out if it is, so we better not touch that pointer until after that check. [...] Is it really possible that we're called into this function with urb-context == NULL? If not, I'd suggest let's just get rid of the check itself, instead. I'm not sure. I am not very familiar with this code. I just figured that moving the assignment is potentially a little safer and it is certainly no worse than the current code, so that's a safe and potentially benneficial change. Removing the check may be safe but I'm not certain enough to make that call... pegasus == NULL there would be a kernel bug. Silently ignoring it, like the code now wants to do is bad. As the oops has never been reported, I figure turning it into an explicit debugging test is overkill, so removal seems to be the best option. Ok, thanks. Updated patch below. [PATCH] pegasus: Remove bogus checks in urb-complete() callbacks urb-complete() callbacks registered in drivers/net/usb/pegasus.c needlessly check for urb-context != NULL, but that is not possible (the only way that can be possible would be a kernel bug elsewhere, and these checks would simply end up hiding that). So let's remove the bogus checks. Signed-off-by: Satyam Sharma [EMAIL PROTECTED] --- drivers/net/usb/pegasus.c |9 + 1 files changed, 1 insertions(+), 8 deletions(-) diff --git a/drivers/net/usb/pegasus.c b/drivers/net/usb/pegasus.c index a05fd97..439ef9f 100644 --- a/drivers/net/usb/pegasus.c +++ b/drivers/net/usb/pegasus.c @@ -770,9 +770,6 @@ static void write_bulk_callback(struct urb *urb) pegasus_t *pegasus = urb-context; struct net_device *net = pegasus-net; - if (!pegasus) - return; - if (!netif_device_present(net) || !netif_running(net)) return; @@ -805,13 +802,9 @@ static void write_bulk_callback(struct urb *urb) static void intr_callback(struct urb *urb) { pegasus_t *pegasus = urb-context; - struct net_device *net; + struct net_device *net = pegasus-net; int status; - if (!pegasus) - return; - net = pegasus-net; - switch (urb-status) { case 0: break; - This SF.net email is sponsored by: Splunk Inc. Still grepping through log files to find problems? Stop. Now Search log events and configuration files using AJAX and a browser. Download your FREE copy of Splunk now http://get.splunk.com/ ___ linux-usb-devel@lists.sourceforge.net To unsubscribe, use the last form field at: https://lists.sourceforge.net/lists/listinfo/linux-usb-devel - This SF.net email is sponsored by: Splunk Inc. Still grepping through log files to find problems? Stop. Now Search log events and configuration files using AJAX and a browser. Download your FREE copy of Splunk now http://get.splunk.com/ ___ linux-usb-devel@lists.sourceforge.net To unsubscribe, use the last form field at: https://lists.sourceforge.net/lists/listinfo/linux-usb-devel
[linux-usb-devel] nRE: [PATCH] USB Pegasus driver - avoid a potential NULL pointer dereference.
Oliver, The callback came from this function: static void read_rxcmd_callback(struct urb *urb) { struct usb_serial_port *port = (struct usb_serial_port *)urb-context; int result; dbg(%s - enter, __FUNCTION__); dbg(%s - urb-status = %d, __FUNCTION__, urb-status); if (urb-status) { dbg(%s - urb-status = %d, __FUNCTION__, urb-status); /* error stop all */ return; } usb_fill_bulk_urb(port-read_urb, port-serial-dev, usb_rcvbulkpipe(port-serial-dev, port-bulk_in_endpointAddress), port-read_urb-transfer_buffer, 256, iuu_uart_read_callback, port); result = usb_submit_urb(port-read_urb, GFP_ATOMIC); dbg(%s - submit result = %d, __FUNCTION__, result); return; } And dbg(%s - submit result = %d, __FUNCTION__, result) alwys display result = 0... I don't understand how it could happens... Now with this check I have another problem: a oops unable to handle kernel paging request in another module ... I can't explain why... My code is running during 1 to 5 minutes but suddenly I have a kernel panic that doesn't appear to come from my module. I begin to be nuts because I try to understand this for a week without any clue to understand. The panic always show the EIP that have nothing to see with my module. One of the panic was due to a null deference and this is why I have added this check and the difference is that de kernel ca run 3 to 5 minutes ( Before it was only for 10 to 60 seconds )... So I progress but it is a nonsense to search like that. Even with Sysrq + t, I don’t' see anything that can explain the problem. Alain -Message d'origine- De : Oliver Neukum [mailto:[EMAIL PROTECTED] Envoyé : dimanche 29 juillet 2007 21:42 À : linux-usb-devel@lists.sourceforge.net Cc : [EMAIL PROTECTED] Objet : Re: [linux-usb-devel] [PATCH] USB Pegasus driver - avoid a potential NULL pointer dereference. Am Sonntag 29 Juli 2007 schrieb [EMAIL PROTECTED]: I have the same problem in my development.. Somewhere in my code: unsigned char *data = urb-transfer_buffer ; if ( data == NULL ) dbg(%s - data is NULL !!!,__FUNCTION__ ); if ( urb-actual_length == 1 data != NULL ) len = (int) data[0]; If I don’t do this check in a usb callback function, I have kernel panic deference to null pointer ! But the fun stuff in this story is that I never see the debug data is NULL !!! so This never happen if I do this check urb-transfer_buffer is set by the caller. Usbcore should never change it. What do you set it to? Regards Oliver - This SF.net email is sponsored by: Splunk Inc. Still grepping through log files to find problems? Stop. Now Search log events and configuration files using AJAX and a browser. Download your FREE copy of Splunk now http://get.splunk.com/ ___ linux-usb-devel@lists.sourceforge.net To unsubscribe, use the last form field at: https://lists.sourceforge.net/lists/listinfo/linux-usb-devel
[linux-usb-devel] usb-serial.c question - potential Memory fault
Hi Greg, After a new complete reading of my code against usb-serial.c, I finally found ( I hope ) my problem. In usb-serial.c, when bulk_in/out buffers are initialized, each buffer size are the same as the wMaxPacketSize given by the endpoint. So, in my case, my device have a value of 64 bytes and I send and receive bulk data that might have 256 bytes length !!! And like pl2303, I just copy the user data to port-write_urb-transfer_buffer. For all driver that use usb-serial for the probe function, this can be a problem (like for me). I have checked for example the pl2303 that never check this value before the memcpy. Am I right ? This can be problem or not ? Alain - This SF.net email is sponsored by: Splunk Inc. Still grepping through log files to find problems? Stop. Now Search log events and configuration files using AJAX and a browser. Download your FREE copy of Splunk now http://get.splunk.com/ ___ linux-usb-devel@lists.sourceforge.net To unsubscribe, use the last form field at: https://lists.sourceforge.net/lists/listinfo/linux-usb-devel
[linux-usb-devel] Second call : iuu_phoenix driver crash the kernel... help needed
Hi all, I just have rewritten the driver to do a constant polling. This imply that the module work in interrupt context. The driver works for a while but after some time ( 1 to 120 seconds it depends ), the driver produce a Oops. But the oops dont give any error on the driver function but show a page allocation problem in other part of the kernel Here the oops is in usbserial but yesterday before activation kernel debug, it was in the raid_one module ! Here the code , I tried different spin_lock_irq but without any changes. If I comment the bulk_write and just do a read polling, The polling is stable ( but this is normal, because the module will never see any character coming from the device because the device never receive any data ). Here is the code that cause the problem: ( It is just a part of the code. This is enough to see all things related to my problem - All spin_lock are removed for the moment.. I know it is quite dangerous but the module call all callback function in a kind of chain order. The oops follow the code ) Some explanations: The code ( not shown here ) iuu_open do a rxcmd with a completion pointer equal to iuu_uart_read_callback. So the polling begin in this function. In the same time, iuu_uart_write is called in a process context to just fill writebuf. So we have: 1.From tty: character - iuu_uart_write - writebuf 2.Polling: iuu_uart_read_callback - if character in device buffer - read_buf - rxcmd if no character in buf and reset is waiting - iuu_reset - rxcmd if no character in device and no reset is waiting - rxcmd rxcmd point at completion to iuu_uart_read_callback some question: 1.Is it right to allocate the memory like I do in the code ? ( iuu_alloc_buf ) 2.What I really must care in interrupt context ? I try to always avois any function that is able to sleep but if you see one .. say me. 3.Sometimes, I have Fatal exception in interrupt... --Code-- /* non interrupt context functions */ static int read_immediate(struct usb_serial_port *port, u8 *buf, u8 count); static int iuu_uart_baud(struct usb_serial_port *port, u_int32_t baud, u_int32_t *actual, u_int8_t parity); static int bulk_immediate(struct usb_serial_port *port, u8 *buf, u8 count); static int iuu_ioctl(struct usb_serial_port *port, struct file *file, unsigned int cmd, unsigned long arg); static int iuu_tiocmset(struct usb_serial_port *port, struct file *file, unsigned int set, unsigned int clear); static int iuu_tiocmget(struct usb_serial_port *port, struct file *file); static int iuu_uart_write(struct usb_serial_port *port, const u8 *buf, int count); static int iuu_uart_on(struct usb_serial_port *port); static int iuu_uart_off(struct usb_serial_port *port); /* polled functions (interrupt context) */ static void iuu_uart_read_callback (struct urb *urb); static int iuu_read_buf(struct usb_serial_port *port ,u8 len); static void read_buf_callback (struct urb *urb); static int iuu_bulk_write(struct usb_serial_port *port); static void iuu_rxcmd (struct urb *urb); static void read_rxcmd_callback (struct urb *urb); static int iuu_status(struct usb_serial_port *port); static void iuu_status_callback(struct urb *urb); static void iuu_update_status_callback(struct urb *urb); static int iuu_reset(struct usb_serial_port *port, u_int8_t wt); /* structures definitions */ static struct usb_serial_driver iuu_device = { .driver = { .owner = THIS_MODULE, .name = IUU Phoenix, }, .id_table = id_table, .num_interrupt_in = NUM_DONT_CARE, .num_bulk_in = 1, .num_bulk_out = 1, .num_ports = 1, .open = iuu_open, .close = iuu_close, .write = iuu_uart_write, .read_bulk_callback = iuu_uart_read_callback, .ioctl = iuu_ioctl, .tiocmget = iuu_tiocmget, .tiocmset = iuu_tiocmset, .attach = iuu_startup, .shutdown = iuu_shutdown, }; struct iuu_private { spinlock_t lock; /* store irq state */ wait_queue_head_t delta_msr_wait; u8 line_control; u8 line_status; u8 termios_initialized; int TIOSTATUS; /* store IUART SIGNAL for tiocmget call */ u8 reset; /* if 1 reset is needed */ int poll; /* number of poll */ u8 *writebuf; /* buffer for writing to device */ int writelen; /* num of byte to write to device */ u8 *buf; /* used for initialize speed */ u8 *dbgbuf; /* debug buffer */ u8 len; }; static int iuu_alloc_buf (struct usb_serial_port *port) { struct iuu_private *priv = usb_get_serial_port_data(port); priv-buf = kmalloc(256,GFP_KERNEL);
Re: [linux-usb-devel] [PATCH] iuu_phoenix new driver proposal 2 fixed
OOps ;-) 2 missing characters... Now it compile without warning or error -Message d'origine- De : [EMAIL PROTECTED] [mailto:[EMAIL PROTECTED] De la part de Oliver Neukum Envoyé : jeudi 19 juillet 2007 8:22 À : linux-usb-devel@lists.sourceforge.net Cc : Alain Degreffe Objet : Re: [linux-usb-devel] [PATCH] iuu_phoenix new driver proposal 2 Am Mittwoch 18 Juli 2007 schrieb Alain Degreffe: +static int iuu_tiocmget(struct usb_serial_port *port, struct file *file) +{ + u8 *st; + int status ; + st = kmalloc(sizeof(u8), GFP_KERNEL); + if (!st) + return -ENOMEM ; + iuu_status(port, st); + + dbg(%s (%d) msg , __FUNCTION__, port-number); + if (st[0] IUU_FULLCARD_IN) { + dbg(%s card present ! value returned %i , __FUNCTION__, + TIOCM_CD); + status = 0 ; + } else { + status TIOCM_CD; Could you make the code compileable and resubmit it? Regards Oliver - 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/ ___ linux-usb-devel@lists.sourceforge.net To unsubscribe, use the last form field at: https://lists.sourceforge.net/lists/listinfo/linux-usb-devel iuu_phoenix.patch Description: Binary data - 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/___ linux-usb-devel@lists.sourceforge.net To unsubscribe, use the last form field at: https://lists.sourceforge.net/lists/listinfo/linux-usb-devel
[linux-usb-devel] [PATCH] iuu_phoenix new driver proposal for review and comments
This patch add the new iuu_phoenix driver. Signed-off-by: Alain Degreffe [EMAIL PROTECTED] diff --git a/drivers/usb/serial/Kconfig b/drivers/usb/serial/Kconfig index 3efe670..1afcd0d 100644 --- a/drivers/usb/serial/Kconfig +++ b/drivers/usb/serial/Kconfig @@ -554,6 +554,15 @@ config USB_SERIAL_OMNINET To compile this driver as a module, choose M here: the module will be called omninet. +config USB_SERIAL_IUU + tristate Infinity Usb Unlimited SM Reader (EXPERIMENTAL) + depends on USB_SERIAL EXPERIMENTAL + help + Say Y here if you want to use a IUU in phoenix mode. + + To compile this driver as a module, choose M here: the + module will be called iuu_phoenix. + config USB_SERIAL_DEBUG tristate USB Debugging Device depends on USB_SERIAL diff --git a/drivers/usb/serial/Makefile b/drivers/usb/serial/Makefile index 61166ad..96b8ddc 100644 --- a/drivers/usb/serial/Makefile +++ b/drivers/usb/serial/Makefile @@ -47,4 +47,5 @@ obj-$(CONFIG_USB_SERIAL_TI) += ti_usb_3410_5052.o obj-$(CONFIG_USB_SERIAL_VISOR) += visor.o obj-$(CONFIG_USB_SERIAL_WHITEHEAT) += whiteheat.o obj-$(CONFIG_USB_SERIAL_XIRCOM)+= keyspan_pda.o +obj-$(CONFIG USB_SERIAL_IUU) += iuu_phoenix.o diff --git a/drivers/usb/serial/iuu_phoenix.c b/drivers/usb/serial/iuu_phoenix.c new file mode 100644 index 000..00f3e96 --- /dev/null +++ b/drivers/usb/serial/iuu_phoenix.c @@ -0,0 +1,1095 @@ +/* + * Infinity Unlimited USB Phoenix driver + * + * Copyright (C) 2007 Alain Degreffe ([EMAIL PROTECTED]) + * + * + * Original code taken from iuutool ( Copyright (C) 2006 Juan Carlos Borrás ) + * + * 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. + * + * And tested with help of WB Electronics + * + */ + +#include linux/kernel.h +#include linux/errno.h +#include linux/init.h +#include linux/slab.h +#include linux/tty.h +#include linux/tty_driver.h +#include linux/tty_flip.h +#include linux/serial.h +#include linux/module.h +#include linux/moduleparam.h +#include linux/spinlock.h +#include linux/uaccess.h +#include linux/usb.h +#include linux/usb/serial.h +#include iuu_phoenix.h + +#ifdef CONFIG_USB_SERIAL_DEBUG +int debug = 1; +#else +int debug = 0; +#endif + +/* + * Version Information + */ +#define DRIVER_VERSION v0.1 +#define DRIVER_DESC Infinity USB Unlimited Phoenix driver + +static struct usb_device_id id_table[] = { + {USB_DEVICE(IUU_USB_VENDOR_ID, IUU_USB_PRODUCT_ID)}, + {} /* Terminating entry */ +}; + +MODULE_DEVICE_TABLE(usb, id_table); + +static struct usb_driver iuu_driver = { + .name = iuu_phoenix, + .probe = usb_serial_probe, + .disconnect = usb_serial_disconnect, + .id_table = id_table, + .no_dynamic_id = 1, +}; + +static int iuu_startup(struct usb_serial *serial); + +static void iuu_shutdown(struct usb_serial *serial); + +static int iuu_open(struct usb_serial_port *port, struct file *filp); +static void iuu_close(struct usb_serial_port *port, struct file *filp); + +static int iuu_uart_write(struct usb_serial_port *port, + const u8 *buf, int count); + +static int read_immediate(struct usb_serial_port *port, u8 *buf, + u8 count); +static int iuu_uart_flush(struct usb_serial_port *port); +static int iuu_uart_read(struct usb_serial_port *port, u8 *data, +u8 *len); +static int iuu_uart_baud(struct usb_serial_port *port, u_int32_t baud, +u_int32_t *actual, u_int8_t parity); +static int iuu_reset(struct usb_serial_port *port, u_int8_t wt); +static int bulk_immediate(struct usb_serial_port *port, u8 *buf, + u8 count); + +static int iuu_ioctl(struct usb_serial_port *port, struct file *file, +unsigned int cmd, unsigned long arg); +static int iuu_tiocmset(struct usb_serial_port *port, struct file *file, + unsigned int set, unsigned int clear); +static int iuu_tiocmget(struct usb_serial_port *port, struct file *file); + +static int iuu_uart_read_and_store(struct usb_serial_port *port); +static int iuu_uart_on(struct usb_serial_port *port); +static int iuu_uart_off(struct usb_serial_port *port); + +static struct usb_serial_driver iuu_device = { + .driver = { + .owner = THIS_MODULE, + .name = IUU Phoenix, + }, + .id_table = id_table, + .num_interrupt_in = NUM_DONT_CARE, + .num_bulk_in = 1, + .num_bulk_out = 1, + .num_ports = 1, + .open = iuu_open, + .close = iuu_close, + .write = iuu_uart_write, + .ioctl = iuu_ioctl, + .tiocmget =