/* Send command to device. */
static int gigaset_write_cmd(struct cardstate *cs, struct cmdbuf_t *cb)
{
	unsigned long flags;

	gigaset_dbg_buffer(cs->mstate != MS_LOCKED ?
			     DEBUG_TRANSCMD : DEBUG_LOCKCMD,
			   "CMD Transmit", cb->len, cb->buf);

	spin_lock_irqsave(&cs->cmdlock, flags);
	cb->prev = cs->lastcmdbuf;
	if (cs->lastcmdbuf)
		cs->lastcmdbuf->next = cb;
	else {
		cs->cmdbuf = cb;
		cs->curlen = cb->len;
	}
	cs->cmdbytes += cb->len;
	cs->lastcmdbuf = cb;
	spin_unlock_irqrestore(&cs->cmdlock, flags);

	spin_lock_irqsave(&cs->lock, flags);
	if (cs->connected)
		tasklet_schedule(&cs->write_tasklet);
	spin_unlock_irqrestore(&cs->lock, flags);
	return cb->len;
}
/*
 * set the break characters on the internal serial adapter
 * using undocumented device commands reverse engineered from USB traces
 * of the Siemens Windows driver
 */
static int gigaset_brkchars(struct cardstate *cs, const unsigned char buf[6])
{
	struct usb_device *udev = cs->hw.usb->udev;

	gigaset_dbg_buffer(DEBUG_USBREQ, "brkchars", 6, buf);
	memcpy(cs->hw.usb->bchars, buf, 6);
	return usb_control_msg(udev, usb_sndctrlpipe(udev, 0), 0x19, 0x41,
			       0, 0, &buf, 6, 2000);
}
예제 #3
0
파일: usb-gigaset.c 프로젝트: 274914765/C
static int gigaset_brkchars(struct cardstate *cs, const unsigned char buf[6])
{
#ifdef CONFIG_GIGASET_UNDOCREQ
    struct usb_device *udev = cs->hw.usb->udev;

    gigaset_dbg_buffer(DEBUG_USBREQ, "brkchars", 6, buf);
    memcpy(cs->hw.usb->bchars, buf, 6);
    return usb_control_msg(udev, usb_sndctrlpipe(udev, 0), 0x19, 0x41,
                   0, 0, &buf, 6, 2000);
#else
    return -EINVAL;
#endif
}
예제 #4
0
파일: usb-gigaset.c 프로젝트: 274914765/C
/* Send command to device. */
static int gigaset_write_cmd(struct cardstate *cs, const unsigned char *buf,
                 int len, struct tasklet_struct *wake_tasklet)
{
    struct cmdbuf_t *cb;
    unsigned long flags;

    gigaset_dbg_buffer(cs->mstate != MS_LOCKED ?
                 DEBUG_TRANSCMD : DEBUG_LOCKCMD,
               "CMD Transmit", len, buf);

    if (len <= 0)
        return 0;

    if (!(cb = kmalloc(sizeof(struct cmdbuf_t) + len, GFP_ATOMIC))) {
        dev_err(cs->dev, "%s: out of memory\n", __func__);
        return -ENOMEM;
    }

    memcpy(cb->buf, buf, len);
    cb->len = len;
    cb->offset = 0;
    cb->next = NULL;
    cb->wake_tasklet = wake_tasklet;

    spin_lock_irqsave(&cs->cmdlock, flags);
    cb->prev = cs->lastcmdbuf;
    if (cs->lastcmdbuf)
        cs->lastcmdbuf->next = cb;
    else {
        cs->cmdbuf = cb;
        cs->curlen = len;
    }
    cs->cmdbytes += len;
    cs->lastcmdbuf = cb;
    spin_unlock_irqrestore(&cs->cmdlock, flags);

    spin_lock_irqsave(&cs->lock, flags);
    if (cs->connected)
        tasklet_schedule(&cs->write_tasklet);
    spin_unlock_irqrestore(&cs->lock, flags);
    return len;
}
예제 #5
0
파일: interface.c 프로젝트: Tigrouzen/k1099
static int if_ioctl(struct tty_struct *tty, struct file *file,
		    unsigned int cmd, unsigned long arg)
{
	struct cardstate *cs;
	int retval = -ENODEV;
	int int_arg;
	unsigned char buf[6];
	unsigned version[4];

	cs = (struct cardstate *) tty->driver_data;
	if (!cs) {
		err("cs==NULL in %s", __func__);
		return -ENODEV;
	}

	gig_dbg(DEBUG_IF, "%u: %s(0x%x)", cs->minor_index, __func__, cmd);

	if (mutex_lock_interruptible(&cs->mutex))
		return -ERESTARTSYS; // FIXME -EINTR?

	if (!cs->open_count)
		warn("%s: device not opened", __func__);
	else {
		retval = 0;
		switch (cmd) {
		case GIGASET_REDIR:
			retval = get_user(int_arg, (int __user *) arg);
			if (retval >= 0)
				retval = if_lock(cs, &int_arg);
			if (retval >= 0)
				retval = put_user(int_arg, (int __user *) arg);
			break;
		case GIGASET_CONFIG:
			retval = get_user(int_arg, (int __user *) arg);
			if (retval >= 0)
				retval = if_config(cs, &int_arg);
			if (retval >= 0)
				retval = put_user(int_arg, (int __user *) arg);
			break;
		case GIGASET_BRKCHARS:
			//FIXME test if MS_LOCKED
			if (!cs->connected) {
				gig_dbg(DEBUG_ANY,
				    "can't communicate with unplugged device");
				retval = -ENODEV;
				break;
			}
			retval = copy_from_user(&buf,
					(const unsigned char __user *) arg, 6)
				? -EFAULT : 0;
			if (retval >= 0) {
				gigaset_dbg_buffer(DEBUG_IF, "GIGASET_BRKCHARS",
						6, (const unsigned char *) arg);
				retval = cs->ops->brkchars(cs, buf);
			}
			break;
		case GIGASET_VERSION:
			retval = copy_from_user(version,
					(unsigned __user *) arg, sizeof version)
				? -EFAULT : 0;
			if (retval >= 0)
				retval = if_version(cs, version);
			if (retval >= 0)
				retval = copy_to_user((unsigned __user *) arg,
						      version, sizeof version)
					? -EFAULT : 0;
			break;
		default:
			gig_dbg(DEBUG_ANY, "%s: arg not supported - 0x%04x",
				__func__, cmd);
			retval = -ENOIOCTLCMD;
		}
	}

	mutex_unlock(&cs->mutex);

	return retval;
}
예제 #6
0
static int if_ioctl(struct tty_struct *tty,
		    unsigned int cmd, unsigned long arg)
{
	struct cardstate *cs = tty->driver_data;
	int retval = -ENODEV;
	int int_arg;
	unsigned char buf[6];
	unsigned version[4];

	gig_dbg(DEBUG_IF, "%u: %s(0x%x)", cs->minor_index, __func__, cmd);

	if (mutex_lock_interruptible(&cs->mutex))
		return -ERESTARTSYS;

	if (!cs->connected) {
		gig_dbg(DEBUG_IF, "not connected");
		retval = -ENODEV;
	} else {
		retval = 0;
		switch (cmd) {
		case GIGASET_REDIR:
			retval = get_user(int_arg, (int __user *) arg);
			if (retval >= 0)
				retval = if_lock(cs, &int_arg);
			if (retval >= 0)
				retval = put_user(int_arg, (int __user *) arg);
			break;
		case GIGASET_CONFIG:
			retval = get_user(int_arg, (int __user *) arg);
			if (retval >= 0)
				retval = if_config(cs, &int_arg);
			if (retval >= 0)
				retval = put_user(int_arg, (int __user *) arg);
			break;
		case GIGASET_BRKCHARS:
			retval = copy_from_user(&buf,
					(const unsigned char __user *) arg, 6)
				? -EFAULT : 0;
			if (retval >= 0) {
				gigaset_dbg_buffer(DEBUG_IF, "GIGASET_BRKCHARS",
						6, (const unsigned char *) arg);
				retval = cs->ops->brkchars(cs, buf);
			}
			break;
		case GIGASET_VERSION:
			retval = copy_from_user(version,
					(unsigned __user *) arg, sizeof version)
				? -EFAULT : 0;
			if (retval >= 0)
				retval = if_version(cs, version);
			if (retval >= 0)
				retval = copy_to_user((unsigned __user *) arg,
						      version, sizeof version)
					? -EFAULT : 0;
			break;
		default:
			gig_dbg(DEBUG_IF, "%s: arg not supported - 0x%04x",
				__func__, cmd);
			retval = -ENOIOCTLCMD;
		}
	}

	mutex_unlock(&cs->mutex);

	return retval;
}