-
- case VZIOC_GET_REG:
- if (get_user(block, (int __user *)arg))
- return -EFAULT;
- if (get_user(reg, (int __user *)(arg + sizeof(int))))
- return -EFAULT;
-
- data = kmalloc(1, GFP_KERNEL);
- if (data == NULL) {
- dev_err(&acm->control->dev, "%s - Cannot allocate USB buffer.\n", __func__);
- return -ENOMEM;
- }
-
- if (block == -1)
- block = acm->block;
-
- rv = vizzini_get_reg(acm, block, reg, data);
- if (rv != 1) {
- dev_err(&acm->control->dev, "Cannot get register (%d)\n", rv);
- kfree(data);
- return -EFAULT;
- }
-
- if (put_user(data[0], (int __user *)(arg + 2 * sizeof(int)))) {
- dev_err(&acm->control->dev, "Cannot put user result\n");
- kfree(data);
- return -EFAULT;
- }
-
- kfree(data);
- break;
-
- case VZIOC_SET_REG:
- if (get_user(block, (int __user *)arg))
- return -EFAULT;
- if (get_user(reg, (int __user *)(arg + sizeof(int))))
- return -EFAULT;
- if (get_user(val, (int __user *)(arg + 2 * sizeof(int))))
- return -EFAULT;
-
- if (block == -1)
- block = acm->block;
-
- rv = vizzini_set_reg(acm, block, reg, val);
- if (rv < 0)
- return -EFAULT;
- break;
-
- case VZIOC_SET_ADDRESS_MATCH:
- match = arg;
-
- dev_dbg(&acm->control->dev, "%s VIOC_SET_ADDRESS_MATCH %d\n", __func__, match);
-
- vizzini_disable(acm);
-
- if (match & VZ_ADDRESS_MATCH_DISABLE) {
- flow = UART_FLOW_MODE_NONE;
- } else {
- flow = UART_FLOW_MODE_ADDR_MATCH_TX;
- unicast = (match >> VZ_ADDRESS_UNICAST_S) & 0xff;
- broadcast = (match >> VZ_ADDRESS_BROADCAST_S) & 0xff;
- }
-
- dev_dbg(&acm->control->dev, "address match: flow=%d ucast=%d bcast=%u\n",
- flow, unicast, broadcast);
- vizzini_set_reg(acm, acm->block, UART_FLOW, flow);
- vizzini_set_reg(acm, acm->block, UART_XON_CHAR, unicast);
- vizzini_set_reg(acm, acm->block, UART_XOFF_CHAR, broadcast);
-
- vizzini_enable(acm);
- break;
-
- case VZIOC_SET_PRECISE_FLAGS:
- preciseflags = arg;
-
- dev_dbg(&acm->control->dev, "%s VIOC_SET_PRECISE_FLAGS %d\n", __func__, preciseflags);
-
- vizzini_disable(acm);
-
- if (preciseflags) {
- acm->preciseflags = 1;
- } else {
- acm->preciseflags = 0;
- }
-
- vizzini_set_reg(acm, EPLOCALS_REG_BLOCK,
- (acm->block * MEM_EP_LOCALS_SIZE) + EP_WIDE_MODE,
- acm->preciseflags);
-
- vizzini_enable(acm);
- rv = 0;
- break;
-
- case VZIOC_TEST_MODE:
- selector = arg;
- dev_dbg(&acm->control->dev, "%s VIOC_TEST_MODE 0x%02x\n", __func__, selector);
- vizzini_test_mode(acm, selector);
- rv = 0;
- break;
-
- case VZIOC_LOOPBACK:
- selector = arg;
- dev_dbg(&acm->control->dev, "VIOC_LOOPBACK 0x%02x\n", selector);
- vizzini_loopback(acm, selector);
- rv = 0;
- break;