* Copyright (C) 2001 REINER SCT
* Author: Matthias Bruestle
*
- * Contact: linux-usb@sii.li (see MAINTAINERS)
+ * Contact: support@reiner-sct.com (see MAINTAINERS)
*
* This program is largely derived from work by the linux-usb group
* and associated source files. Please see the usb/serial files for
*
* In case of problems, please write to the contact e-mail address
* mentioned above.
+ *
+ * Please note that later models of the cyberjack reader family are
+ * supported by a libusb-based userspace device driver.
+ *
+ * Homepage: http://www.reiner-sct.de/support/treiber_cyberjack.php#linux
*/
#include <linux/spinlock.h>
#include <asm/uaccess.h>
#include <linux/usb.h>
+#include "usb-serial.h"
#define CYBERJACK_LOCAL_BUF_SIZE 32
-#ifdef CONFIG_USB_SERIAL_DEBUG
- static int debug = 1;
-#else
- static int debug;
-#endif
-
-#include "usb-serial.h"
+static int debug;
/*
* Version Information
*/
-#define DRIVER_VERSION "v1.0"
+#define DRIVER_VERSION "v1.01"
#define DRIVER_AUTHOR "Matthias Bruestle"
#define DRIVER_DESC "REINER SCT cyberJack pinpad/e-com USB Chipcard Reader Driver"
static void cyberjack_shutdown (struct usb_serial *serial);
static int cyberjack_open (struct usb_serial_port *port, struct file *filp);
static void cyberjack_close (struct usb_serial_port *port, struct file *filp);
-static int cyberjack_write (struct usb_serial_port *port, int from_user,
- const unsigned char *buf, int count);
+static int cyberjack_write (struct usb_serial_port *port, const unsigned char *buf, int count);
static int cyberjack_write_room( struct usb_serial_port *port );
static void cyberjack_read_int_callback (struct urb *urb, struct pt_regs *regs);
static void cyberjack_read_bulk_callback (struct urb *urb, struct pt_regs *regs);
static int cyberjack_startup (struct usb_serial *serial)
{
struct cyberjack_private *priv;
+ int i;
dbg("%s", __FUNCTION__);
init_waitqueue_head(&serial->port[0]->write_wait);
+ for (i = 0; i < serial->num_ports; ++i) {
+ int result;
+ serial->port[i]->interrupt_in_urb->dev = serial->dev;
+ result = usb_submit_urb(serial->port[i]->interrupt_in_urb,
+ GFP_KERNEL);
+ if (result)
+ err(" usb_submit_urb(read int) failed");
+ dbg("%s - usb_submit_urb(int urb)", __FUNCTION__);
+ }
+
return( 0 );
}
dbg("%s", __FUNCTION__);
for (i=0; i < serial->num_ports; ++i) {
+ usb_kill_urb(serial->port[i]->interrupt_in_urb);
/* My special items, the standard routines free my urbs */
kfree(usb_get_serial_port_data(serial->port[i]));
usb_set_serial_port_data(serial->port[i], NULL);
priv->wrsent = 0;
spin_unlock_irqrestore(&priv->lock, flags);
- /* shutdown any bulk reads that might be going on */
- usb_unlink_urb (port->write_urb);
- usb_unlink_urb (port->read_urb);
- usb_unlink_urb (port->interrupt_in_urb);
-
- port->interrupt_in_urb->dev = port->serial->dev;
- result = usb_submit_urb(port->interrupt_in_urb, GFP_KERNEL);
- if (result)
- err(" usb_submit_urb(read int) failed");
- dbg("%s - usb_submit_urb(int urb)", __FUNCTION__);
-
return result;
}
if (port->serial->dev) {
/* shutdown any bulk reads that might be going on */
- usb_unlink_urb (port->write_urb);
- usb_unlink_urb (port->read_urb);
- usb_unlink_urb (port->interrupt_in_urb);
- dbg("%s - usb_clear_halt", __FUNCTION__ );
- usb_clear_halt(port->serial->dev, port->write_urb->pipe);
- usb_clear_halt(port->serial->dev, port->read_urb->pipe);
- usb_clear_halt(port->serial->dev, port->interrupt_in_urb->pipe);
+ usb_kill_urb(port->write_urb);
+ usb_kill_urb(port->read_urb);
}
}
-static int cyberjack_write (struct usb_serial_port *port, int from_user, const unsigned char *buf, int count)
+static int cyberjack_write (struct usb_serial_port *port, const unsigned char *buf, int count)
{
struct usb_serial *serial = port->serial;
struct cyberjack_private *priv = usb_get_serial_port_data(port);
int wrexpected;
dbg("%s - port %d", __FUNCTION__, port->number);
- dbg("%s - from_user %d", __FUNCTION__, from_user);
if (count == 0) {
dbg("%s - write request of 0 bytes", __FUNCTION__);
}
/* Copy data */
- if (from_user) {
- if (copy_from_user(priv->wrbuf+priv->wrfilled, buf, count)) {
- spin_unlock_irqrestore(&priv->lock, flags);
- return -EFAULT;
- }
- } else {
- memcpy (priv->wrbuf+priv->wrfilled, buf, count);
- }
+ memcpy (priv->wrbuf+priv->wrfilled, buf, count);
- usb_serial_debug_data (__FILE__, __FUNCTION__, count,
+ usb_serial_debug_data(debug, &port->dev, __FUNCTION__, count,
priv->wrbuf+priv->wrfilled);
priv->wrfilled += count;
if (urb->status)
return;
- usb_serial_debug_data (__FILE__, __FUNCTION__, urb->actual_length, data);
+ usb_serial_debug_data(debug, &port->dev, __FUNCTION__, urb->actual_length, data);
/* React only to interrupts signaling a bulk_in transfer */
if( (urb->actual_length==4) && (data[0]==0x01) ) {
dbg("%s - port %d", __FUNCTION__, port->number);
+ usb_serial_debug_data(debug, &port->dev, __FUNCTION__, urb->actual_length, data);
if (urb->status) {
- usb_serial_debug_data (__FILE__, __FUNCTION__, urb->actual_length, urb->transfer_buffer);
dbg("%s - nonzero read bulk status received: %d", __FUNCTION__, urb->status);
return;
}
- usb_serial_debug_data (__FILE__, __FUNCTION__, urb->actual_length, data);
-
tty = port->tty;
+ if (!tty) {
+ dbg("%s - ignoring since device not open\n", __FUNCTION__);
+ return;
+ }
if (urb->actual_length) {
for (i = 0; i < urb->actual_length ; ++i) {
/* if we insert more than TTY_FLIPBUF_SIZE characters, we drop them. */
MODULE_AUTHOR( DRIVER_AUTHOR );
MODULE_DESCRIPTION( DRIVER_DESC );
+MODULE_VERSION( DRIVER_VERSION );
MODULE_LICENSE("GPL");
-MODULE_PARM(debug, "i");
+module_param(debug, bool, S_IRUGO | S_IWUSR);
MODULE_PARM_DESC(debug, "Debug enabled or not");
-