^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) USB Driver for Sierra Wireless
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) Copyright (C) 2006, 2007, 2008 Kevin Lloyd <klloyd@sierrawireless.com>,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) Copyright (C) 2008, 2009 Elina Pasheva, Matthew Safar, Rory Filer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) <linux@sierrawireless.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) IMPORTANT DISCLAIMER: This driver is not commercially supported by
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) Sierra Wireless. Use at your own risk.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) Portions based on the option driver by Matthias Urlichs <smurf@smurf.noris.de>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) Whom based his on the Keyspan driver by Hugh Blemings <hugh@blemings.org>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) /* Uncomment to log function calls */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) /* #define DEBUG */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #define DRIVER_AUTHOR "Kevin Lloyd, Elina Pasheva, Matthew Safar, Rory Filer"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #define DRIVER_DESC "USB Driver for Sierra Wireless USB modems"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) #include <linux/jiffies.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) #include <linux/errno.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) #include <linux/tty.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) #include <linux/tty_flip.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) #include <linux/usb.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) #include <linux/usb/serial.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) #define SWIMS_USB_REQUEST_SetPower 0x00
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) #define SWIMS_USB_REQUEST_SetNmea 0x07
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) #define N_IN_URB_HM 8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) #define N_OUT_URB_HM 64
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) #define N_IN_URB 4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) #define N_OUT_URB 4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) #define IN_BUFLEN 4096
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) #define MAX_TRANSFER (PAGE_SIZE - 512)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) /* MAX_TRANSFER is chosen so that the VM is not stressed by
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) allocations > PAGE_SIZE and the number of packets in a page
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) is an integer 512 is the largest possible packet on EHCI */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) static bool nmea;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) struct sierra_iface_list {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) const u8 *nums; /* array of interface numbers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) size_t count; /* number of elements in array */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) struct sierra_intf_private {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) spinlock_t susp_lock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) unsigned int suspended:1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) int in_flight;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) unsigned int open_ports;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) static int sierra_set_power_state(struct usb_device *udev, __u16 swiState)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) return usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) SWIMS_USB_REQUEST_SetPower, /* __u8 request */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) USB_TYPE_VENDOR, /* __u8 request type */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) swiState, /* __u16 value */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) 0, /* __u16 index */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) NULL, /* void *data */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) 0, /* __u16 size */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) USB_CTRL_SET_TIMEOUT); /* int timeout */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) static int sierra_vsc_set_nmea(struct usb_device *udev, __u16 enable)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) return usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) SWIMS_USB_REQUEST_SetNmea, /* __u8 request */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) USB_TYPE_VENDOR, /* __u8 request type */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) enable, /* __u16 value */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) 0x0000, /* __u16 index */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) NULL, /* void *data */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) 0, /* __u16 size */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) USB_CTRL_SET_TIMEOUT); /* int timeout */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) static int sierra_calc_num_ports(struct usb_serial *serial,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) struct usb_serial_endpoints *epds)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) int num_ports = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) u8 ifnum, numendpoints;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) ifnum = serial->interface->cur_altsetting->desc.bInterfaceNumber;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) numendpoints = serial->interface->cur_altsetting->desc.bNumEndpoints;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) /* Dummy interface present on some SKUs should be ignored */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) if (ifnum == 0x99)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) num_ports = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) else if (numendpoints <= 3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) num_ports = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) num_ports = (numendpoints-1)/2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) return num_ports;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) static bool is_listed(const u8 ifnum, const struct sierra_iface_list *list)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) if (!list)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) for (i = 0; i < list->count; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) if (list->nums[i] == ifnum)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) static u8 sierra_interface_num(struct usb_serial *serial)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) return serial->interface->cur_altsetting->desc.bInterfaceNumber;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) static int sierra_probe(struct usb_serial *serial,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) const struct usb_device_id *id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) const struct sierra_iface_list *ignore_list;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) int result = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) struct usb_device *udev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) u8 ifnum;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) udev = serial->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) ifnum = sierra_interface_num(serial);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) * If this interface supports more than 1 alternate
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) * select the 2nd one
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) if (serial->interface->num_altsetting == 2) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) dev_dbg(&udev->dev, "Selecting alt setting for interface %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) ifnum);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) /* We know the alternate setting is 1 for the MC8785 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) usb_set_interface(udev, ifnum, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) ignore_list = (const struct sierra_iface_list *)id->driver_info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) if (is_listed(ifnum, ignore_list)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) dev_dbg(&serial->dev->dev, "Ignoring interface #%d\n", ifnum);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) return result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) /* interfaces with higher memory requirements */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) static const u8 hi_memory_typeA_ifaces[] = { 0, 2 };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) static const struct sierra_iface_list typeA_interface_list = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) .nums = hi_memory_typeA_ifaces,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) .count = ARRAY_SIZE(hi_memory_typeA_ifaces),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) static const u8 hi_memory_typeB_ifaces[] = { 3, 4, 5, 6 };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) static const struct sierra_iface_list typeB_interface_list = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) .nums = hi_memory_typeB_ifaces,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) .count = ARRAY_SIZE(hi_memory_typeB_ifaces),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) /* 'ignorelist' of interfaces not served by this driver */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) static const u8 direct_ip_non_serial_ifaces[] = { 7, 8, 9, 10, 11, 19, 20 };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) static const struct sierra_iface_list direct_ip_interface_ignore = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) .nums = direct_ip_non_serial_ifaces,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) .count = ARRAY_SIZE(direct_ip_non_serial_ifaces),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) static const struct usb_device_id id_table[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) { USB_DEVICE(0x0F3D, 0x0112) }, /* Airprime/Sierra PC 5220 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) { USB_DEVICE(0x03F0, 0x1B1D) }, /* HP ev2200 a.k.a MC5720 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) { USB_DEVICE(0x03F0, 0x211D) }, /* HP ev2210 a.k.a MC5725 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) { USB_DEVICE(0x03F0, 0x1E1D) }, /* HP hs2300 a.k.a MC8775 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) { USB_DEVICE(0x1199, 0x0017) }, /* Sierra Wireless EM5625 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) { USB_DEVICE(0x1199, 0x0018) }, /* Sierra Wireless MC5720 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) { USB_DEVICE(0x1199, 0x0218) }, /* Sierra Wireless MC5720 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) { USB_DEVICE(0x1199, 0x0020) }, /* Sierra Wireless MC5725 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) { USB_DEVICE(0x1199, 0x0220) }, /* Sierra Wireless MC5725 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) { USB_DEVICE(0x1199, 0x0022) }, /* Sierra Wireless EM5725 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) { USB_DEVICE(0x1199, 0x0024) }, /* Sierra Wireless MC5727 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) { USB_DEVICE(0x1199, 0x0224) }, /* Sierra Wireless MC5727 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) { USB_DEVICE(0x1199, 0x0019) }, /* Sierra Wireless AirCard 595 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) { USB_DEVICE(0x1199, 0x0021) }, /* Sierra Wireless AirCard 597E */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) { USB_DEVICE(0x1199, 0x0112) }, /* Sierra Wireless AirCard 580 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) { USB_DEVICE(0x1199, 0x0120) }, /* Sierra Wireless USB Dongle 595U */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) { USB_DEVICE(0x1199, 0x0301) }, /* Sierra Wireless USB Dongle 250U */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) /* Sierra Wireless C597 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) { USB_DEVICE_AND_INTERFACE_INFO(0x1199, 0x0023, 0xFF, 0xFF, 0xFF) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) /* Sierra Wireless T598 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) { USB_DEVICE_AND_INTERFACE_INFO(0x1199, 0x0025, 0xFF, 0xFF, 0xFF) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) { USB_DEVICE(0x1199, 0x0026) }, /* Sierra Wireless T11 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) { USB_DEVICE(0x1199, 0x0027) }, /* Sierra Wireless AC402 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) { USB_DEVICE(0x1199, 0x0028) }, /* Sierra Wireless MC5728 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) { USB_DEVICE(0x1199, 0x0029) }, /* Sierra Wireless Device */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) { USB_DEVICE(0x1199, 0x6802) }, /* Sierra Wireless MC8755 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) { USB_DEVICE(0x1199, 0x6803) }, /* Sierra Wireless MC8765 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) { USB_DEVICE(0x1199, 0x6804) }, /* Sierra Wireless MC8755 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) { USB_DEVICE(0x1199, 0x6805) }, /* Sierra Wireless MC8765 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) { USB_DEVICE(0x1199, 0x6808) }, /* Sierra Wireless MC8755 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) { USB_DEVICE(0x1199, 0x6809) }, /* Sierra Wireless MC8765 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) { USB_DEVICE(0x1199, 0x6812) }, /* Sierra Wireless MC8775 & AC 875U */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) { USB_DEVICE(0x1199, 0x6813) }, /* Sierra Wireless MC8775 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) { USB_DEVICE(0x1199, 0x6815) }, /* Sierra Wireless MC8775 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) { USB_DEVICE(0x1199, 0x6816) }, /* Sierra Wireless MC8775 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) { USB_DEVICE(0x1199, 0x6820) }, /* Sierra Wireless AirCard 875 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) { USB_DEVICE(0x1199, 0x6821) }, /* Sierra Wireless AirCard 875U */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) { USB_DEVICE(0x1199, 0x6822) }, /* Sierra Wireless AirCard 875E */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) { USB_DEVICE(0x1199, 0x6832) }, /* Sierra Wireless MC8780 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) { USB_DEVICE(0x1199, 0x6833) }, /* Sierra Wireless MC8781 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) { USB_DEVICE(0x1199, 0x6834) }, /* Sierra Wireless MC8780 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) { USB_DEVICE(0x1199, 0x6835) }, /* Sierra Wireless MC8781 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) { USB_DEVICE(0x1199, 0x6838) }, /* Sierra Wireless MC8780 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) { USB_DEVICE(0x1199, 0x6839) }, /* Sierra Wireless MC8781 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) { USB_DEVICE(0x1199, 0x683A) }, /* Sierra Wireless MC8785 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) { USB_DEVICE(0x1199, 0x683B) }, /* Sierra Wireless MC8785 Composite */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) /* Sierra Wireless MC8790, MC8791, MC8792 Composite */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) { USB_DEVICE(0x1199, 0x683C) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) { USB_DEVICE(0x1199, 0x683D) }, /* Sierra Wireless MC8791 Composite */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) /* Sierra Wireless MC8790, MC8791, MC8792 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) { USB_DEVICE(0x1199, 0x683E) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) { USB_DEVICE(0x1199, 0x6850) }, /* Sierra Wireless AirCard 880 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) { USB_DEVICE(0x1199, 0x6851) }, /* Sierra Wireless AirCard 881 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) { USB_DEVICE(0x1199, 0x6852) }, /* Sierra Wireless AirCard 880 E */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) { USB_DEVICE(0x1199, 0x6853) }, /* Sierra Wireless AirCard 881 E */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) { USB_DEVICE(0x1199, 0x6855) }, /* Sierra Wireless AirCard 880 U */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) { USB_DEVICE(0x1199, 0x6856) }, /* Sierra Wireless AirCard 881 U */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) { USB_DEVICE(0x1199, 0x6859) }, /* Sierra Wireless AirCard 885 E */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) { USB_DEVICE(0x1199, 0x685A) }, /* Sierra Wireless AirCard 885 E */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) /* Sierra Wireless C885 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) { USB_DEVICE_AND_INTERFACE_INFO(0x1199, 0x6880, 0xFF, 0xFF, 0xFF)},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) /* Sierra Wireless C888, Air Card 501, USB 303, USB 304 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) { USB_DEVICE_AND_INTERFACE_INFO(0x1199, 0x6890, 0xFF, 0xFF, 0xFF)},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) /* Sierra Wireless C22/C33 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) { USB_DEVICE_AND_INTERFACE_INFO(0x1199, 0x6891, 0xFF, 0xFF, 0xFF)},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) /* Sierra Wireless HSPA Non-Composite Device */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) { USB_DEVICE_AND_INTERFACE_INFO(0x1199, 0x6892, 0xFF, 0xFF, 0xFF)},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) { USB_DEVICE(0x1199, 0x6893) }, /* Sierra Wireless Device */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) /* Sierra Wireless Direct IP modems */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) { USB_DEVICE_AND_INTERFACE_INFO(0x1199, 0x68A3, 0xFF, 0xFF, 0xFF),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) .driver_info = (kernel_ulong_t)&direct_ip_interface_ignore
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) { USB_DEVICE_AND_INTERFACE_INFO(0x1199, 0x68AA, 0xFF, 0xFF, 0xFF),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) .driver_info = (kernel_ulong_t)&direct_ip_interface_ignore
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) { USB_DEVICE(0x1199, 0x68AB) }, /* Sierra Wireless AR8550 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) /* AT&T Direct IP LTE modems */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) { USB_DEVICE_AND_INTERFACE_INFO(0x0F3D, 0x68AA, 0xFF, 0xFF, 0xFF),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) .driver_info = (kernel_ulong_t)&direct_ip_interface_ignore
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) /* Airprime/Sierra Wireless Direct IP modems */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) { USB_DEVICE_AND_INTERFACE_INFO(0x0F3D, 0x68A3, 0xFF, 0xFF, 0xFF),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) .driver_info = (kernel_ulong_t)&direct_ip_interface_ignore
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) { }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) MODULE_DEVICE_TABLE(usb, id_table);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) struct sierra_port_private {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) spinlock_t lock; /* lock the structure */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) int outstanding_urbs; /* number of out urbs in flight */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) struct usb_anchor active;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) struct usb_anchor delayed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) int num_out_urbs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) int num_in_urbs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) /* Input endpoints and buffers for this port */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) struct urb *in_urbs[N_IN_URB_HM];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) /* Settings for the port */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) int rts_state; /* Handshaking pins (outputs) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) int dtr_state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) int cts_state; /* Handshaking pins (inputs) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) int dsr_state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) int dcd_state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) int ri_state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) static int sierra_send_setup(struct usb_serial_port *port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) struct usb_serial *serial = port->serial;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) struct sierra_port_private *portdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) __u16 interface = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) int val = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) int do_send = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) int retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) portdata = usb_get_serial_port_data(port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) if (portdata->dtr_state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) val |= 0x01;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) if (portdata->rts_state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) val |= 0x02;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) /* If composite device then properly report interface */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) if (serial->num_ports == 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) interface = sierra_interface_num(serial);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) /* Control message is sent only to interfaces with
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) * interrupt_in endpoints
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) if (port->interrupt_in_urb) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) /* send control message */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) do_send = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) /* Otherwise the need to do non-composite mapping */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) if (port->bulk_out_endpointAddress == 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) interface = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) else if (port->bulk_out_endpointAddress == 4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) interface = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) else if (port->bulk_out_endpointAddress == 5)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) interface = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) do_send = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) if (!do_send)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) retval = usb_autopm_get_interface(serial->interface);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) if (retval < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) return retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) retval = usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) 0x22, 0x21, val, interface, NULL, 0, USB_CTRL_SET_TIMEOUT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) usb_autopm_put_interface(serial->interface);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) return retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) static int sierra_tiocmget(struct tty_struct *tty)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) struct usb_serial_port *port = tty->driver_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) unsigned int value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) struct sierra_port_private *portdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) portdata = usb_get_serial_port_data(port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) value = ((portdata->rts_state) ? TIOCM_RTS : 0) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) ((portdata->dtr_state) ? TIOCM_DTR : 0) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) ((portdata->cts_state) ? TIOCM_CTS : 0) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) ((portdata->dsr_state) ? TIOCM_DSR : 0) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) ((portdata->dcd_state) ? TIOCM_CAR : 0) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) ((portdata->ri_state) ? TIOCM_RNG : 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) return value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) static int sierra_tiocmset(struct tty_struct *tty,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) unsigned int set, unsigned int clear)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) struct usb_serial_port *port = tty->driver_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) struct sierra_port_private *portdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) portdata = usb_get_serial_port_data(port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) if (set & TIOCM_RTS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) portdata->rts_state = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) if (set & TIOCM_DTR)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) portdata->dtr_state = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) if (clear & TIOCM_RTS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) portdata->rts_state = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) if (clear & TIOCM_DTR)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) portdata->dtr_state = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) return sierra_send_setup(port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) static void sierra_release_urb(struct urb *urb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) if (urb) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) kfree(urb->transfer_buffer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) usb_free_urb(urb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) static void sierra_outdat_callback(struct urb *urb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) struct usb_serial_port *port = urb->context;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) struct sierra_port_private *portdata = usb_get_serial_port_data(port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) struct sierra_intf_private *intfdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) int status = urb->status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) intfdata = usb_get_serial_data(port->serial);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) /* free up the transfer buffer, as usb_free_urb() does not do this */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) kfree(urb->transfer_buffer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) usb_autopm_put_interface_async(port->serial->interface);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) if (status)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) dev_dbg(&port->dev, "%s - nonzero write bulk status "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) "received: %d\n", __func__, status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) spin_lock_irqsave(&portdata->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) --portdata->outstanding_urbs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) spin_unlock_irqrestore(&portdata->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) spin_lock_irqsave(&intfdata->susp_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) --intfdata->in_flight;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) spin_unlock_irqrestore(&intfdata->susp_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) usb_serial_port_softint(port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) /* Write */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) static int sierra_write(struct tty_struct *tty, struct usb_serial_port *port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) const unsigned char *buf, int count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) struct sierra_port_private *portdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) struct sierra_intf_private *intfdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) struct usb_serial *serial = port->serial;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) unsigned char *buffer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) struct urb *urb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) size_t writesize = min((size_t)count, (size_t)MAX_TRANSFER);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) int retval = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) /* verify that we actually have some data to write */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) if (count == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) portdata = usb_get_serial_port_data(port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) intfdata = usb_get_serial_data(serial);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) dev_dbg(&port->dev, "%s: write (%zd bytes)\n", __func__, writesize);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) spin_lock_irqsave(&portdata->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) dev_dbg(&port->dev, "%s - outstanding_urbs: %d\n", __func__,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) portdata->outstanding_urbs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) if (portdata->outstanding_urbs > portdata->num_out_urbs) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) spin_unlock_irqrestore(&portdata->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) dev_dbg(&port->dev, "%s - write limit hit\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) portdata->outstanding_urbs++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) dev_dbg(&port->dev, "%s - 1, outstanding_urbs: %d\n", __func__,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) portdata->outstanding_urbs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) spin_unlock_irqrestore(&portdata->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) retval = usb_autopm_get_interface_async(serial->interface);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) if (retval < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) spin_lock_irqsave(&portdata->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) portdata->outstanding_urbs--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) spin_unlock_irqrestore(&portdata->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) goto error_simple;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) buffer = kmalloc(writesize, GFP_ATOMIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) if (!buffer) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) retval = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) goto error_no_buffer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) urb = usb_alloc_urb(0, GFP_ATOMIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) if (!urb) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) retval = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) goto error_no_urb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) memcpy(buffer, buf, writesize);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) usb_serial_debug_data(&port->dev, __func__, writesize, buffer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) usb_fill_bulk_urb(urb, serial->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) usb_sndbulkpipe(serial->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) port->bulk_out_endpointAddress),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) buffer, writesize, sierra_outdat_callback, port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) /* Handle the need to send a zero length packet */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) urb->transfer_flags |= URB_ZERO_PACKET;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) spin_lock_irqsave(&intfdata->susp_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) if (intfdata->suspended) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) usb_anchor_urb(urb, &portdata->delayed);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) spin_unlock_irqrestore(&intfdata->susp_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) goto skip_power;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) usb_anchor_urb(urb, &portdata->active);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) /* send it down the pipe */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) retval = usb_submit_urb(urb, GFP_ATOMIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) if (retval) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) usb_unanchor_urb(urb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) spin_unlock_irqrestore(&intfdata->susp_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) dev_err(&port->dev, "%s - usb_submit_urb(write bulk) failed "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) "with status = %d\n", __func__, retval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) intfdata->in_flight++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) spin_unlock_irqrestore(&intfdata->susp_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) skip_power:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) /* we are done with this urb, so let the host driver
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) * really free it when it is finished with it */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) usb_free_urb(urb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) return writesize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) error:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) usb_free_urb(urb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) error_no_urb:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) kfree(buffer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) error_no_buffer:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) spin_lock_irqsave(&portdata->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) --portdata->outstanding_urbs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) dev_dbg(&port->dev, "%s - 2. outstanding_urbs: %d\n", __func__,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) portdata->outstanding_urbs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) spin_unlock_irqrestore(&portdata->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) usb_autopm_put_interface_async(serial->interface);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) error_simple:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) return retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) static void sierra_indat_callback(struct urb *urb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) int endpoint;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) struct usb_serial_port *port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) unsigned char *data = urb->transfer_buffer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) int status = urb->status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) endpoint = usb_pipeendpoint(urb->pipe);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) port = urb->context;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) if (status) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) dev_dbg(&port->dev, "%s: nonzero status: %d on"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) " endpoint %02x\n", __func__, status, endpoint);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) if (urb->actual_length) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) tty_insert_flip_string(&port->port, data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) urb->actual_length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) tty_flip_buffer_push(&port->port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) usb_serial_debug_data(&port->dev, __func__,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) urb->actual_length, data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) dev_dbg(&port->dev, "%s: empty read urb"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) " received\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) /* Resubmit urb so we continue receiving */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) if (status != -ESHUTDOWN && status != -EPERM) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) usb_mark_last_busy(port->serial->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) err = usb_submit_urb(urb, GFP_ATOMIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) if (err && err != -EPERM)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) dev_err(&port->dev, "resubmit read urb failed."
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) "(%d)\n", err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) static void sierra_instat_callback(struct urb *urb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) int status = urb->status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) struct usb_serial_port *port = urb->context;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) struct sierra_port_private *portdata = usb_get_serial_port_data(port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) struct usb_serial *serial = port->serial;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) dev_dbg(&port->dev, "%s: urb %p port %p has data %p\n", __func__,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) urb, port, portdata);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) if (status == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) struct usb_ctrlrequest *req_pkt = urb->transfer_buffer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) if (!req_pkt) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) dev_dbg(&port->dev, "%s: NULL req_pkt\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) if ((req_pkt->bRequestType == 0xA1) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) (req_pkt->bRequest == 0x20)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) int old_dcd_state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) unsigned char signals = *((unsigned char *)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) urb->transfer_buffer +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) sizeof(struct usb_ctrlrequest));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) dev_dbg(&port->dev, "%s: signal x%x\n", __func__,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) signals);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) old_dcd_state = portdata->dcd_state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) portdata->cts_state = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) portdata->dcd_state = ((signals & 0x01) ? 1 : 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) portdata->dsr_state = ((signals & 0x02) ? 1 : 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) portdata->ri_state = ((signals & 0x08) ? 1 : 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) if (old_dcd_state && !portdata->dcd_state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) tty_port_tty_hangup(&port->port, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) dev_dbg(&port->dev, "%s: type %x req %x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) __func__, req_pkt->bRequestType,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) req_pkt->bRequest);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) dev_dbg(&port->dev, "%s: error %d\n", __func__, status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) /* Resubmit urb so we continue receiving IRQ data */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) if (status != -ESHUTDOWN && status != -ENOENT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) usb_mark_last_busy(serial->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) err = usb_submit_urb(urb, GFP_ATOMIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) if (err && err != -EPERM)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) dev_err(&port->dev, "%s: resubmit intr urb "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) "failed. (%d)\n", __func__, err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) static int sierra_write_room(struct tty_struct *tty)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) struct usb_serial_port *port = tty->driver_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) struct sierra_port_private *portdata = usb_get_serial_port_data(port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) /* try to give a good number back based on if we have any free urbs at
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) * this point in time */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) spin_lock_irqsave(&portdata->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) if (portdata->outstanding_urbs > (portdata->num_out_urbs * 2) / 3) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) spin_unlock_irqrestore(&portdata->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) dev_dbg(&port->dev, "%s - write limit hit\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) spin_unlock_irqrestore(&portdata->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) return 2048;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) static int sierra_chars_in_buffer(struct tty_struct *tty)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) struct usb_serial_port *port = tty->driver_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) struct sierra_port_private *portdata = usb_get_serial_port_data(port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) int chars;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) /* NOTE: This overcounts somewhat. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) spin_lock_irqsave(&portdata->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) chars = portdata->outstanding_urbs * MAX_TRANSFER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) spin_unlock_irqrestore(&portdata->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) dev_dbg(&port->dev, "%s - %d\n", __func__, chars);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) return chars;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) static void sierra_stop_rx_urbs(struct usb_serial_port *port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) struct sierra_port_private *portdata = usb_get_serial_port_data(port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) for (i = 0; i < portdata->num_in_urbs; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) usb_kill_urb(portdata->in_urbs[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) usb_kill_urb(port->interrupt_in_urb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) static int sierra_submit_rx_urbs(struct usb_serial_port *port, gfp_t mem_flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) int ok_cnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) int err = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) struct urb *urb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) struct sierra_port_private *portdata = usb_get_serial_port_data(port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) ok_cnt = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) for (i = 0; i < portdata->num_in_urbs; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) urb = portdata->in_urbs[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) if (!urb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) err = usb_submit_urb(urb, mem_flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) dev_err(&port->dev, "%s: submit urb failed: %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) __func__, err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) ok_cnt++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) if (ok_cnt && port->interrupt_in_urb) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) err = usb_submit_urb(port->interrupt_in_urb, mem_flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) dev_err(&port->dev, "%s: submit intr urb failed: %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) __func__, err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) if (ok_cnt > 0) /* at least one rx urb submitted */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) static struct urb *sierra_setup_urb(struct usb_serial *serial, int endpoint,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) int dir, void *ctx, int len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) gfp_t mem_flags,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) usb_complete_t callback)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) struct urb *urb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) u8 *buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) urb = usb_alloc_urb(0, mem_flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) if (!urb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) buf = kmalloc(len, mem_flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) if (buf) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) /* Fill URB using supplied data */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) usb_fill_bulk_urb(urb, serial->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) usb_sndbulkpipe(serial->dev, endpoint) | dir,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) buf, len, callback, ctx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) dev_dbg(&serial->dev->dev, "%s %c u : %p d:%p\n", __func__,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) dir == USB_DIR_IN ? 'i' : 'o', urb, buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) sierra_release_urb(urb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) urb = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) return urb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) static void sierra_close(struct usb_serial_port *port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) struct usb_serial *serial = port->serial;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) struct sierra_port_private *portdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) struct sierra_intf_private *intfdata = usb_get_serial_data(serial);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) struct urb *urb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) portdata = usb_get_serial_port_data(port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) * Need to take susp_lock to make sure port is not already being
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) * resumed, but no need to hold it due to initialized
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742) spin_lock_irq(&intfdata->susp_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743) if (--intfdata->open_ports == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) serial->interface->needs_remote_wakeup = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) spin_unlock_irq(&intfdata->susp_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) for (;;) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) urb = usb_get_from_anchor(&portdata->delayed);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749) if (!urb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) kfree(urb->transfer_buffer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) usb_free_urb(urb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) usb_autopm_put_interface_async(serial->interface);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754) spin_lock_irq(&portdata->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) portdata->outstanding_urbs--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) spin_unlock_irq(&portdata->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) sierra_stop_rx_urbs(port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) usb_kill_anchored_urbs(&portdata->active);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) for (i = 0; i < portdata->num_in_urbs; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763) sierra_release_urb(portdata->in_urbs[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764) portdata->in_urbs[i] = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) usb_autopm_get_interface_no_resume(serial->interface);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) static int sierra_open(struct tty_struct *tty, struct usb_serial_port *port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772) struct sierra_port_private *portdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773) struct usb_serial *serial = port->serial;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774) struct sierra_intf_private *intfdata = usb_get_serial_data(serial);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) int endpoint;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) struct urb *urb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) portdata = usb_get_serial_port_data(port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782) endpoint = port->bulk_in_endpointAddress;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783) for (i = 0; i < portdata->num_in_urbs; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784) urb = sierra_setup_urb(serial, endpoint, USB_DIR_IN, port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785) IN_BUFLEN, GFP_KERNEL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786) sierra_indat_callback);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787) portdata->in_urbs[i] = urb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789) /* clear halt condition */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790) usb_clear_halt(serial->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791) usb_sndbulkpipe(serial->dev, endpoint) | USB_DIR_IN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793) err = sierra_submit_rx_urbs(port, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795) goto err_submit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797) spin_lock_irq(&intfdata->susp_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798) if (++intfdata->open_ports == 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799) serial->interface->needs_remote_wakeup = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800) spin_unlock_irq(&intfdata->susp_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801) usb_autopm_put_interface(serial->interface);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805) err_submit:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806) sierra_stop_rx_urbs(port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808) for (i = 0; i < portdata->num_in_urbs; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809) sierra_release_urb(portdata->in_urbs[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810) portdata->in_urbs[i] = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817) static void sierra_dtr_rts(struct usb_serial_port *port, int on)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819) struct sierra_port_private *portdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821) portdata = usb_get_serial_port_data(port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822) portdata->rts_state = on;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823) portdata->dtr_state = on;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825) sierra_send_setup(port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828) static int sierra_startup(struct usb_serial *serial)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830) struct sierra_intf_private *intfdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832) intfdata = kzalloc(sizeof(*intfdata), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833) if (!intfdata)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836) spin_lock_init(&intfdata->susp_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838) usb_set_serial_data(serial, intfdata);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840) /* Set Device mode to D0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841) sierra_set_power_state(serial->dev, 0x0000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843) /* Check NMEA and set */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844) if (nmea)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845) sierra_vsc_set_nmea(serial->dev, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850) static void sierra_release(struct usb_serial *serial)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852) struct sierra_intf_private *intfdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854) intfdata = usb_get_serial_data(serial);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855) kfree(intfdata);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858) static int sierra_port_probe(struct usb_serial_port *port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860) struct usb_serial *serial = port->serial;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861) struct sierra_port_private *portdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862) const struct sierra_iface_list *himemory_list;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 863) u8 ifnum;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 864)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 865) portdata = kzalloc(sizeof(*portdata), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 866) if (!portdata)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 867) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 868)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 869) spin_lock_init(&portdata->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 870) init_usb_anchor(&portdata->active);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 871) init_usb_anchor(&portdata->delayed);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 872)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 873) /* Assume low memory requirements */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 874) portdata->num_out_urbs = N_OUT_URB;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 875) portdata->num_in_urbs = N_IN_URB;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 876)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 877) /* Determine actual memory requirements */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 878) if (serial->num_ports == 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 879) /* Get interface number for composite device */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 880) ifnum = sierra_interface_num(serial);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 881) himemory_list = &typeB_interface_list;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 882) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 883) /* This is really the usb-serial port number of the interface
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 884) * rather than the interface number.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 885) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 886) ifnum = port->port_number;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 887) himemory_list = &typeA_interface_list;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 888) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 889)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 890) if (is_listed(ifnum, himemory_list)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 891) portdata->num_out_urbs = N_OUT_URB_HM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 892) portdata->num_in_urbs = N_IN_URB_HM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 893) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 894)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 895) dev_dbg(&port->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 896) "Memory usage (urbs) interface #%d, in=%d, out=%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 897) ifnum, portdata->num_in_urbs, portdata->num_out_urbs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 898)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 899) usb_set_serial_port_data(port, portdata);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 900)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 901) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 902) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 903)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 904) static int sierra_port_remove(struct usb_serial_port *port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 905) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 906) struct sierra_port_private *portdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 907)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 908) portdata = usb_get_serial_port_data(port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 909) usb_set_serial_port_data(port, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 910) kfree(portdata);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 911)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 912) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 913) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 914)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 915) #ifdef CONFIG_PM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 916) static void stop_read_write_urbs(struct usb_serial *serial)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 917) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 918) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 919) struct usb_serial_port *port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 920) struct sierra_port_private *portdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 921)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 922) /* Stop reading/writing urbs */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 923) for (i = 0; i < serial->num_ports; ++i) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 924) port = serial->port[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 925) portdata = usb_get_serial_port_data(port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 926) if (!portdata)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 927) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 928) sierra_stop_rx_urbs(port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 929) usb_kill_anchored_urbs(&portdata->active);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 930) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 931) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 932)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 933) static int sierra_suspend(struct usb_serial *serial, pm_message_t message)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 934) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 935) struct sierra_intf_private *intfdata = usb_get_serial_data(serial);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 936)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 937) spin_lock_irq(&intfdata->susp_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 938) if (PMSG_IS_AUTO(message)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 939) if (intfdata->in_flight) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 940) spin_unlock_irq(&intfdata->susp_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 941) return -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 942) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 943) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 944) intfdata->suspended = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 945) spin_unlock_irq(&intfdata->susp_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 946)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 947) stop_read_write_urbs(serial);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 948)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 949) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 950) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 951)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 952) /* Caller must hold susp_lock. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 953) static int sierra_submit_delayed_urbs(struct usb_serial_port *port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 954) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 955) struct sierra_port_private *portdata = usb_get_serial_port_data(port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 956) struct sierra_intf_private *intfdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 957) struct urb *urb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 958) int ec = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 959) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 960)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 961) intfdata = usb_get_serial_data(port->serial);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 962)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 963) for (;;) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 964) urb = usb_get_from_anchor(&portdata->delayed);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 965) if (!urb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 966) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 967)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 968) usb_anchor_urb(urb, &portdata->active);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 969) intfdata->in_flight++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 970) err = usb_submit_urb(urb, GFP_ATOMIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 971) if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 972) dev_err(&port->dev, "%s - submit urb failed: %d",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 973) __func__, err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 974) ec++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 975) intfdata->in_flight--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 976) usb_unanchor_urb(urb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 977) kfree(urb->transfer_buffer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 978) usb_free_urb(urb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 979)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 980) spin_lock(&portdata->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 981) portdata->outstanding_urbs--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 982) spin_unlock(&portdata->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 983) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 984) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 985)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 986) if (ec)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 987) return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 988)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 989) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 990) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 991)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 992) static int sierra_resume(struct usb_serial *serial)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 993) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 994) struct usb_serial_port *port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 995) struct sierra_intf_private *intfdata = usb_get_serial_data(serial);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 996) int ec = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 997) int i, err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 998)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 999) spin_lock_irq(&intfdata->susp_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000) for (i = 0; i < serial->num_ports; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001) port = serial->port[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003) if (!tty_port_initialized(&port->port))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006) err = sierra_submit_delayed_urbs(port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008) ec++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010) err = sierra_submit_rx_urbs(port, GFP_ATOMIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012) ec++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014) intfdata->suspended = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015) spin_unlock_irq(&intfdata->susp_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017) return ec ? -EIO : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021) #define sierra_suspend NULL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022) #define sierra_resume NULL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025) static struct usb_serial_driver sierra_device = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026) .driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027) .owner = THIS_MODULE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028) .name = "sierra",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030) .description = "Sierra USB modem",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031) .id_table = id_table,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1032) .calc_num_ports = sierra_calc_num_ports,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033) .probe = sierra_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034) .open = sierra_open,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1035) .close = sierra_close,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036) .dtr_rts = sierra_dtr_rts,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037) .write = sierra_write,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038) .write_room = sierra_write_room,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1039) .chars_in_buffer = sierra_chars_in_buffer,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1040) .tiocmget = sierra_tiocmget,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1041) .tiocmset = sierra_tiocmset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1042) .attach = sierra_startup,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1043) .release = sierra_release,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1044) .port_probe = sierra_port_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1045) .port_remove = sierra_port_remove,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1046) .suspend = sierra_suspend,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1047) .resume = sierra_resume,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1048) .read_int_callback = sierra_instat_callback,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1049) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1050)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1051) static struct usb_serial_driver * const serial_drivers[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1052) &sierra_device, NULL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1053) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1054)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1055) module_usb_serial_driver(serial_drivers, id_table);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1056)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1057) MODULE_AUTHOR(DRIVER_AUTHOR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1058) MODULE_DESCRIPTION(DRIVER_DESC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1059) MODULE_LICENSE("GPL v2");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1060)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1061) module_param(nmea, bool, S_IRUGO | S_IWUSR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1062) MODULE_PARM_DESC(nmea, "NMEA streaming");