*
*/
-#include <linux/config.h>
#include <linux/kernel.h>
#include <linux/errno.h>
#include <linux/init.h>
#include <linux/spinlock.h>
#include <asm/uaccess.h>
#include <linux/usb.h>
-#include "usb-serial.h"
+#include <linux/usb/serial.h>
static int debug;
/* function prototypes */
static int omninet_open (struct usb_serial_port *port, struct file *filp);
static void omninet_close (struct usb_serial_port *port, struct file *filp);
-static void omninet_read_bulk_callback (struct urb *urb, struct pt_regs *regs);
-static void omninet_write_bulk_callback (struct urb *urb, struct pt_regs *regs);
-static int omninet_write (struct usb_serial_port *port, int from_user, const unsigned char *buf, int count);
+static void omninet_read_bulk_callback (struct urb *urb);
+static void omninet_write_bulk_callback (struct urb *urb);
+static int omninet_write (struct usb_serial_port *port, const unsigned char *buf, int count);
static int omninet_write_room (struct usb_serial_port *port);
static void omninet_shutdown (struct usb_serial *serial);
MODULE_DEVICE_TABLE (usb, id_table);
static struct usb_driver omninet_driver = {
- .owner = THIS_MODULE,
.name = "omninet",
.probe = usb_serial_probe,
.disconnect = usb_serial_disconnect,
.id_table = id_table,
+ .no_dynamic_id = 1,
};
-static struct usb_serial_device_type zyxel_omninet_device = {
- .owner = THIS_MODULE,
- .name = "ZyXEL - omni.net lcd plus usb",
- .short_name = "omninet",
+static struct usb_serial_driver zyxel_omninet_device = {
+ .driver = {
+ .owner = THIS_MODULE,
+ .name = "omninet",
+ },
+ .description = "ZyXEL - omni.net lcd plus usb",
.id_table = id_table,
.num_interrupt_in = 1,
.num_bulk_in = 1,
{
struct usb_serial *serial = port->serial;
struct usb_serial_port *wport;
- struct omninet_data *od;
dbg("%s - port %d", __FUNCTION__, port->number);
wport = serial->port[1];
- usb_unlink_urb(wport->write_urb);
- usb_unlink_urb(port->read_urb);
+ usb_kill_urb(wport->write_urb);
+ usb_kill_urb(port->read_urb);
- od = usb_get_serial_port_data(port);
- if (od)
- kfree(od);
+ kfree(usb_get_serial_port_data(port));
}
#define OMNINET_HEADERLEN sizeof(struct omninet_header)
#define OMNINET_BULKOUTSIZE (64 - OMNINET_HEADERLEN)
-static void omninet_read_bulk_callback (struct urb *urb, struct pt_regs *regs)
+static void omninet_read_bulk_callback (struct urb *urb)
{
struct usb_serial_port *port = (struct usb_serial_port *)urb->context;
unsigned char *data = urb->transfer_buffer;
int i;
int result;
-// dbg("omninet_read_bulk_callback");
+ dbg("%s - port %d", __FUNCTION__, port->number);
if (urb->status) {
dbg("%s - nonzero read bulk status received: %d", __FUNCTION__, urb->status);
return;
}
-static int omninet_write (struct usb_serial_port *port, int from_user, const unsigned char *buf, int count)
+static int omninet_write (struct usb_serial_port *port, const unsigned char *buf, int count)
{
struct usb_serial *serial = port->serial;
struct usb_serial_port *wport = serial->port[1];
int result;
-// dbg("omninet_write port %d", port->number);
+ dbg("%s - port %d", __FUNCTION__, port->number);
if (count == 0) {
dbg("%s - write request of 0 bytes", __FUNCTION__);
return (0);
}
- if (wport->write_urb->status == -EINPROGRESS) {
+
+ spin_lock_bh(&wport->lock);
+ if (wport->write_urb_busy) {
+ spin_unlock_bh(&wport->lock);
dbg("%s - already writing", __FUNCTION__);
- return (0);
+ return 0;
}
+ wport->write_urb_busy = 1;
+ spin_unlock_bh(&wport->lock);
count = (count > OMNINET_BULKOUTSIZE) ? OMNINET_BULKOUTSIZE : count;
- if (from_user) {
- if (copy_from_user(wport->write_urb->transfer_buffer + OMNINET_DATAOFFSET, buf, count) != 0) {
- result = -EFAULT;
- goto exit;
- }
- }
- else {
- memcpy (wport->write_urb->transfer_buffer + OMNINET_DATAOFFSET, buf, count);
- }
+ memcpy (wport->write_urb->transfer_buffer + OMNINET_DATAOFFSET, buf, count);
usb_serial_debug_data(debug, &port->dev, __FUNCTION__, count, wport->write_urb->transfer_buffer);
wport->write_urb->dev = serial->dev;
result = usb_submit_urb(wport->write_urb, GFP_ATOMIC);
- if (result)
+ if (result) {
+ wport->write_urb_busy = 0;
err("%s - failed submitting write urb, error %d", __FUNCTION__, result);
- else
+ } else
result = count;
-exit:
return result;
}
int room = 0; // Default: no room
- if (wport->write_urb->status != -EINPROGRESS)
+ if (wport->write_urb_busy)
room = wport->bulk_out_size - OMNINET_HEADERLEN;
-// dbg("omninet_write_room returns %d", room);
+ dbg("%s - returns %d", __FUNCTION__, room);
return (room);
}
-static void omninet_write_bulk_callback (struct urb *urb, struct pt_regs *regs)
+static void omninet_write_bulk_callback (struct urb *urb)
{
/* struct omninet_header *header = (struct omninet_header *) urb->transfer_buffer; */
struct usb_serial_port *port = (struct usb_serial_port *) urb->context;
-// dbg("omninet_write_bulk_callback, port %0x\n", port);
+ dbg("%s - port %0x\n", __FUNCTION__, port->number);
+ port->write_urb_busy = 0;
if (urb->status) {
dbg("%s - nonzero write bulk status received: %d", __FUNCTION__, urb->status);
return;
}
- schedule_work(&port->work);
-
-// dbg("omninet_write_bulk_callback, tty %0x\n", tty);
+ usb_serial_port_softint(port);
}