#include <linux/device.h>
#include <linux/tty.h>
#include <linux/tty_flip.h>
+#include <linux/mutex.h>
#include <asm/byteorder.h>
#include <asm/io.h>
static const char *EP_OUT_NAME;
static const char *EP_NOTIFY_NAME;
-static struct semaphore gs_open_close_sem[GS_NUM_PORTS];
+static struct mutex gs_open_close_lock[GS_NUM_PORTS];
static unsigned int read_q_size = GS_DEFAULT_READ_Q_SIZE;
static unsigned int write_q_size = GS_DEFAULT_WRITE_Q_SIZE;
tty_set_operations(gs_tty_driver, &gs_tty_ops);
for (i=0; i < GS_NUM_PORTS; i++)
- sema_init(&gs_open_close_sem[i], 1);
+ mutex_init(&gs_open_close_lock[i]);
retval = tty_register_driver(gs_tty_driver);
if (retval) {
struct gs_port *port;
struct gs_dev *dev;
struct gs_buf *buf;
- struct semaphore *sem;
+ struct mutex *mtx;
int ret;
port_num = tty->index;
return -ENODEV;
}
- sem = &gs_open_close_sem[port_num];
- if (down_interruptible(sem)) {
+ mtx = &gs_open_close_lock[port_num];
+ if (mutex_lock_interruptible(mtx)) {
printk(KERN_ERR
- "gs_open: (%d,%p,%p) interrupted waiting for semaphore\n",
+ "gs_open: (%d,%p,%p) interrupted waiting for mutex\n",
port_num, tty, file);
return -ERESTARTSYS;
}
exit_unlock_port:
spin_unlock_irqrestore(&port->port_lock, flags);
- up(sem);
+ mutex_unlock(mtx);
return ret;
exit_unlock_dev:
spin_unlock_irqrestore(&dev->dev_lock, flags);
- up(sem);
+ mutex_unlock(mtx);
return ret;
}
static void gs_close(struct tty_struct *tty, struct file *file)
{
struct gs_port *port = tty->driver_data;
- struct semaphore *sem;
+ struct mutex *mtx;
if (port == NULL) {
printk(KERN_ERR "gs_close: NULL port pointer\n");
gs_debug("gs_close: (%d,%p,%p)\n", port->port_num, tty, file);
- sem = &gs_open_close_sem[port->port_num];
- down(sem);
+ mtx = &gs_open_close_lock[port->port_num];
+ mutex_lock(mtx);
spin_lock_irq(&port->port_lock);
exit:
spin_unlock_irq(&port->port_lock);
- up(sem);
+ mutex_unlock(mtx);
}
/*
switch (ctrl->bRequest) {
case USB_CDC_REQ_SET_LINE_CODING:
- ret = min(wLength,
- (u16)sizeof(struct usb_cdc_line_coding));
- if (port) {
- spin_lock(&port->port_lock);
- memcpy(&port->port_line_coding, req->buf, ret);
- spin_unlock(&port->port_lock);
- }
- ret = 0;
+ /* FIXME Submit req to read the data; have its completion
+ * handler copy that data to port->port_line_coding (iff
+ * it's valid) and maybe pass it on. Until then, fail.
+ */
+ printk(KERN_WARNING "gs_setup: set_line_coding "
+ "unuspported\n");
break;
case USB_CDC_REQ_GET_LINE_CODING:
break;
case USB_CDC_REQ_SET_CONTROL_LINE_STATE:
- ret = 0;
+ /* FIXME Submit req to read the data; have its completion
+ * handler use that to set the state (iff it's valid) and
+ * maybe pass it on. Until then, fail.
+ */
+ printk(KERN_WARNING "gs_setup: set_control_line_state "
+ "unuspported\n");
break;
default:
- printk(KERN_ERR "gs_setup: unknown class request, type=%02x, request=%02x, value=%04x, index=%04x, length=%d\n",
+ printk(KERN_ERR "gs_setup: unknown class request, "
+ "type=%02x, request=%02x, value=%04x, "
+ "index=%04x, length=%d\n",
ctrl->bRequestType, ctrl->bRequest,
wValue, wIndex, wLength);
break;