| .. | .. |
|---|
| 185 | 185 | for (;;) { |
|---|
| 186 | 186 | wb = &acm->wb[wbn]; |
|---|
| 187 | 187 | if (!wb->use) { |
|---|
| 188 | | - wb->use = 1; |
|---|
| 188 | + wb->use = true; |
|---|
| 189 | 189 | wb->len = 0; |
|---|
| 190 | 190 | return wbn; |
|---|
| 191 | 191 | } |
|---|
| .. | .. |
|---|
| 203 | 203 | n = ACM_NW; |
|---|
| 204 | 204 | spin_lock_irqsave(&acm->write_lock, flags); |
|---|
| 205 | 205 | for (i = 0; i < ACM_NW; i++) |
|---|
| 206 | | - n -= acm->wb[i].use; |
|---|
| 206 | + if(acm->wb[i].use) |
|---|
| 207 | + n--; |
|---|
| 207 | 208 | spin_unlock_irqrestore(&acm->write_lock, flags); |
|---|
| 208 | 209 | return n; |
|---|
| 209 | 210 | } |
|---|
| .. | .. |
|---|
| 213 | 214 | */ |
|---|
| 214 | 215 | static void acm_write_done(struct acm *acm, struct acm_wb *wb) |
|---|
| 215 | 216 | { |
|---|
| 216 | | - wb->use = 0; |
|---|
| 217 | + wb->use = false; |
|---|
| 217 | 218 | acm->transmitting--; |
|---|
| 218 | 219 | usb_autopm_put_interface_async(acm->control); |
|---|
| 219 | 220 | } |
|---|
| .. | .. |
|---|
| 494 | 495 | { |
|---|
| 495 | 496 | struct acm_rb *rb = urb->context; |
|---|
| 496 | 497 | struct acm *acm = rb->instance; |
|---|
| 497 | | - unsigned long flags; |
|---|
| 498 | 498 | int status = urb->status; |
|---|
| 499 | 499 | bool stopped = false; |
|---|
| 500 | 500 | bool stalled = false; |
|---|
| .. | .. |
|---|
| 558 | 558 | return; |
|---|
| 559 | 559 | } |
|---|
| 560 | 560 | |
|---|
| 561 | | - /* throttle device if requested by tty */ |
|---|
| 562 | | - spin_lock_irqsave(&acm->read_lock, flags); |
|---|
| 563 | | - acm->throttled = acm->throttle_req; |
|---|
| 564 | | - if (!acm->throttled) { |
|---|
| 565 | | - spin_unlock_irqrestore(&acm->read_lock, flags); |
|---|
| 566 | | - acm_submit_read_urb(acm, rb->index, GFP_ATOMIC); |
|---|
| 567 | | - } else { |
|---|
| 568 | | - spin_unlock_irqrestore(&acm->read_lock, flags); |
|---|
| 569 | | - } |
|---|
| 561 | + if (test_bit(ACM_THROTTLED, &acm->flags)) |
|---|
| 562 | + return; |
|---|
| 563 | + |
|---|
| 564 | + acm_submit_read_urb(acm, rb->index, GFP_ATOMIC); |
|---|
| 570 | 565 | } |
|---|
| 571 | 566 | |
|---|
| 572 | 567 | /* data interface wrote those outgoing bytes */ |
|---|
| .. | .. |
|---|
| 710 | 705 | /* |
|---|
| 711 | 706 | * Unthrottle device in case the TTY was closed while throttled. |
|---|
| 712 | 707 | */ |
|---|
| 713 | | - spin_lock_irq(&acm->read_lock); |
|---|
| 714 | | - acm->throttled = 0; |
|---|
| 715 | | - acm->throttle_req = 0; |
|---|
| 716 | | - spin_unlock_irq(&acm->read_lock); |
|---|
| 708 | + clear_bit(ACM_THROTTLED, &acm->flags); |
|---|
| 717 | 709 | |
|---|
| 718 | 710 | retval = acm_submit_read_urbs(acm, GFP_KERNEL); |
|---|
| 719 | 711 | if (retval) |
|---|
| .. | .. |
|---|
| 772 | 764 | if (!urb) |
|---|
| 773 | 765 | break; |
|---|
| 774 | 766 | wb = urb->context; |
|---|
| 775 | | - wb->use = 0; |
|---|
| 767 | + wb->use = false; |
|---|
| 776 | 768 | usb_autopm_put_interface_async(acm->control); |
|---|
| 777 | 769 | } |
|---|
| 778 | 770 | |
|---|
| .. | .. |
|---|
| 824 | 816 | wb = &acm->wb[wbn]; |
|---|
| 825 | 817 | |
|---|
| 826 | 818 | if (!acm->dev) { |
|---|
| 827 | | - wb->use = 0; |
|---|
| 819 | + wb->use = false; |
|---|
| 828 | 820 | spin_unlock_irqrestore(&acm->write_lock, flags); |
|---|
| 829 | 821 | return -ENODEV; |
|---|
| 830 | 822 | } |
|---|
| .. | .. |
|---|
| 836 | 828 | |
|---|
| 837 | 829 | stat = usb_autopm_get_interface_async(acm->control); |
|---|
| 838 | 830 | if (stat) { |
|---|
| 839 | | - wb->use = 0; |
|---|
| 831 | + wb->use = false; |
|---|
| 840 | 832 | spin_unlock_irqrestore(&acm->write_lock, flags); |
|---|
| 841 | 833 | return stat; |
|---|
| 842 | 834 | } |
|---|
| .. | .. |
|---|
| 884 | 876 | { |
|---|
| 885 | 877 | struct acm *acm = tty->driver_data; |
|---|
| 886 | 878 | |
|---|
| 887 | | - spin_lock_irq(&acm->read_lock); |
|---|
| 888 | | - acm->throttle_req = 1; |
|---|
| 889 | | - spin_unlock_irq(&acm->read_lock); |
|---|
| 879 | + set_bit(ACM_THROTTLED, &acm->flags); |
|---|
| 890 | 880 | } |
|---|
| 891 | 881 | |
|---|
| 892 | 882 | static void acm_tty_unthrottle(struct tty_struct *tty) |
|---|
| 893 | 883 | { |
|---|
| 894 | 884 | struct acm *acm = tty->driver_data; |
|---|
| 895 | | - unsigned int was_throttled; |
|---|
| 896 | 885 | |
|---|
| 897 | | - spin_lock_irq(&acm->read_lock); |
|---|
| 898 | | - was_throttled = acm->throttled; |
|---|
| 899 | | - acm->throttled = 0; |
|---|
| 900 | | - acm->throttle_req = 0; |
|---|
| 901 | | - spin_unlock_irq(&acm->read_lock); |
|---|
| 886 | + clear_bit(ACM_THROTTLED, &acm->flags); |
|---|
| 902 | 887 | |
|---|
| 903 | 888 | /* Matches the smp_mb__after_atomic() in acm_read_bulk_callback(). */ |
|---|
| 904 | 889 | smp_mb(); |
|---|
| 905 | 890 | |
|---|
| 906 | | - if (was_throttled) |
|---|
| 907 | | - acm_submit_read_urbs(acm, GFP_KERNEL); |
|---|
| 891 | + acm_submit_read_urbs(acm, GFP_KERNEL); |
|---|
| 908 | 892 | } |
|---|
| 909 | 893 | |
|---|
| 910 | 894 | static int acm_tty_break_ctl(struct tty_struct *tty, int state) |
|---|
| .. | .. |
|---|
| 950 | 934 | return acm_set_control(acm, acm->ctrlout = newctrl); |
|---|
| 951 | 935 | } |
|---|
| 952 | 936 | |
|---|
| 953 | | -static int get_serial_info(struct acm *acm, struct serial_struct __user *info) |
|---|
| 937 | +static int get_serial_info(struct tty_struct *tty, struct serial_struct *ss) |
|---|
| 954 | 938 | { |
|---|
| 955 | | - struct serial_struct tmp; |
|---|
| 939 | + struct acm *acm = tty->driver_data; |
|---|
| 956 | 940 | |
|---|
| 957 | | - memset(&tmp, 0, sizeof(tmp)); |
|---|
| 958 | | - tmp.xmit_fifo_size = acm->writesize; |
|---|
| 959 | | - tmp.baud_base = le32_to_cpu(acm->line.dwDTERate); |
|---|
| 960 | | - tmp.close_delay = jiffies_to_msecs(acm->port.close_delay) / 10; |
|---|
| 961 | | - tmp.closing_wait = acm->port.closing_wait == ASYNC_CLOSING_WAIT_NONE ? |
|---|
| 941 | + ss->line = acm->minor; |
|---|
| 942 | + ss->close_delay = jiffies_to_msecs(acm->port.close_delay) / 10; |
|---|
| 943 | + ss->closing_wait = acm->port.closing_wait == ASYNC_CLOSING_WAIT_NONE ? |
|---|
| 962 | 944 | ASYNC_CLOSING_WAIT_NONE : |
|---|
| 963 | 945 | jiffies_to_msecs(acm->port.closing_wait) / 10; |
|---|
| 964 | | - |
|---|
| 965 | | - if (copy_to_user(info, &tmp, sizeof(tmp))) |
|---|
| 966 | | - return -EFAULT; |
|---|
| 967 | | - else |
|---|
| 968 | | - return 0; |
|---|
| 946 | + return 0; |
|---|
| 969 | 947 | } |
|---|
| 970 | 948 | |
|---|
| 971 | | -static int set_serial_info(struct acm *acm, |
|---|
| 972 | | - struct serial_struct __user *newinfo) |
|---|
| 949 | +static int set_serial_info(struct tty_struct *tty, struct serial_struct *ss) |
|---|
| 973 | 950 | { |
|---|
| 974 | | - struct serial_struct new_serial; |
|---|
| 951 | + struct acm *acm = tty->driver_data; |
|---|
| 975 | 952 | unsigned int closing_wait, close_delay; |
|---|
| 976 | | - unsigned int old_closing_wait, old_close_delay; |
|---|
| 977 | 953 | int retval = 0; |
|---|
| 978 | 954 | |
|---|
| 979 | | - if (copy_from_user(&new_serial, newinfo, sizeof(new_serial))) |
|---|
| 980 | | - return -EFAULT; |
|---|
| 981 | | - |
|---|
| 982 | | - close_delay = msecs_to_jiffies(new_serial.close_delay * 10); |
|---|
| 983 | | - closing_wait = new_serial.closing_wait == ASYNC_CLOSING_WAIT_NONE ? |
|---|
| 955 | + close_delay = msecs_to_jiffies(ss->close_delay * 10); |
|---|
| 956 | + closing_wait = ss->closing_wait == ASYNC_CLOSING_WAIT_NONE ? |
|---|
| 984 | 957 | ASYNC_CLOSING_WAIT_NONE : |
|---|
| 985 | | - msecs_to_jiffies(new_serial.closing_wait * 10); |
|---|
| 986 | | - |
|---|
| 987 | | - /* we must redo the rounding here, so that the values match */ |
|---|
| 988 | | - old_close_delay = jiffies_to_msecs(acm->port.close_delay) / 10; |
|---|
| 989 | | - old_closing_wait = acm->port.closing_wait == ASYNC_CLOSING_WAIT_NONE ? |
|---|
| 990 | | - ASYNC_CLOSING_WAIT_NONE : |
|---|
| 991 | | - jiffies_to_msecs(acm->port.closing_wait) / 10; |
|---|
| 958 | + msecs_to_jiffies(ss->closing_wait * 10); |
|---|
| 992 | 959 | |
|---|
| 993 | 960 | mutex_lock(&acm->port.mutex); |
|---|
| 994 | 961 | |
|---|
| 995 | 962 | if (!capable(CAP_SYS_ADMIN)) { |
|---|
| 996 | | - if ((new_serial.close_delay != old_close_delay) || |
|---|
| 997 | | - (new_serial.closing_wait != old_closing_wait)) |
|---|
| 963 | + if ((close_delay != acm->port.close_delay) || |
|---|
| 964 | + (closing_wait != acm->port.closing_wait)) |
|---|
| 998 | 965 | retval = -EPERM; |
|---|
| 999 | 966 | } else { |
|---|
| 1000 | 967 | acm->port.close_delay = close_delay; |
|---|
| .. | .. |
|---|
| 1071 | 1038 | int rv = -ENOIOCTLCMD; |
|---|
| 1072 | 1039 | |
|---|
| 1073 | 1040 | switch (cmd) { |
|---|
| 1074 | | - case TIOCGSERIAL: /* gets serial port data */ |
|---|
| 1075 | | - rv = get_serial_info(acm, (struct serial_struct __user *) arg); |
|---|
| 1076 | | - break; |
|---|
| 1077 | | - case TIOCSSERIAL: |
|---|
| 1078 | | - rv = set_serial_info(acm, (struct serial_struct __user *) arg); |
|---|
| 1079 | | - break; |
|---|
| 1080 | 1041 | case TIOCMIWAIT: |
|---|
| 1081 | 1042 | rv = usb_autopm_get_interface(acm->control); |
|---|
| 1082 | 1043 | if (rv < 0) { |
|---|
| .. | .. |
|---|
| 1249 | 1210 | return -EINVAL; |
|---|
| 1250 | 1211 | } |
|---|
| 1251 | 1212 | |
|---|
| 1252 | | - if (!intf->cur_altsetting) |
|---|
| 1253 | | - return -EINVAL; |
|---|
| 1254 | | - |
|---|
| 1255 | 1213 | if (!buflen) { |
|---|
| 1256 | 1214 | if (intf->cur_altsetting->endpoint && |
|---|
| 1257 | 1215 | intf->cur_altsetting->endpoint->extralen && |
|---|
| .. | .. |
|---|
| 1274 | 1232 | call_intf_num = cmgmd->bDataInterface; |
|---|
| 1275 | 1233 | |
|---|
| 1276 | 1234 | if (!union_header) { |
|---|
| 1277 | | - if (call_intf_num > 0) { |
|---|
| 1235 | + if (intf->cur_altsetting->desc.bNumEndpoints == 3) { |
|---|
| 1236 | + dev_dbg(&intf->dev, "No union descriptor, assuming single interface\n"); |
|---|
| 1237 | + combined_interfaces = 1; |
|---|
| 1238 | + control_interface = data_interface = intf; |
|---|
| 1239 | + goto look_for_collapsed_interface; |
|---|
| 1240 | + } else if (call_intf_num > 0) { |
|---|
| 1278 | 1241 | dev_dbg(&intf->dev, "No union descriptor, using call management descriptor\n"); |
|---|
| 1279 | | - /* quirks for Droids MuIn LCD */ |
|---|
| 1280 | | - if (quirks & NO_DATA_INTERFACE) { |
|---|
| 1281 | | - data_interface = usb_ifnum_to_if(usb_dev, 0); |
|---|
| 1282 | | - } else { |
|---|
| 1283 | | - data_intf_num = call_intf_num; |
|---|
| 1284 | | - data_interface = usb_ifnum_to_if(usb_dev, data_intf_num); |
|---|
| 1285 | | - } |
|---|
| 1242 | + data_intf_num = call_intf_num; |
|---|
| 1243 | + data_interface = usb_ifnum_to_if(usb_dev, data_intf_num); |
|---|
| 1286 | 1244 | control_interface = intf; |
|---|
| 1287 | 1245 | } else { |
|---|
| 1288 | | - if (intf->cur_altsetting->desc.bNumEndpoints != 3) { |
|---|
| 1289 | | - dev_dbg(&intf->dev,"No union descriptor, giving up\n"); |
|---|
| 1290 | | - return -ENODEV; |
|---|
| 1291 | | - } else { |
|---|
| 1292 | | - dev_warn(&intf->dev,"No union descriptor, testing for castrated device\n"); |
|---|
| 1293 | | - combined_interfaces = 1; |
|---|
| 1294 | | - control_interface = data_interface = intf; |
|---|
| 1295 | | - goto look_for_collapsed_interface; |
|---|
| 1296 | | - } |
|---|
| 1246 | + dev_dbg(&intf->dev, "No union descriptor, giving up\n"); |
|---|
| 1247 | + return -ENODEV; |
|---|
| 1297 | 1248 | } |
|---|
| 1298 | 1249 | } else { |
|---|
| 1299 | 1250 | int class = -1; |
|---|
| .. | .. |
|---|
| 1317 | 1268 | dev_dbg(&intf->dev, "no interfaces\n"); |
|---|
| 1318 | 1269 | return -ENODEV; |
|---|
| 1319 | 1270 | } |
|---|
| 1320 | | - if (!data_interface->cur_altsetting || !control_interface->cur_altsetting) |
|---|
| 1321 | | - return -ENODEV; |
|---|
| 1322 | 1271 | |
|---|
| 1323 | 1272 | if (data_intf_num != call_intf_num) |
|---|
| 1324 | 1273 | dev_dbg(&intf->dev, "Separate call control interface. That is not fully supported.\n"); |
|---|
| .. | .. |
|---|
| 1345 | 1294 | skip_normal_probe: |
|---|
| 1346 | 1295 | |
|---|
| 1347 | 1296 | /*workaround for switched interfaces */ |
|---|
| 1348 | | - if (data_interface->cur_altsetting->desc.bInterfaceClass |
|---|
| 1349 | | - != CDC_DATA_INTERFACE_TYPE) { |
|---|
| 1350 | | - if (control_interface->cur_altsetting->desc.bInterfaceClass |
|---|
| 1351 | | - == CDC_DATA_INTERFACE_TYPE) { |
|---|
| 1297 | + if (data_interface->cur_altsetting->desc.bInterfaceClass != USB_CLASS_CDC_DATA) { |
|---|
| 1298 | + if (control_interface->cur_altsetting->desc.bInterfaceClass == USB_CLASS_CDC_DATA) { |
|---|
| 1352 | 1299 | dev_dbg(&intf->dev, |
|---|
| 1353 | 1300 | "Your device has switched interfaces.\n"); |
|---|
| 1354 | 1301 | swap(control_interface, data_interface); |
|---|
| .. | .. |
|---|
| 1883 | 1830 | { USB_DEVICE(0x09d8, 0x0320), /* Elatec GmbH TWN3 */ |
|---|
| 1884 | 1831 | .driver_info = NO_UNION_NORMAL, /* has misplaced union descriptor */ |
|---|
| 1885 | 1832 | }, |
|---|
| 1833 | + { USB_DEVICE(0x0c26, 0x0020), /* Icom ICF3400 Serie */ |
|---|
| 1834 | + .driver_info = NO_UNION_NORMAL, /* reports zero length descriptor */ |
|---|
| 1835 | + }, |
|---|
| 1886 | 1836 | { USB_DEVICE(0x0ca6, 0xa050), /* Castles VEGA3000 */ |
|---|
| 1887 | 1837 | .driver_info = NO_UNION_NORMAL, /* reports zero length descriptor */ |
|---|
| 1888 | 1838 | }, |
|---|
| .. | .. |
|---|
| 1960 | 1910 | |
|---|
| 1961 | 1911 | /* NOTE: non-Nokia COMM/ACM/0xff is likely MSFT RNDIS... NOT a modem! */ |
|---|
| 1962 | 1912 | |
|---|
| 1963 | | - /* Support for Droids MuIn LCD */ |
|---|
| 1964 | | - { USB_DEVICE(0x04d8, 0x000b), |
|---|
| 1965 | | - .driver_info = NO_DATA_INTERFACE, |
|---|
| 1966 | | - }, |
|---|
| 1967 | | - |
|---|
| 1968 | 1913 | #if IS_ENABLED(CONFIG_INPUT_IMS_PCU) |
|---|
| 1969 | 1914 | { USB_DEVICE(0x04d8, 0x0082), /* Application mode */ |
|---|
| 1970 | 1915 | .driver_info = IGNORE_DEVICE, |
|---|
| 1971 | 1916 | }, |
|---|
| 1972 | 1917 | { USB_DEVICE(0x04d8, 0x0083), /* Bootloader mode */ |
|---|
| 1918 | + .driver_info = IGNORE_DEVICE, |
|---|
| 1919 | + }, |
|---|
| 1920 | +#endif |
|---|
| 1921 | + |
|---|
| 1922 | +#if IS_ENABLED(CONFIG_IR_TOY) |
|---|
| 1923 | + { USB_DEVICE(0x04d8, 0xfd08), |
|---|
| 1973 | 1924 | .driver_info = IGNORE_DEVICE, |
|---|
| 1974 | 1925 | }, |
|---|
| 1975 | 1926 | |
|---|
| .. | .. |
|---|
| 2080 | 2031 | .set_termios = acm_tty_set_termios, |
|---|
| 2081 | 2032 | .tiocmget = acm_tty_tiocmget, |
|---|
| 2082 | 2033 | .tiocmset = acm_tty_tiocmset, |
|---|
| 2034 | + .get_serial = get_serial_info, |
|---|
| 2035 | + .set_serial = set_serial_info, |
|---|
| 2083 | 2036 | .get_icount = acm_tty_get_icount, |
|---|
| 2084 | 2037 | }; |
|---|
| 2085 | 2038 | |
|---|