xref: /OK3568_Linux_fs/kernel/drivers/usb/class/usbtmc.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun // SPDX-License-Identifier: GPL-2.0+
2*4882a593Smuzhiyun /*
3*4882a593Smuzhiyun  * drivers/usb/class/usbtmc.c - USB Test & Measurement class driver
4*4882a593Smuzhiyun  *
5*4882a593Smuzhiyun  * Copyright (C) 2007 Stefan Kopp, Gechingen, Germany
6*4882a593Smuzhiyun  * Copyright (C) 2008 Novell, Inc.
7*4882a593Smuzhiyun  * Copyright (C) 2008 Greg Kroah-Hartman <gregkh@suse.de>
8*4882a593Smuzhiyun  * Copyright (C) 2018 IVI Foundation, Inc.
9*4882a593Smuzhiyun  */
10*4882a593Smuzhiyun 
11*4882a593Smuzhiyun #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
12*4882a593Smuzhiyun 
13*4882a593Smuzhiyun #include <linux/module.h>
14*4882a593Smuzhiyun #include <linux/kernel.h>
15*4882a593Smuzhiyun #include <linux/fs.h>
16*4882a593Smuzhiyun #include <linux/uaccess.h>
17*4882a593Smuzhiyun #include <linux/kref.h>
18*4882a593Smuzhiyun #include <linux/slab.h>
19*4882a593Smuzhiyun #include <linux/poll.h>
20*4882a593Smuzhiyun #include <linux/mutex.h>
21*4882a593Smuzhiyun #include <linux/usb.h>
22*4882a593Smuzhiyun #include <linux/compat.h>
23*4882a593Smuzhiyun #include <linux/usb/tmc.h>
24*4882a593Smuzhiyun 
25*4882a593Smuzhiyun /* Increment API VERSION when changing tmc.h with new flags or ioctls
26*4882a593Smuzhiyun  * or when changing a significant behavior of the driver.
27*4882a593Smuzhiyun  */
28*4882a593Smuzhiyun #define USBTMC_API_VERSION (2)
29*4882a593Smuzhiyun 
30*4882a593Smuzhiyun #define USBTMC_HEADER_SIZE	12
31*4882a593Smuzhiyun #define USBTMC_MINOR_BASE	176
32*4882a593Smuzhiyun 
33*4882a593Smuzhiyun /* Minimum USB timeout (in milliseconds) */
34*4882a593Smuzhiyun #define USBTMC_MIN_TIMEOUT	100
35*4882a593Smuzhiyun /* Default USB timeout (in milliseconds) */
36*4882a593Smuzhiyun #define USBTMC_TIMEOUT		5000
37*4882a593Smuzhiyun 
38*4882a593Smuzhiyun /* Max number of urbs used in write transfers */
39*4882a593Smuzhiyun #define MAX_URBS_IN_FLIGHT	16
40*4882a593Smuzhiyun /* I/O buffer size used in generic read/write functions */
41*4882a593Smuzhiyun #define USBTMC_BUFSIZE		(4096)
42*4882a593Smuzhiyun 
43*4882a593Smuzhiyun /*
44*4882a593Smuzhiyun  * Maximum number of read cycles to empty bulk in endpoint during CLEAR and
45*4882a593Smuzhiyun  * ABORT_BULK_IN requests. Ends the loop if (for whatever reason) a short
46*4882a593Smuzhiyun  * packet is never read.
47*4882a593Smuzhiyun  */
48*4882a593Smuzhiyun #define USBTMC_MAX_READS_TO_CLEAR_BULK_IN	100
49*4882a593Smuzhiyun 
50*4882a593Smuzhiyun static const struct usb_device_id usbtmc_devices[] = {
51*4882a593Smuzhiyun 	{ USB_INTERFACE_INFO(USB_CLASS_APP_SPEC, 3, 0), },
52*4882a593Smuzhiyun 	{ USB_INTERFACE_INFO(USB_CLASS_APP_SPEC, 3, 1), },
53*4882a593Smuzhiyun 	{ 0, } /* terminating entry */
54*4882a593Smuzhiyun };
55*4882a593Smuzhiyun MODULE_DEVICE_TABLE(usb, usbtmc_devices);
56*4882a593Smuzhiyun 
57*4882a593Smuzhiyun /*
58*4882a593Smuzhiyun  * This structure is the capabilities for the device
59*4882a593Smuzhiyun  * See section 4.2.1.8 of the USBTMC specification,
60*4882a593Smuzhiyun  * and section 4.2.2 of the USBTMC usb488 subclass
61*4882a593Smuzhiyun  * specification for details.
62*4882a593Smuzhiyun  */
63*4882a593Smuzhiyun struct usbtmc_dev_capabilities {
64*4882a593Smuzhiyun 	__u8 interface_capabilities;
65*4882a593Smuzhiyun 	__u8 device_capabilities;
66*4882a593Smuzhiyun 	__u8 usb488_interface_capabilities;
67*4882a593Smuzhiyun 	__u8 usb488_device_capabilities;
68*4882a593Smuzhiyun };
69*4882a593Smuzhiyun 
70*4882a593Smuzhiyun /* This structure holds private data for each USBTMC device. One copy is
71*4882a593Smuzhiyun  * allocated for each USBTMC device in the driver's probe function.
72*4882a593Smuzhiyun  */
73*4882a593Smuzhiyun struct usbtmc_device_data {
74*4882a593Smuzhiyun 	const struct usb_device_id *id;
75*4882a593Smuzhiyun 	struct usb_device *usb_dev;
76*4882a593Smuzhiyun 	struct usb_interface *intf;
77*4882a593Smuzhiyun 	struct list_head file_list;
78*4882a593Smuzhiyun 
79*4882a593Smuzhiyun 	unsigned int bulk_in;
80*4882a593Smuzhiyun 	unsigned int bulk_out;
81*4882a593Smuzhiyun 
82*4882a593Smuzhiyun 	u8 bTag;
83*4882a593Smuzhiyun 	u8 bTag_last_write;	/* needed for abort */
84*4882a593Smuzhiyun 	u8 bTag_last_read;	/* needed for abort */
85*4882a593Smuzhiyun 
86*4882a593Smuzhiyun 	/* packet size of IN bulk */
87*4882a593Smuzhiyun 	u16            wMaxPacketSize;
88*4882a593Smuzhiyun 
89*4882a593Smuzhiyun 	/* data for interrupt in endpoint handling */
90*4882a593Smuzhiyun 	u8             bNotify1;
91*4882a593Smuzhiyun 	u8             bNotify2;
92*4882a593Smuzhiyun 	u16            ifnum;
93*4882a593Smuzhiyun 	u8             iin_bTag;
94*4882a593Smuzhiyun 	u8            *iin_buffer;
95*4882a593Smuzhiyun 	atomic_t       iin_data_valid;
96*4882a593Smuzhiyun 	unsigned int   iin_ep;
97*4882a593Smuzhiyun 	int            iin_ep_present;
98*4882a593Smuzhiyun 	int            iin_interval;
99*4882a593Smuzhiyun 	struct urb    *iin_urb;
100*4882a593Smuzhiyun 	u16            iin_wMaxPacketSize;
101*4882a593Smuzhiyun 
102*4882a593Smuzhiyun 	/* coalesced usb488_caps from usbtmc_dev_capabilities */
103*4882a593Smuzhiyun 	__u8 usb488_caps;
104*4882a593Smuzhiyun 
105*4882a593Smuzhiyun 	bool zombie; /* fd of disconnected device */
106*4882a593Smuzhiyun 
107*4882a593Smuzhiyun 	struct usbtmc_dev_capabilities	capabilities;
108*4882a593Smuzhiyun 	struct kref kref;
109*4882a593Smuzhiyun 	struct mutex io_mutex;	/* only one i/o function running at a time */
110*4882a593Smuzhiyun 	wait_queue_head_t waitq;
111*4882a593Smuzhiyun 	struct fasync_struct *fasync;
112*4882a593Smuzhiyun 	spinlock_t dev_lock; /* lock for file_list */
113*4882a593Smuzhiyun };
114*4882a593Smuzhiyun #define to_usbtmc_data(d) container_of(d, struct usbtmc_device_data, kref)
115*4882a593Smuzhiyun 
116*4882a593Smuzhiyun /*
117*4882a593Smuzhiyun  * This structure holds private data for each USBTMC file handle.
118*4882a593Smuzhiyun  */
119*4882a593Smuzhiyun struct usbtmc_file_data {
120*4882a593Smuzhiyun 	struct usbtmc_device_data *data;
121*4882a593Smuzhiyun 	struct list_head file_elem;
122*4882a593Smuzhiyun 
123*4882a593Smuzhiyun 	u32            timeout;
124*4882a593Smuzhiyun 	u8             srq_byte;
125*4882a593Smuzhiyun 	atomic_t       srq_asserted;
126*4882a593Smuzhiyun 	atomic_t       closing;
127*4882a593Smuzhiyun 	u8             bmTransferAttributes; /* member of DEV_DEP_MSG_IN */
128*4882a593Smuzhiyun 
129*4882a593Smuzhiyun 	u8             eom_val;
130*4882a593Smuzhiyun 	u8             term_char;
131*4882a593Smuzhiyun 	bool           term_char_enabled;
132*4882a593Smuzhiyun 	bool           auto_abort;
133*4882a593Smuzhiyun 
134*4882a593Smuzhiyun 	spinlock_t     err_lock; /* lock for errors */
135*4882a593Smuzhiyun 
136*4882a593Smuzhiyun 	struct usb_anchor submitted;
137*4882a593Smuzhiyun 
138*4882a593Smuzhiyun 	/* data for generic_write */
139*4882a593Smuzhiyun 	struct semaphore limit_write_sem;
140*4882a593Smuzhiyun 	u32 out_transfer_size;
141*4882a593Smuzhiyun 	int out_status;
142*4882a593Smuzhiyun 
143*4882a593Smuzhiyun 	/* data for generic_read */
144*4882a593Smuzhiyun 	u32 in_transfer_size;
145*4882a593Smuzhiyun 	int in_status;
146*4882a593Smuzhiyun 	int in_urbs_used;
147*4882a593Smuzhiyun 	struct usb_anchor in_anchor;
148*4882a593Smuzhiyun 	wait_queue_head_t wait_bulk_in;
149*4882a593Smuzhiyun };
150*4882a593Smuzhiyun 
151*4882a593Smuzhiyun /* Forward declarations */
152*4882a593Smuzhiyun static struct usb_driver usbtmc_driver;
153*4882a593Smuzhiyun static void usbtmc_draw_down(struct usbtmc_file_data *file_data);
154*4882a593Smuzhiyun 
usbtmc_delete(struct kref * kref)155*4882a593Smuzhiyun static void usbtmc_delete(struct kref *kref)
156*4882a593Smuzhiyun {
157*4882a593Smuzhiyun 	struct usbtmc_device_data *data = to_usbtmc_data(kref);
158*4882a593Smuzhiyun 
159*4882a593Smuzhiyun 	usb_put_dev(data->usb_dev);
160*4882a593Smuzhiyun 	kfree(data);
161*4882a593Smuzhiyun }
162*4882a593Smuzhiyun 
usbtmc_open(struct inode * inode,struct file * filp)163*4882a593Smuzhiyun static int usbtmc_open(struct inode *inode, struct file *filp)
164*4882a593Smuzhiyun {
165*4882a593Smuzhiyun 	struct usb_interface *intf;
166*4882a593Smuzhiyun 	struct usbtmc_device_data *data;
167*4882a593Smuzhiyun 	struct usbtmc_file_data *file_data;
168*4882a593Smuzhiyun 
169*4882a593Smuzhiyun 	intf = usb_find_interface(&usbtmc_driver, iminor(inode));
170*4882a593Smuzhiyun 	if (!intf) {
171*4882a593Smuzhiyun 		pr_err("can not find device for minor %d", iminor(inode));
172*4882a593Smuzhiyun 		return -ENODEV;
173*4882a593Smuzhiyun 	}
174*4882a593Smuzhiyun 
175*4882a593Smuzhiyun 	file_data = kzalloc(sizeof(*file_data), GFP_KERNEL);
176*4882a593Smuzhiyun 	if (!file_data)
177*4882a593Smuzhiyun 		return -ENOMEM;
178*4882a593Smuzhiyun 
179*4882a593Smuzhiyun 	spin_lock_init(&file_data->err_lock);
180*4882a593Smuzhiyun 	sema_init(&file_data->limit_write_sem, MAX_URBS_IN_FLIGHT);
181*4882a593Smuzhiyun 	init_usb_anchor(&file_data->submitted);
182*4882a593Smuzhiyun 	init_usb_anchor(&file_data->in_anchor);
183*4882a593Smuzhiyun 	init_waitqueue_head(&file_data->wait_bulk_in);
184*4882a593Smuzhiyun 
185*4882a593Smuzhiyun 	data = usb_get_intfdata(intf);
186*4882a593Smuzhiyun 	/* Protect reference to data from file structure until release */
187*4882a593Smuzhiyun 	kref_get(&data->kref);
188*4882a593Smuzhiyun 
189*4882a593Smuzhiyun 	mutex_lock(&data->io_mutex);
190*4882a593Smuzhiyun 	file_data->data = data;
191*4882a593Smuzhiyun 
192*4882a593Smuzhiyun 	atomic_set(&file_data->closing, 0);
193*4882a593Smuzhiyun 
194*4882a593Smuzhiyun 	file_data->timeout = USBTMC_TIMEOUT;
195*4882a593Smuzhiyun 	file_data->term_char = '\n';
196*4882a593Smuzhiyun 	file_data->term_char_enabled = 0;
197*4882a593Smuzhiyun 	file_data->auto_abort = 0;
198*4882a593Smuzhiyun 	file_data->eom_val = 1;
199*4882a593Smuzhiyun 
200*4882a593Smuzhiyun 	INIT_LIST_HEAD(&file_data->file_elem);
201*4882a593Smuzhiyun 	spin_lock_irq(&data->dev_lock);
202*4882a593Smuzhiyun 	list_add_tail(&file_data->file_elem, &data->file_list);
203*4882a593Smuzhiyun 	spin_unlock_irq(&data->dev_lock);
204*4882a593Smuzhiyun 	mutex_unlock(&data->io_mutex);
205*4882a593Smuzhiyun 
206*4882a593Smuzhiyun 	/* Store pointer in file structure's private data field */
207*4882a593Smuzhiyun 	filp->private_data = file_data;
208*4882a593Smuzhiyun 
209*4882a593Smuzhiyun 	return 0;
210*4882a593Smuzhiyun }
211*4882a593Smuzhiyun 
212*4882a593Smuzhiyun /*
213*4882a593Smuzhiyun  * usbtmc_flush - called before file handle is closed
214*4882a593Smuzhiyun  */
usbtmc_flush(struct file * file,fl_owner_t id)215*4882a593Smuzhiyun static int usbtmc_flush(struct file *file, fl_owner_t id)
216*4882a593Smuzhiyun {
217*4882a593Smuzhiyun 	struct usbtmc_file_data *file_data;
218*4882a593Smuzhiyun 	struct usbtmc_device_data *data;
219*4882a593Smuzhiyun 
220*4882a593Smuzhiyun 	file_data = file->private_data;
221*4882a593Smuzhiyun 	if (file_data == NULL)
222*4882a593Smuzhiyun 		return -ENODEV;
223*4882a593Smuzhiyun 
224*4882a593Smuzhiyun 	atomic_set(&file_data->closing, 1);
225*4882a593Smuzhiyun 	data = file_data->data;
226*4882a593Smuzhiyun 
227*4882a593Smuzhiyun 	/* wait for io to stop */
228*4882a593Smuzhiyun 	mutex_lock(&data->io_mutex);
229*4882a593Smuzhiyun 
230*4882a593Smuzhiyun 	usbtmc_draw_down(file_data);
231*4882a593Smuzhiyun 
232*4882a593Smuzhiyun 	spin_lock_irq(&file_data->err_lock);
233*4882a593Smuzhiyun 	file_data->in_status = 0;
234*4882a593Smuzhiyun 	file_data->in_transfer_size = 0;
235*4882a593Smuzhiyun 	file_data->in_urbs_used = 0;
236*4882a593Smuzhiyun 	file_data->out_status = 0;
237*4882a593Smuzhiyun 	file_data->out_transfer_size = 0;
238*4882a593Smuzhiyun 	spin_unlock_irq(&file_data->err_lock);
239*4882a593Smuzhiyun 
240*4882a593Smuzhiyun 	wake_up_interruptible_all(&data->waitq);
241*4882a593Smuzhiyun 	mutex_unlock(&data->io_mutex);
242*4882a593Smuzhiyun 
243*4882a593Smuzhiyun 	return 0;
244*4882a593Smuzhiyun }
245*4882a593Smuzhiyun 
usbtmc_release(struct inode * inode,struct file * file)246*4882a593Smuzhiyun static int usbtmc_release(struct inode *inode, struct file *file)
247*4882a593Smuzhiyun {
248*4882a593Smuzhiyun 	struct usbtmc_file_data *file_data = file->private_data;
249*4882a593Smuzhiyun 
250*4882a593Smuzhiyun 	/* prevent IO _AND_ usbtmc_interrupt */
251*4882a593Smuzhiyun 	mutex_lock(&file_data->data->io_mutex);
252*4882a593Smuzhiyun 	spin_lock_irq(&file_data->data->dev_lock);
253*4882a593Smuzhiyun 
254*4882a593Smuzhiyun 	list_del(&file_data->file_elem);
255*4882a593Smuzhiyun 
256*4882a593Smuzhiyun 	spin_unlock_irq(&file_data->data->dev_lock);
257*4882a593Smuzhiyun 	mutex_unlock(&file_data->data->io_mutex);
258*4882a593Smuzhiyun 
259*4882a593Smuzhiyun 	kref_put(&file_data->data->kref, usbtmc_delete);
260*4882a593Smuzhiyun 	file_data->data = NULL;
261*4882a593Smuzhiyun 	kfree(file_data);
262*4882a593Smuzhiyun 	return 0;
263*4882a593Smuzhiyun }
264*4882a593Smuzhiyun 
usbtmc_ioctl_abort_bulk_in_tag(struct usbtmc_device_data * data,u8 tag)265*4882a593Smuzhiyun static int usbtmc_ioctl_abort_bulk_in_tag(struct usbtmc_device_data *data,
266*4882a593Smuzhiyun 					  u8 tag)
267*4882a593Smuzhiyun {
268*4882a593Smuzhiyun 	u8 *buffer;
269*4882a593Smuzhiyun 	struct device *dev;
270*4882a593Smuzhiyun 	int rv;
271*4882a593Smuzhiyun 	int n;
272*4882a593Smuzhiyun 	int actual;
273*4882a593Smuzhiyun 
274*4882a593Smuzhiyun 	dev = &data->intf->dev;
275*4882a593Smuzhiyun 	buffer = kmalloc(USBTMC_BUFSIZE, GFP_KERNEL);
276*4882a593Smuzhiyun 	if (!buffer)
277*4882a593Smuzhiyun 		return -ENOMEM;
278*4882a593Smuzhiyun 
279*4882a593Smuzhiyun 	rv = usb_control_msg(data->usb_dev,
280*4882a593Smuzhiyun 			     usb_rcvctrlpipe(data->usb_dev, 0),
281*4882a593Smuzhiyun 			     USBTMC_REQUEST_INITIATE_ABORT_BULK_IN,
282*4882a593Smuzhiyun 			     USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_ENDPOINT,
283*4882a593Smuzhiyun 			     tag, data->bulk_in,
284*4882a593Smuzhiyun 			     buffer, 2, USB_CTRL_GET_TIMEOUT);
285*4882a593Smuzhiyun 
286*4882a593Smuzhiyun 	if (rv < 0) {
287*4882a593Smuzhiyun 		dev_err(dev, "usb_control_msg returned %d\n", rv);
288*4882a593Smuzhiyun 		goto exit;
289*4882a593Smuzhiyun 	}
290*4882a593Smuzhiyun 
291*4882a593Smuzhiyun 	dev_dbg(dev, "INITIATE_ABORT_BULK_IN returned %x with tag %02x\n",
292*4882a593Smuzhiyun 		buffer[0], buffer[1]);
293*4882a593Smuzhiyun 
294*4882a593Smuzhiyun 	if (buffer[0] == USBTMC_STATUS_FAILED) {
295*4882a593Smuzhiyun 		/* No transfer in progress and the Bulk-OUT FIFO is empty. */
296*4882a593Smuzhiyun 		rv = 0;
297*4882a593Smuzhiyun 		goto exit;
298*4882a593Smuzhiyun 	}
299*4882a593Smuzhiyun 
300*4882a593Smuzhiyun 	if (buffer[0] == USBTMC_STATUS_TRANSFER_NOT_IN_PROGRESS) {
301*4882a593Smuzhiyun 		/* The device returns this status if either:
302*4882a593Smuzhiyun 		 * - There is a transfer in progress, but the specified bTag
303*4882a593Smuzhiyun 		 *   does not match.
304*4882a593Smuzhiyun 		 * - There is no transfer in progress, but the Bulk-OUT FIFO
305*4882a593Smuzhiyun 		 *   is not empty.
306*4882a593Smuzhiyun 		 */
307*4882a593Smuzhiyun 		rv = -ENOMSG;
308*4882a593Smuzhiyun 		goto exit;
309*4882a593Smuzhiyun 	}
310*4882a593Smuzhiyun 
311*4882a593Smuzhiyun 	if (buffer[0] != USBTMC_STATUS_SUCCESS) {
312*4882a593Smuzhiyun 		dev_err(dev, "INITIATE_ABORT_BULK_IN returned %x\n",
313*4882a593Smuzhiyun 			buffer[0]);
314*4882a593Smuzhiyun 		rv = -EPERM;
315*4882a593Smuzhiyun 		goto exit;
316*4882a593Smuzhiyun 	}
317*4882a593Smuzhiyun 
318*4882a593Smuzhiyun 	n = 0;
319*4882a593Smuzhiyun 
320*4882a593Smuzhiyun usbtmc_abort_bulk_in_status:
321*4882a593Smuzhiyun 	dev_dbg(dev, "Reading from bulk in EP\n");
322*4882a593Smuzhiyun 
323*4882a593Smuzhiyun 	/* Data must be present. So use low timeout 300 ms */
324*4882a593Smuzhiyun 	actual = 0;
325*4882a593Smuzhiyun 	rv = usb_bulk_msg(data->usb_dev,
326*4882a593Smuzhiyun 			  usb_rcvbulkpipe(data->usb_dev,
327*4882a593Smuzhiyun 					  data->bulk_in),
328*4882a593Smuzhiyun 			  buffer, USBTMC_BUFSIZE,
329*4882a593Smuzhiyun 			  &actual, 300);
330*4882a593Smuzhiyun 
331*4882a593Smuzhiyun 	print_hex_dump_debug("usbtmc ", DUMP_PREFIX_NONE, 16, 1,
332*4882a593Smuzhiyun 			     buffer, actual, true);
333*4882a593Smuzhiyun 
334*4882a593Smuzhiyun 	n++;
335*4882a593Smuzhiyun 
336*4882a593Smuzhiyun 	if (rv < 0) {
337*4882a593Smuzhiyun 		dev_err(dev, "usb_bulk_msg returned %d\n", rv);
338*4882a593Smuzhiyun 		if (rv != -ETIMEDOUT)
339*4882a593Smuzhiyun 			goto exit;
340*4882a593Smuzhiyun 	}
341*4882a593Smuzhiyun 
342*4882a593Smuzhiyun 	if (actual == USBTMC_BUFSIZE)
343*4882a593Smuzhiyun 		goto usbtmc_abort_bulk_in_status;
344*4882a593Smuzhiyun 
345*4882a593Smuzhiyun 	if (n >= USBTMC_MAX_READS_TO_CLEAR_BULK_IN) {
346*4882a593Smuzhiyun 		dev_err(dev, "Couldn't clear device buffer within %d cycles\n",
347*4882a593Smuzhiyun 			USBTMC_MAX_READS_TO_CLEAR_BULK_IN);
348*4882a593Smuzhiyun 		rv = -EPERM;
349*4882a593Smuzhiyun 		goto exit;
350*4882a593Smuzhiyun 	}
351*4882a593Smuzhiyun 
352*4882a593Smuzhiyun 	rv = usb_control_msg(data->usb_dev,
353*4882a593Smuzhiyun 			     usb_rcvctrlpipe(data->usb_dev, 0),
354*4882a593Smuzhiyun 			     USBTMC_REQUEST_CHECK_ABORT_BULK_IN_STATUS,
355*4882a593Smuzhiyun 			     USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_ENDPOINT,
356*4882a593Smuzhiyun 			     0, data->bulk_in, buffer, 0x08,
357*4882a593Smuzhiyun 			     USB_CTRL_GET_TIMEOUT);
358*4882a593Smuzhiyun 
359*4882a593Smuzhiyun 	if (rv < 0) {
360*4882a593Smuzhiyun 		dev_err(dev, "usb_control_msg returned %d\n", rv);
361*4882a593Smuzhiyun 		goto exit;
362*4882a593Smuzhiyun 	}
363*4882a593Smuzhiyun 
364*4882a593Smuzhiyun 	dev_dbg(dev, "CHECK_ABORT_BULK_IN returned %x\n", buffer[0]);
365*4882a593Smuzhiyun 
366*4882a593Smuzhiyun 	if (buffer[0] == USBTMC_STATUS_SUCCESS) {
367*4882a593Smuzhiyun 		rv = 0;
368*4882a593Smuzhiyun 		goto exit;
369*4882a593Smuzhiyun 	}
370*4882a593Smuzhiyun 
371*4882a593Smuzhiyun 	if (buffer[0] != USBTMC_STATUS_PENDING) {
372*4882a593Smuzhiyun 		dev_err(dev, "CHECK_ABORT_BULK_IN returned %x\n", buffer[0]);
373*4882a593Smuzhiyun 		rv = -EPERM;
374*4882a593Smuzhiyun 		goto exit;
375*4882a593Smuzhiyun 	}
376*4882a593Smuzhiyun 
377*4882a593Smuzhiyun 	if ((buffer[1] & 1) > 0) {
378*4882a593Smuzhiyun 		/* The device has 1 or more queued packets the Host can read */
379*4882a593Smuzhiyun 		goto usbtmc_abort_bulk_in_status;
380*4882a593Smuzhiyun 	}
381*4882a593Smuzhiyun 
382*4882a593Smuzhiyun 	/* The Host must send CHECK_ABORT_BULK_IN_STATUS at a later time. */
383*4882a593Smuzhiyun 	rv = -EAGAIN;
384*4882a593Smuzhiyun exit:
385*4882a593Smuzhiyun 	kfree(buffer);
386*4882a593Smuzhiyun 	return rv;
387*4882a593Smuzhiyun }
388*4882a593Smuzhiyun 
usbtmc_ioctl_abort_bulk_in(struct usbtmc_device_data * data)389*4882a593Smuzhiyun static int usbtmc_ioctl_abort_bulk_in(struct usbtmc_device_data *data)
390*4882a593Smuzhiyun {
391*4882a593Smuzhiyun 	return usbtmc_ioctl_abort_bulk_in_tag(data, data->bTag_last_read);
392*4882a593Smuzhiyun }
393*4882a593Smuzhiyun 
usbtmc_ioctl_abort_bulk_out_tag(struct usbtmc_device_data * data,u8 tag)394*4882a593Smuzhiyun static int usbtmc_ioctl_abort_bulk_out_tag(struct usbtmc_device_data *data,
395*4882a593Smuzhiyun 					   u8 tag)
396*4882a593Smuzhiyun {
397*4882a593Smuzhiyun 	struct device *dev;
398*4882a593Smuzhiyun 	u8 *buffer;
399*4882a593Smuzhiyun 	int rv;
400*4882a593Smuzhiyun 	int n;
401*4882a593Smuzhiyun 
402*4882a593Smuzhiyun 	dev = &data->intf->dev;
403*4882a593Smuzhiyun 
404*4882a593Smuzhiyun 	buffer = kmalloc(8, GFP_KERNEL);
405*4882a593Smuzhiyun 	if (!buffer)
406*4882a593Smuzhiyun 		return -ENOMEM;
407*4882a593Smuzhiyun 
408*4882a593Smuzhiyun 	rv = usb_control_msg(data->usb_dev,
409*4882a593Smuzhiyun 			     usb_rcvctrlpipe(data->usb_dev, 0),
410*4882a593Smuzhiyun 			     USBTMC_REQUEST_INITIATE_ABORT_BULK_OUT,
411*4882a593Smuzhiyun 			     USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_ENDPOINT,
412*4882a593Smuzhiyun 			     tag, data->bulk_out,
413*4882a593Smuzhiyun 			     buffer, 2, USB_CTRL_GET_TIMEOUT);
414*4882a593Smuzhiyun 
415*4882a593Smuzhiyun 	if (rv < 0) {
416*4882a593Smuzhiyun 		dev_err(dev, "usb_control_msg returned %d\n", rv);
417*4882a593Smuzhiyun 		goto exit;
418*4882a593Smuzhiyun 	}
419*4882a593Smuzhiyun 
420*4882a593Smuzhiyun 	dev_dbg(dev, "INITIATE_ABORT_BULK_OUT returned %x\n", buffer[0]);
421*4882a593Smuzhiyun 
422*4882a593Smuzhiyun 	if (buffer[0] != USBTMC_STATUS_SUCCESS) {
423*4882a593Smuzhiyun 		dev_err(dev, "INITIATE_ABORT_BULK_OUT returned %x\n",
424*4882a593Smuzhiyun 			buffer[0]);
425*4882a593Smuzhiyun 		rv = -EPERM;
426*4882a593Smuzhiyun 		goto exit;
427*4882a593Smuzhiyun 	}
428*4882a593Smuzhiyun 
429*4882a593Smuzhiyun 	n = 0;
430*4882a593Smuzhiyun 
431*4882a593Smuzhiyun usbtmc_abort_bulk_out_check_status:
432*4882a593Smuzhiyun 	/* do not stress device with subsequent requests */
433*4882a593Smuzhiyun 	msleep(50);
434*4882a593Smuzhiyun 	rv = usb_control_msg(data->usb_dev,
435*4882a593Smuzhiyun 			     usb_rcvctrlpipe(data->usb_dev, 0),
436*4882a593Smuzhiyun 			     USBTMC_REQUEST_CHECK_ABORT_BULK_OUT_STATUS,
437*4882a593Smuzhiyun 			     USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_ENDPOINT,
438*4882a593Smuzhiyun 			     0, data->bulk_out, buffer, 0x08,
439*4882a593Smuzhiyun 			     USB_CTRL_GET_TIMEOUT);
440*4882a593Smuzhiyun 	n++;
441*4882a593Smuzhiyun 	if (rv < 0) {
442*4882a593Smuzhiyun 		dev_err(dev, "usb_control_msg returned %d\n", rv);
443*4882a593Smuzhiyun 		goto exit;
444*4882a593Smuzhiyun 	}
445*4882a593Smuzhiyun 
446*4882a593Smuzhiyun 	dev_dbg(dev, "CHECK_ABORT_BULK_OUT returned %x\n", buffer[0]);
447*4882a593Smuzhiyun 
448*4882a593Smuzhiyun 	if (buffer[0] == USBTMC_STATUS_SUCCESS)
449*4882a593Smuzhiyun 		goto usbtmc_abort_bulk_out_clear_halt;
450*4882a593Smuzhiyun 
451*4882a593Smuzhiyun 	if ((buffer[0] == USBTMC_STATUS_PENDING) &&
452*4882a593Smuzhiyun 	    (n < USBTMC_MAX_READS_TO_CLEAR_BULK_IN))
453*4882a593Smuzhiyun 		goto usbtmc_abort_bulk_out_check_status;
454*4882a593Smuzhiyun 
455*4882a593Smuzhiyun 	rv = -EPERM;
456*4882a593Smuzhiyun 	goto exit;
457*4882a593Smuzhiyun 
458*4882a593Smuzhiyun usbtmc_abort_bulk_out_clear_halt:
459*4882a593Smuzhiyun 	rv = usb_clear_halt(data->usb_dev,
460*4882a593Smuzhiyun 			    usb_sndbulkpipe(data->usb_dev, data->bulk_out));
461*4882a593Smuzhiyun 
462*4882a593Smuzhiyun 	if (rv < 0) {
463*4882a593Smuzhiyun 		dev_err(dev, "usb_control_msg returned %d\n", rv);
464*4882a593Smuzhiyun 		goto exit;
465*4882a593Smuzhiyun 	}
466*4882a593Smuzhiyun 	rv = 0;
467*4882a593Smuzhiyun 
468*4882a593Smuzhiyun exit:
469*4882a593Smuzhiyun 	kfree(buffer);
470*4882a593Smuzhiyun 	return rv;
471*4882a593Smuzhiyun }
472*4882a593Smuzhiyun 
usbtmc_ioctl_abort_bulk_out(struct usbtmc_device_data * data)473*4882a593Smuzhiyun static int usbtmc_ioctl_abort_bulk_out(struct usbtmc_device_data *data)
474*4882a593Smuzhiyun {
475*4882a593Smuzhiyun 	return usbtmc_ioctl_abort_bulk_out_tag(data, data->bTag_last_write);
476*4882a593Smuzhiyun }
477*4882a593Smuzhiyun 
usbtmc488_ioctl_read_stb(struct usbtmc_file_data * file_data,void __user * arg)478*4882a593Smuzhiyun static int usbtmc488_ioctl_read_stb(struct usbtmc_file_data *file_data,
479*4882a593Smuzhiyun 				void __user *arg)
480*4882a593Smuzhiyun {
481*4882a593Smuzhiyun 	struct usbtmc_device_data *data = file_data->data;
482*4882a593Smuzhiyun 	struct device *dev = &data->intf->dev;
483*4882a593Smuzhiyun 	int srq_asserted = 0;
484*4882a593Smuzhiyun 	u8 *buffer;
485*4882a593Smuzhiyun 	u8 tag;
486*4882a593Smuzhiyun 	__u8 stb;
487*4882a593Smuzhiyun 	int rv;
488*4882a593Smuzhiyun 
489*4882a593Smuzhiyun 	dev_dbg(dev, "Enter ioctl_read_stb iin_ep_present: %d\n",
490*4882a593Smuzhiyun 		data->iin_ep_present);
491*4882a593Smuzhiyun 
492*4882a593Smuzhiyun 	spin_lock_irq(&data->dev_lock);
493*4882a593Smuzhiyun 	srq_asserted = atomic_xchg(&file_data->srq_asserted, srq_asserted);
494*4882a593Smuzhiyun 	if (srq_asserted) {
495*4882a593Smuzhiyun 		/* a STB with SRQ is already received */
496*4882a593Smuzhiyun 		stb = file_data->srq_byte;
497*4882a593Smuzhiyun 		spin_unlock_irq(&data->dev_lock);
498*4882a593Smuzhiyun 		rv = put_user(stb, (__u8 __user *)arg);
499*4882a593Smuzhiyun 		dev_dbg(dev, "stb:0x%02x with srq received %d\n",
500*4882a593Smuzhiyun 			(unsigned int)stb, rv);
501*4882a593Smuzhiyun 		return rv;
502*4882a593Smuzhiyun 	}
503*4882a593Smuzhiyun 	spin_unlock_irq(&data->dev_lock);
504*4882a593Smuzhiyun 
505*4882a593Smuzhiyun 	buffer = kmalloc(8, GFP_KERNEL);
506*4882a593Smuzhiyun 	if (!buffer)
507*4882a593Smuzhiyun 		return -ENOMEM;
508*4882a593Smuzhiyun 
509*4882a593Smuzhiyun 	atomic_set(&data->iin_data_valid, 0);
510*4882a593Smuzhiyun 
511*4882a593Smuzhiyun 	rv = usb_control_msg(data->usb_dev,
512*4882a593Smuzhiyun 			usb_rcvctrlpipe(data->usb_dev, 0),
513*4882a593Smuzhiyun 			USBTMC488_REQUEST_READ_STATUS_BYTE,
514*4882a593Smuzhiyun 			USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_INTERFACE,
515*4882a593Smuzhiyun 			data->iin_bTag,
516*4882a593Smuzhiyun 			data->ifnum,
517*4882a593Smuzhiyun 			buffer, 0x03, USB_CTRL_GET_TIMEOUT);
518*4882a593Smuzhiyun 	if (rv < 0) {
519*4882a593Smuzhiyun 		dev_err(dev, "stb usb_control_msg returned %d\n", rv);
520*4882a593Smuzhiyun 		goto exit;
521*4882a593Smuzhiyun 	}
522*4882a593Smuzhiyun 
523*4882a593Smuzhiyun 	if (buffer[0] != USBTMC_STATUS_SUCCESS) {
524*4882a593Smuzhiyun 		dev_err(dev, "control status returned %x\n", buffer[0]);
525*4882a593Smuzhiyun 		rv = -EIO;
526*4882a593Smuzhiyun 		goto exit;
527*4882a593Smuzhiyun 	}
528*4882a593Smuzhiyun 
529*4882a593Smuzhiyun 	if (data->iin_ep_present) {
530*4882a593Smuzhiyun 		rv = wait_event_interruptible_timeout(
531*4882a593Smuzhiyun 			data->waitq,
532*4882a593Smuzhiyun 			atomic_read(&data->iin_data_valid) != 0,
533*4882a593Smuzhiyun 			file_data->timeout);
534*4882a593Smuzhiyun 		if (rv < 0) {
535*4882a593Smuzhiyun 			dev_dbg(dev, "wait interrupted %d\n", rv);
536*4882a593Smuzhiyun 			goto exit;
537*4882a593Smuzhiyun 		}
538*4882a593Smuzhiyun 
539*4882a593Smuzhiyun 		if (rv == 0) {
540*4882a593Smuzhiyun 			dev_dbg(dev, "wait timed out\n");
541*4882a593Smuzhiyun 			rv = -ETIMEDOUT;
542*4882a593Smuzhiyun 			goto exit;
543*4882a593Smuzhiyun 		}
544*4882a593Smuzhiyun 
545*4882a593Smuzhiyun 		tag = data->bNotify1 & 0x7f;
546*4882a593Smuzhiyun 		if (tag != data->iin_bTag) {
547*4882a593Smuzhiyun 			dev_err(dev, "expected bTag %x got %x\n",
548*4882a593Smuzhiyun 				data->iin_bTag, tag);
549*4882a593Smuzhiyun 		}
550*4882a593Smuzhiyun 
551*4882a593Smuzhiyun 		stb = data->bNotify2;
552*4882a593Smuzhiyun 	} else {
553*4882a593Smuzhiyun 		stb = buffer[2];
554*4882a593Smuzhiyun 	}
555*4882a593Smuzhiyun 
556*4882a593Smuzhiyun 	rv = put_user(stb, (__u8 __user *)arg);
557*4882a593Smuzhiyun 	dev_dbg(dev, "stb:0x%02x received %d\n", (unsigned int)stb, rv);
558*4882a593Smuzhiyun 
559*4882a593Smuzhiyun  exit:
560*4882a593Smuzhiyun 	/* bump interrupt bTag */
561*4882a593Smuzhiyun 	data->iin_bTag += 1;
562*4882a593Smuzhiyun 	if (data->iin_bTag > 127)
563*4882a593Smuzhiyun 		/* 1 is for SRQ see USBTMC-USB488 subclass spec section 4.3.1 */
564*4882a593Smuzhiyun 		data->iin_bTag = 2;
565*4882a593Smuzhiyun 
566*4882a593Smuzhiyun 	kfree(buffer);
567*4882a593Smuzhiyun 	return rv;
568*4882a593Smuzhiyun }
569*4882a593Smuzhiyun 
usbtmc488_ioctl_wait_srq(struct usbtmc_file_data * file_data,__u32 __user * arg)570*4882a593Smuzhiyun static int usbtmc488_ioctl_wait_srq(struct usbtmc_file_data *file_data,
571*4882a593Smuzhiyun 				    __u32 __user *arg)
572*4882a593Smuzhiyun {
573*4882a593Smuzhiyun 	struct usbtmc_device_data *data = file_data->data;
574*4882a593Smuzhiyun 	struct device *dev = &data->intf->dev;
575*4882a593Smuzhiyun 	int rv;
576*4882a593Smuzhiyun 	u32 timeout;
577*4882a593Smuzhiyun 	unsigned long expire;
578*4882a593Smuzhiyun 
579*4882a593Smuzhiyun 	if (!data->iin_ep_present) {
580*4882a593Smuzhiyun 		dev_dbg(dev, "no interrupt endpoint present\n");
581*4882a593Smuzhiyun 		return -EFAULT;
582*4882a593Smuzhiyun 	}
583*4882a593Smuzhiyun 
584*4882a593Smuzhiyun 	if (get_user(timeout, arg))
585*4882a593Smuzhiyun 		return -EFAULT;
586*4882a593Smuzhiyun 
587*4882a593Smuzhiyun 	expire = msecs_to_jiffies(timeout);
588*4882a593Smuzhiyun 
589*4882a593Smuzhiyun 	mutex_unlock(&data->io_mutex);
590*4882a593Smuzhiyun 
591*4882a593Smuzhiyun 	rv = wait_event_interruptible_timeout(
592*4882a593Smuzhiyun 			data->waitq,
593*4882a593Smuzhiyun 			atomic_read(&file_data->srq_asserted) != 0 ||
594*4882a593Smuzhiyun 			atomic_read(&file_data->closing),
595*4882a593Smuzhiyun 			expire);
596*4882a593Smuzhiyun 
597*4882a593Smuzhiyun 	mutex_lock(&data->io_mutex);
598*4882a593Smuzhiyun 
599*4882a593Smuzhiyun 	/* Note! disconnect or close could be called in the meantime */
600*4882a593Smuzhiyun 	if (atomic_read(&file_data->closing) || data->zombie)
601*4882a593Smuzhiyun 		rv = -ENODEV;
602*4882a593Smuzhiyun 
603*4882a593Smuzhiyun 	if (rv < 0) {
604*4882a593Smuzhiyun 		/* dev can be invalid now! */
605*4882a593Smuzhiyun 		pr_debug("%s - wait interrupted %d\n", __func__, rv);
606*4882a593Smuzhiyun 		return rv;
607*4882a593Smuzhiyun 	}
608*4882a593Smuzhiyun 
609*4882a593Smuzhiyun 	if (rv == 0) {
610*4882a593Smuzhiyun 		dev_dbg(dev, "%s - wait timed out\n", __func__);
611*4882a593Smuzhiyun 		return -ETIMEDOUT;
612*4882a593Smuzhiyun 	}
613*4882a593Smuzhiyun 
614*4882a593Smuzhiyun 	dev_dbg(dev, "%s - srq asserted\n", __func__);
615*4882a593Smuzhiyun 	return 0;
616*4882a593Smuzhiyun }
617*4882a593Smuzhiyun 
usbtmc488_ioctl_simple(struct usbtmc_device_data * data,void __user * arg,unsigned int cmd)618*4882a593Smuzhiyun static int usbtmc488_ioctl_simple(struct usbtmc_device_data *data,
619*4882a593Smuzhiyun 				void __user *arg, unsigned int cmd)
620*4882a593Smuzhiyun {
621*4882a593Smuzhiyun 	struct device *dev = &data->intf->dev;
622*4882a593Smuzhiyun 	__u8 val;
623*4882a593Smuzhiyun 	u8 *buffer;
624*4882a593Smuzhiyun 	u16 wValue;
625*4882a593Smuzhiyun 	int rv;
626*4882a593Smuzhiyun 
627*4882a593Smuzhiyun 	if (!(data->usb488_caps & USBTMC488_CAPABILITY_SIMPLE))
628*4882a593Smuzhiyun 		return -EINVAL;
629*4882a593Smuzhiyun 
630*4882a593Smuzhiyun 	buffer = kmalloc(8, GFP_KERNEL);
631*4882a593Smuzhiyun 	if (!buffer)
632*4882a593Smuzhiyun 		return -ENOMEM;
633*4882a593Smuzhiyun 
634*4882a593Smuzhiyun 	if (cmd == USBTMC488_REQUEST_REN_CONTROL) {
635*4882a593Smuzhiyun 		rv = copy_from_user(&val, arg, sizeof(val));
636*4882a593Smuzhiyun 		if (rv) {
637*4882a593Smuzhiyun 			rv = -EFAULT;
638*4882a593Smuzhiyun 			goto exit;
639*4882a593Smuzhiyun 		}
640*4882a593Smuzhiyun 		wValue = val ? 1 : 0;
641*4882a593Smuzhiyun 	} else {
642*4882a593Smuzhiyun 		wValue = 0;
643*4882a593Smuzhiyun 	}
644*4882a593Smuzhiyun 
645*4882a593Smuzhiyun 	rv = usb_control_msg(data->usb_dev,
646*4882a593Smuzhiyun 			usb_rcvctrlpipe(data->usb_dev, 0),
647*4882a593Smuzhiyun 			cmd,
648*4882a593Smuzhiyun 			USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_INTERFACE,
649*4882a593Smuzhiyun 			wValue,
650*4882a593Smuzhiyun 			data->ifnum,
651*4882a593Smuzhiyun 			buffer, 0x01, USB_CTRL_GET_TIMEOUT);
652*4882a593Smuzhiyun 	if (rv < 0) {
653*4882a593Smuzhiyun 		dev_err(dev, "simple usb_control_msg failed %d\n", rv);
654*4882a593Smuzhiyun 		goto exit;
655*4882a593Smuzhiyun 	} else if (rv != 1) {
656*4882a593Smuzhiyun 		dev_warn(dev, "simple usb_control_msg returned %d\n", rv);
657*4882a593Smuzhiyun 		rv = -EIO;
658*4882a593Smuzhiyun 		goto exit;
659*4882a593Smuzhiyun 	}
660*4882a593Smuzhiyun 
661*4882a593Smuzhiyun 	if (buffer[0] != USBTMC_STATUS_SUCCESS) {
662*4882a593Smuzhiyun 		dev_err(dev, "simple control status returned %x\n", buffer[0]);
663*4882a593Smuzhiyun 		rv = -EIO;
664*4882a593Smuzhiyun 		goto exit;
665*4882a593Smuzhiyun 	}
666*4882a593Smuzhiyun 	rv = 0;
667*4882a593Smuzhiyun 
668*4882a593Smuzhiyun  exit:
669*4882a593Smuzhiyun 	kfree(buffer);
670*4882a593Smuzhiyun 	return rv;
671*4882a593Smuzhiyun }
672*4882a593Smuzhiyun 
673*4882a593Smuzhiyun /*
674*4882a593Smuzhiyun  * Sends a TRIGGER Bulk-OUT command message
675*4882a593Smuzhiyun  * See the USBTMC-USB488 specification, Table 2.
676*4882a593Smuzhiyun  *
677*4882a593Smuzhiyun  * Also updates bTag_last_write.
678*4882a593Smuzhiyun  */
usbtmc488_ioctl_trigger(struct usbtmc_file_data * file_data)679*4882a593Smuzhiyun static int usbtmc488_ioctl_trigger(struct usbtmc_file_data *file_data)
680*4882a593Smuzhiyun {
681*4882a593Smuzhiyun 	struct usbtmc_device_data *data = file_data->data;
682*4882a593Smuzhiyun 	int retval;
683*4882a593Smuzhiyun 	u8 *buffer;
684*4882a593Smuzhiyun 	int actual;
685*4882a593Smuzhiyun 
686*4882a593Smuzhiyun 	buffer = kzalloc(USBTMC_HEADER_SIZE, GFP_KERNEL);
687*4882a593Smuzhiyun 	if (!buffer)
688*4882a593Smuzhiyun 		return -ENOMEM;
689*4882a593Smuzhiyun 
690*4882a593Smuzhiyun 	buffer[0] = 128;
691*4882a593Smuzhiyun 	buffer[1] = data->bTag;
692*4882a593Smuzhiyun 	buffer[2] = ~data->bTag;
693*4882a593Smuzhiyun 
694*4882a593Smuzhiyun 	retval = usb_bulk_msg(data->usb_dev,
695*4882a593Smuzhiyun 			      usb_sndbulkpipe(data->usb_dev,
696*4882a593Smuzhiyun 					      data->bulk_out),
697*4882a593Smuzhiyun 			      buffer, USBTMC_HEADER_SIZE,
698*4882a593Smuzhiyun 			      &actual, file_data->timeout);
699*4882a593Smuzhiyun 
700*4882a593Smuzhiyun 	/* Store bTag (in case we need to abort) */
701*4882a593Smuzhiyun 	data->bTag_last_write = data->bTag;
702*4882a593Smuzhiyun 
703*4882a593Smuzhiyun 	/* Increment bTag -- and increment again if zero */
704*4882a593Smuzhiyun 	data->bTag++;
705*4882a593Smuzhiyun 	if (!data->bTag)
706*4882a593Smuzhiyun 		data->bTag++;
707*4882a593Smuzhiyun 
708*4882a593Smuzhiyun 	kfree(buffer);
709*4882a593Smuzhiyun 	if (retval < 0) {
710*4882a593Smuzhiyun 		dev_err(&data->intf->dev, "%s returned %d\n",
711*4882a593Smuzhiyun 			__func__, retval);
712*4882a593Smuzhiyun 		return retval;
713*4882a593Smuzhiyun 	}
714*4882a593Smuzhiyun 
715*4882a593Smuzhiyun 	return 0;
716*4882a593Smuzhiyun }
717*4882a593Smuzhiyun 
usbtmc_create_urb(void)718*4882a593Smuzhiyun static struct urb *usbtmc_create_urb(void)
719*4882a593Smuzhiyun {
720*4882a593Smuzhiyun 	const size_t bufsize = USBTMC_BUFSIZE;
721*4882a593Smuzhiyun 	u8 *dmabuf = NULL;
722*4882a593Smuzhiyun 	struct urb *urb = usb_alloc_urb(0, GFP_KERNEL);
723*4882a593Smuzhiyun 
724*4882a593Smuzhiyun 	if (!urb)
725*4882a593Smuzhiyun 		return NULL;
726*4882a593Smuzhiyun 
727*4882a593Smuzhiyun 	dmabuf = kmalloc(bufsize, GFP_KERNEL);
728*4882a593Smuzhiyun 	if (!dmabuf) {
729*4882a593Smuzhiyun 		usb_free_urb(urb);
730*4882a593Smuzhiyun 		return NULL;
731*4882a593Smuzhiyun 	}
732*4882a593Smuzhiyun 
733*4882a593Smuzhiyun 	urb->transfer_buffer = dmabuf;
734*4882a593Smuzhiyun 	urb->transfer_buffer_length = bufsize;
735*4882a593Smuzhiyun 	urb->transfer_flags |= URB_FREE_BUFFER;
736*4882a593Smuzhiyun 	return urb;
737*4882a593Smuzhiyun }
738*4882a593Smuzhiyun 
usbtmc_read_bulk_cb(struct urb * urb)739*4882a593Smuzhiyun static void usbtmc_read_bulk_cb(struct urb *urb)
740*4882a593Smuzhiyun {
741*4882a593Smuzhiyun 	struct usbtmc_file_data *file_data = urb->context;
742*4882a593Smuzhiyun 	int status = urb->status;
743*4882a593Smuzhiyun 	unsigned long flags;
744*4882a593Smuzhiyun 
745*4882a593Smuzhiyun 	/* sync/async unlink faults aren't errors */
746*4882a593Smuzhiyun 	if (status) {
747*4882a593Smuzhiyun 		if (!(/* status == -ENOENT || */
748*4882a593Smuzhiyun 			status == -ECONNRESET ||
749*4882a593Smuzhiyun 			status == -EREMOTEIO || /* Short packet */
750*4882a593Smuzhiyun 			status == -ESHUTDOWN))
751*4882a593Smuzhiyun 			dev_err(&file_data->data->intf->dev,
752*4882a593Smuzhiyun 			"%s - nonzero read bulk status received: %d\n",
753*4882a593Smuzhiyun 			__func__, status);
754*4882a593Smuzhiyun 
755*4882a593Smuzhiyun 		spin_lock_irqsave(&file_data->err_lock, flags);
756*4882a593Smuzhiyun 		if (!file_data->in_status)
757*4882a593Smuzhiyun 			file_data->in_status = status;
758*4882a593Smuzhiyun 		spin_unlock_irqrestore(&file_data->err_lock, flags);
759*4882a593Smuzhiyun 	}
760*4882a593Smuzhiyun 
761*4882a593Smuzhiyun 	spin_lock_irqsave(&file_data->err_lock, flags);
762*4882a593Smuzhiyun 	file_data->in_transfer_size += urb->actual_length;
763*4882a593Smuzhiyun 	dev_dbg(&file_data->data->intf->dev,
764*4882a593Smuzhiyun 		"%s - total size: %u current: %d status: %d\n",
765*4882a593Smuzhiyun 		__func__, file_data->in_transfer_size,
766*4882a593Smuzhiyun 		urb->actual_length, status);
767*4882a593Smuzhiyun 	spin_unlock_irqrestore(&file_data->err_lock, flags);
768*4882a593Smuzhiyun 	usb_anchor_urb(urb, &file_data->in_anchor);
769*4882a593Smuzhiyun 
770*4882a593Smuzhiyun 	wake_up_interruptible(&file_data->wait_bulk_in);
771*4882a593Smuzhiyun 	wake_up_interruptible(&file_data->data->waitq);
772*4882a593Smuzhiyun }
773*4882a593Smuzhiyun 
usbtmc_do_transfer(struct usbtmc_file_data * file_data)774*4882a593Smuzhiyun static inline bool usbtmc_do_transfer(struct usbtmc_file_data *file_data)
775*4882a593Smuzhiyun {
776*4882a593Smuzhiyun 	bool data_or_error;
777*4882a593Smuzhiyun 
778*4882a593Smuzhiyun 	spin_lock_irq(&file_data->err_lock);
779*4882a593Smuzhiyun 	data_or_error = !usb_anchor_empty(&file_data->in_anchor)
780*4882a593Smuzhiyun 			|| file_data->in_status;
781*4882a593Smuzhiyun 	spin_unlock_irq(&file_data->err_lock);
782*4882a593Smuzhiyun 	dev_dbg(&file_data->data->intf->dev, "%s: returns %d\n", __func__,
783*4882a593Smuzhiyun 		data_or_error);
784*4882a593Smuzhiyun 	return data_or_error;
785*4882a593Smuzhiyun }
786*4882a593Smuzhiyun 
usbtmc_generic_read(struct usbtmc_file_data * file_data,void __user * user_buffer,u32 transfer_size,u32 * transferred,u32 flags)787*4882a593Smuzhiyun static ssize_t usbtmc_generic_read(struct usbtmc_file_data *file_data,
788*4882a593Smuzhiyun 				   void __user *user_buffer,
789*4882a593Smuzhiyun 				   u32 transfer_size,
790*4882a593Smuzhiyun 				   u32 *transferred,
791*4882a593Smuzhiyun 				   u32 flags)
792*4882a593Smuzhiyun {
793*4882a593Smuzhiyun 	struct usbtmc_device_data *data = file_data->data;
794*4882a593Smuzhiyun 	struct device *dev = &data->intf->dev;
795*4882a593Smuzhiyun 	u32 done = 0;
796*4882a593Smuzhiyun 	u32 remaining;
797*4882a593Smuzhiyun 	const u32 bufsize = USBTMC_BUFSIZE;
798*4882a593Smuzhiyun 	int retval = 0;
799*4882a593Smuzhiyun 	u32 max_transfer_size;
800*4882a593Smuzhiyun 	unsigned long expire;
801*4882a593Smuzhiyun 	int bufcount = 1;
802*4882a593Smuzhiyun 	int again = 0;
803*4882a593Smuzhiyun 
804*4882a593Smuzhiyun 	/* mutex already locked */
805*4882a593Smuzhiyun 
806*4882a593Smuzhiyun 	*transferred = done;
807*4882a593Smuzhiyun 
808*4882a593Smuzhiyun 	max_transfer_size = transfer_size;
809*4882a593Smuzhiyun 
810*4882a593Smuzhiyun 	if (flags & USBTMC_FLAG_IGNORE_TRAILER) {
811*4882a593Smuzhiyun 		/* The device may send extra alignment bytes (up to
812*4882a593Smuzhiyun 		 * wMaxPacketSize – 1) to avoid sending a zero-length
813*4882a593Smuzhiyun 		 * packet
814*4882a593Smuzhiyun 		 */
815*4882a593Smuzhiyun 		remaining = transfer_size;
816*4882a593Smuzhiyun 		if ((max_transfer_size % data->wMaxPacketSize) == 0)
817*4882a593Smuzhiyun 			max_transfer_size += (data->wMaxPacketSize - 1);
818*4882a593Smuzhiyun 	} else {
819*4882a593Smuzhiyun 		/* round down to bufsize to avoid truncated data left */
820*4882a593Smuzhiyun 		if (max_transfer_size > bufsize) {
821*4882a593Smuzhiyun 			max_transfer_size =
822*4882a593Smuzhiyun 				roundup(max_transfer_size + 1 - bufsize,
823*4882a593Smuzhiyun 					bufsize);
824*4882a593Smuzhiyun 		}
825*4882a593Smuzhiyun 		remaining = max_transfer_size;
826*4882a593Smuzhiyun 	}
827*4882a593Smuzhiyun 
828*4882a593Smuzhiyun 	spin_lock_irq(&file_data->err_lock);
829*4882a593Smuzhiyun 
830*4882a593Smuzhiyun 	if (file_data->in_status) {
831*4882a593Smuzhiyun 		/* return the very first error */
832*4882a593Smuzhiyun 		retval = file_data->in_status;
833*4882a593Smuzhiyun 		spin_unlock_irq(&file_data->err_lock);
834*4882a593Smuzhiyun 		goto error;
835*4882a593Smuzhiyun 	}
836*4882a593Smuzhiyun 
837*4882a593Smuzhiyun 	if (flags & USBTMC_FLAG_ASYNC) {
838*4882a593Smuzhiyun 		if (usb_anchor_empty(&file_data->in_anchor))
839*4882a593Smuzhiyun 			again = 1;
840*4882a593Smuzhiyun 
841*4882a593Smuzhiyun 		if (file_data->in_urbs_used == 0) {
842*4882a593Smuzhiyun 			file_data->in_transfer_size = 0;
843*4882a593Smuzhiyun 			file_data->in_status = 0;
844*4882a593Smuzhiyun 		}
845*4882a593Smuzhiyun 	} else {
846*4882a593Smuzhiyun 		file_data->in_transfer_size = 0;
847*4882a593Smuzhiyun 		file_data->in_status = 0;
848*4882a593Smuzhiyun 	}
849*4882a593Smuzhiyun 
850*4882a593Smuzhiyun 	if (max_transfer_size == 0) {
851*4882a593Smuzhiyun 		bufcount = 0;
852*4882a593Smuzhiyun 	} else {
853*4882a593Smuzhiyun 		bufcount = roundup(max_transfer_size, bufsize) / bufsize;
854*4882a593Smuzhiyun 		if (bufcount > file_data->in_urbs_used)
855*4882a593Smuzhiyun 			bufcount -= file_data->in_urbs_used;
856*4882a593Smuzhiyun 		else
857*4882a593Smuzhiyun 			bufcount = 0;
858*4882a593Smuzhiyun 
859*4882a593Smuzhiyun 		if (bufcount + file_data->in_urbs_used > MAX_URBS_IN_FLIGHT) {
860*4882a593Smuzhiyun 			bufcount = MAX_URBS_IN_FLIGHT -
861*4882a593Smuzhiyun 					file_data->in_urbs_used;
862*4882a593Smuzhiyun 		}
863*4882a593Smuzhiyun 	}
864*4882a593Smuzhiyun 	spin_unlock_irq(&file_data->err_lock);
865*4882a593Smuzhiyun 
866*4882a593Smuzhiyun 	dev_dbg(dev, "%s: requested=%u flags=0x%X size=%u bufs=%d used=%d\n",
867*4882a593Smuzhiyun 		__func__, transfer_size, flags,
868*4882a593Smuzhiyun 		max_transfer_size, bufcount, file_data->in_urbs_used);
869*4882a593Smuzhiyun 
870*4882a593Smuzhiyun 	while (bufcount > 0) {
871*4882a593Smuzhiyun 		u8 *dmabuf = NULL;
872*4882a593Smuzhiyun 		struct urb *urb = usbtmc_create_urb();
873*4882a593Smuzhiyun 
874*4882a593Smuzhiyun 		if (!urb) {
875*4882a593Smuzhiyun 			retval = -ENOMEM;
876*4882a593Smuzhiyun 			goto error;
877*4882a593Smuzhiyun 		}
878*4882a593Smuzhiyun 
879*4882a593Smuzhiyun 		dmabuf = urb->transfer_buffer;
880*4882a593Smuzhiyun 
881*4882a593Smuzhiyun 		usb_fill_bulk_urb(urb, data->usb_dev,
882*4882a593Smuzhiyun 			usb_rcvbulkpipe(data->usb_dev, data->bulk_in),
883*4882a593Smuzhiyun 			dmabuf, bufsize,
884*4882a593Smuzhiyun 			usbtmc_read_bulk_cb, file_data);
885*4882a593Smuzhiyun 
886*4882a593Smuzhiyun 		usb_anchor_urb(urb, &file_data->submitted);
887*4882a593Smuzhiyun 		retval = usb_submit_urb(urb, GFP_KERNEL);
888*4882a593Smuzhiyun 		/* urb is anchored. We can release our reference. */
889*4882a593Smuzhiyun 		usb_free_urb(urb);
890*4882a593Smuzhiyun 		if (unlikely(retval)) {
891*4882a593Smuzhiyun 			usb_unanchor_urb(urb);
892*4882a593Smuzhiyun 			goto error;
893*4882a593Smuzhiyun 		}
894*4882a593Smuzhiyun 		file_data->in_urbs_used++;
895*4882a593Smuzhiyun 		bufcount--;
896*4882a593Smuzhiyun 	}
897*4882a593Smuzhiyun 
898*4882a593Smuzhiyun 	if (again) {
899*4882a593Smuzhiyun 		dev_dbg(dev, "%s: ret=again\n", __func__);
900*4882a593Smuzhiyun 		return -EAGAIN;
901*4882a593Smuzhiyun 	}
902*4882a593Smuzhiyun 
903*4882a593Smuzhiyun 	if (user_buffer == NULL)
904*4882a593Smuzhiyun 		return -EINVAL;
905*4882a593Smuzhiyun 
906*4882a593Smuzhiyun 	expire = msecs_to_jiffies(file_data->timeout);
907*4882a593Smuzhiyun 
908*4882a593Smuzhiyun 	while (max_transfer_size > 0) {
909*4882a593Smuzhiyun 		u32 this_part;
910*4882a593Smuzhiyun 		struct urb *urb = NULL;
911*4882a593Smuzhiyun 
912*4882a593Smuzhiyun 		if (!(flags & USBTMC_FLAG_ASYNC)) {
913*4882a593Smuzhiyun 			dev_dbg(dev, "%s: before wait time %lu\n",
914*4882a593Smuzhiyun 				__func__, expire);
915*4882a593Smuzhiyun 			retval = wait_event_interruptible_timeout(
916*4882a593Smuzhiyun 				file_data->wait_bulk_in,
917*4882a593Smuzhiyun 				usbtmc_do_transfer(file_data),
918*4882a593Smuzhiyun 				expire);
919*4882a593Smuzhiyun 
920*4882a593Smuzhiyun 			dev_dbg(dev, "%s: wait returned %d\n",
921*4882a593Smuzhiyun 				__func__, retval);
922*4882a593Smuzhiyun 
923*4882a593Smuzhiyun 			if (retval <= 0) {
924*4882a593Smuzhiyun 				if (retval == 0)
925*4882a593Smuzhiyun 					retval = -ETIMEDOUT;
926*4882a593Smuzhiyun 				goto error;
927*4882a593Smuzhiyun 			}
928*4882a593Smuzhiyun 		}
929*4882a593Smuzhiyun 
930*4882a593Smuzhiyun 		urb = usb_get_from_anchor(&file_data->in_anchor);
931*4882a593Smuzhiyun 		if (!urb) {
932*4882a593Smuzhiyun 			if (!(flags & USBTMC_FLAG_ASYNC)) {
933*4882a593Smuzhiyun 				/* synchronous case: must not happen */
934*4882a593Smuzhiyun 				retval = -EFAULT;
935*4882a593Smuzhiyun 				goto error;
936*4882a593Smuzhiyun 			}
937*4882a593Smuzhiyun 
938*4882a593Smuzhiyun 			/* asynchronous case: ready, do not block or wait */
939*4882a593Smuzhiyun 			*transferred = done;
940*4882a593Smuzhiyun 			dev_dbg(dev, "%s: (async) done=%u ret=0\n",
941*4882a593Smuzhiyun 				__func__, done);
942*4882a593Smuzhiyun 			return 0;
943*4882a593Smuzhiyun 		}
944*4882a593Smuzhiyun 
945*4882a593Smuzhiyun 		file_data->in_urbs_used--;
946*4882a593Smuzhiyun 
947*4882a593Smuzhiyun 		if (max_transfer_size > urb->actual_length)
948*4882a593Smuzhiyun 			max_transfer_size -= urb->actual_length;
949*4882a593Smuzhiyun 		else
950*4882a593Smuzhiyun 			max_transfer_size = 0;
951*4882a593Smuzhiyun 
952*4882a593Smuzhiyun 		if (remaining > urb->actual_length)
953*4882a593Smuzhiyun 			this_part = urb->actual_length;
954*4882a593Smuzhiyun 		else
955*4882a593Smuzhiyun 			this_part = remaining;
956*4882a593Smuzhiyun 
957*4882a593Smuzhiyun 		print_hex_dump_debug("usbtmc ", DUMP_PREFIX_NONE, 16, 1,
958*4882a593Smuzhiyun 			urb->transfer_buffer, urb->actual_length, true);
959*4882a593Smuzhiyun 
960*4882a593Smuzhiyun 		if (copy_to_user(user_buffer + done,
961*4882a593Smuzhiyun 				 urb->transfer_buffer, this_part)) {
962*4882a593Smuzhiyun 			usb_free_urb(urb);
963*4882a593Smuzhiyun 			retval = -EFAULT;
964*4882a593Smuzhiyun 			goto error;
965*4882a593Smuzhiyun 		}
966*4882a593Smuzhiyun 
967*4882a593Smuzhiyun 		remaining -= this_part;
968*4882a593Smuzhiyun 		done += this_part;
969*4882a593Smuzhiyun 
970*4882a593Smuzhiyun 		spin_lock_irq(&file_data->err_lock);
971*4882a593Smuzhiyun 		if (urb->status) {
972*4882a593Smuzhiyun 			/* return the very first error */
973*4882a593Smuzhiyun 			retval = file_data->in_status;
974*4882a593Smuzhiyun 			spin_unlock_irq(&file_data->err_lock);
975*4882a593Smuzhiyun 			usb_free_urb(urb);
976*4882a593Smuzhiyun 			goto error;
977*4882a593Smuzhiyun 		}
978*4882a593Smuzhiyun 		spin_unlock_irq(&file_data->err_lock);
979*4882a593Smuzhiyun 
980*4882a593Smuzhiyun 		if (urb->actual_length < bufsize) {
981*4882a593Smuzhiyun 			/* short packet or ZLP received => ready */
982*4882a593Smuzhiyun 			usb_free_urb(urb);
983*4882a593Smuzhiyun 			retval = 1;
984*4882a593Smuzhiyun 			break;
985*4882a593Smuzhiyun 		}
986*4882a593Smuzhiyun 
987*4882a593Smuzhiyun 		if (!(flags & USBTMC_FLAG_ASYNC) &&
988*4882a593Smuzhiyun 		    max_transfer_size > (bufsize * file_data->in_urbs_used)) {
989*4882a593Smuzhiyun 			/* resubmit, since other buffers still not enough */
990*4882a593Smuzhiyun 			usb_anchor_urb(urb, &file_data->submitted);
991*4882a593Smuzhiyun 			retval = usb_submit_urb(urb, GFP_KERNEL);
992*4882a593Smuzhiyun 			if (unlikely(retval)) {
993*4882a593Smuzhiyun 				usb_unanchor_urb(urb);
994*4882a593Smuzhiyun 				usb_free_urb(urb);
995*4882a593Smuzhiyun 				goto error;
996*4882a593Smuzhiyun 			}
997*4882a593Smuzhiyun 			file_data->in_urbs_used++;
998*4882a593Smuzhiyun 		}
999*4882a593Smuzhiyun 		usb_free_urb(urb);
1000*4882a593Smuzhiyun 		retval = 0;
1001*4882a593Smuzhiyun 	}
1002*4882a593Smuzhiyun 
1003*4882a593Smuzhiyun error:
1004*4882a593Smuzhiyun 	*transferred = done;
1005*4882a593Smuzhiyun 
1006*4882a593Smuzhiyun 	dev_dbg(dev, "%s: before kill\n", __func__);
1007*4882a593Smuzhiyun 	/* Attention: killing urbs can take long time (2 ms) */
1008*4882a593Smuzhiyun 	usb_kill_anchored_urbs(&file_data->submitted);
1009*4882a593Smuzhiyun 	dev_dbg(dev, "%s: after kill\n", __func__);
1010*4882a593Smuzhiyun 	usb_scuttle_anchored_urbs(&file_data->in_anchor);
1011*4882a593Smuzhiyun 	file_data->in_urbs_used = 0;
1012*4882a593Smuzhiyun 	file_data->in_status = 0; /* no spinlock needed here */
1013*4882a593Smuzhiyun 	dev_dbg(dev, "%s: done=%u ret=%d\n", __func__, done, retval);
1014*4882a593Smuzhiyun 
1015*4882a593Smuzhiyun 	return retval;
1016*4882a593Smuzhiyun }
1017*4882a593Smuzhiyun 
usbtmc_ioctl_generic_read(struct usbtmc_file_data * file_data,void __user * arg)1018*4882a593Smuzhiyun static ssize_t usbtmc_ioctl_generic_read(struct usbtmc_file_data *file_data,
1019*4882a593Smuzhiyun 					 void __user *arg)
1020*4882a593Smuzhiyun {
1021*4882a593Smuzhiyun 	struct usbtmc_message msg;
1022*4882a593Smuzhiyun 	ssize_t retval = 0;
1023*4882a593Smuzhiyun 
1024*4882a593Smuzhiyun 	/* mutex already locked */
1025*4882a593Smuzhiyun 
1026*4882a593Smuzhiyun 	if (copy_from_user(&msg, arg, sizeof(struct usbtmc_message)))
1027*4882a593Smuzhiyun 		return -EFAULT;
1028*4882a593Smuzhiyun 
1029*4882a593Smuzhiyun 	retval = usbtmc_generic_read(file_data, msg.message,
1030*4882a593Smuzhiyun 				     msg.transfer_size, &msg.transferred,
1031*4882a593Smuzhiyun 				     msg.flags);
1032*4882a593Smuzhiyun 
1033*4882a593Smuzhiyun 	if (put_user(msg.transferred,
1034*4882a593Smuzhiyun 		     &((struct usbtmc_message __user *)arg)->transferred))
1035*4882a593Smuzhiyun 		return -EFAULT;
1036*4882a593Smuzhiyun 
1037*4882a593Smuzhiyun 	return retval;
1038*4882a593Smuzhiyun }
1039*4882a593Smuzhiyun 
usbtmc_write_bulk_cb(struct urb * urb)1040*4882a593Smuzhiyun static void usbtmc_write_bulk_cb(struct urb *urb)
1041*4882a593Smuzhiyun {
1042*4882a593Smuzhiyun 	struct usbtmc_file_data *file_data = urb->context;
1043*4882a593Smuzhiyun 	int wakeup = 0;
1044*4882a593Smuzhiyun 	unsigned long flags;
1045*4882a593Smuzhiyun 
1046*4882a593Smuzhiyun 	spin_lock_irqsave(&file_data->err_lock, flags);
1047*4882a593Smuzhiyun 	file_data->out_transfer_size += urb->actual_length;
1048*4882a593Smuzhiyun 
1049*4882a593Smuzhiyun 	/* sync/async unlink faults aren't errors */
1050*4882a593Smuzhiyun 	if (urb->status) {
1051*4882a593Smuzhiyun 		if (!(urb->status == -ENOENT ||
1052*4882a593Smuzhiyun 			urb->status == -ECONNRESET ||
1053*4882a593Smuzhiyun 			urb->status == -ESHUTDOWN))
1054*4882a593Smuzhiyun 			dev_err(&file_data->data->intf->dev,
1055*4882a593Smuzhiyun 				"%s - nonzero write bulk status received: %d\n",
1056*4882a593Smuzhiyun 				__func__, urb->status);
1057*4882a593Smuzhiyun 
1058*4882a593Smuzhiyun 		if (!file_data->out_status) {
1059*4882a593Smuzhiyun 			file_data->out_status = urb->status;
1060*4882a593Smuzhiyun 			wakeup = 1;
1061*4882a593Smuzhiyun 		}
1062*4882a593Smuzhiyun 	}
1063*4882a593Smuzhiyun 	spin_unlock_irqrestore(&file_data->err_lock, flags);
1064*4882a593Smuzhiyun 
1065*4882a593Smuzhiyun 	dev_dbg(&file_data->data->intf->dev,
1066*4882a593Smuzhiyun 		"%s - write bulk total size: %u\n",
1067*4882a593Smuzhiyun 		__func__, file_data->out_transfer_size);
1068*4882a593Smuzhiyun 
1069*4882a593Smuzhiyun 	up(&file_data->limit_write_sem);
1070*4882a593Smuzhiyun 	if (usb_anchor_empty(&file_data->submitted) || wakeup)
1071*4882a593Smuzhiyun 		wake_up_interruptible(&file_data->data->waitq);
1072*4882a593Smuzhiyun }
1073*4882a593Smuzhiyun 
usbtmc_generic_write(struct usbtmc_file_data * file_data,const void __user * user_buffer,u32 transfer_size,u32 * transferred,u32 flags)1074*4882a593Smuzhiyun static ssize_t usbtmc_generic_write(struct usbtmc_file_data *file_data,
1075*4882a593Smuzhiyun 				    const void __user *user_buffer,
1076*4882a593Smuzhiyun 				    u32 transfer_size,
1077*4882a593Smuzhiyun 				    u32 *transferred,
1078*4882a593Smuzhiyun 				    u32 flags)
1079*4882a593Smuzhiyun {
1080*4882a593Smuzhiyun 	struct usbtmc_device_data *data = file_data->data;
1081*4882a593Smuzhiyun 	struct device *dev;
1082*4882a593Smuzhiyun 	u32 done = 0;
1083*4882a593Smuzhiyun 	u32 remaining;
1084*4882a593Smuzhiyun 	unsigned long expire;
1085*4882a593Smuzhiyun 	const u32 bufsize = USBTMC_BUFSIZE;
1086*4882a593Smuzhiyun 	struct urb *urb = NULL;
1087*4882a593Smuzhiyun 	int retval = 0;
1088*4882a593Smuzhiyun 	u32 timeout;
1089*4882a593Smuzhiyun 
1090*4882a593Smuzhiyun 	*transferred = 0;
1091*4882a593Smuzhiyun 
1092*4882a593Smuzhiyun 	/* Get pointer to private data structure */
1093*4882a593Smuzhiyun 	dev = &data->intf->dev;
1094*4882a593Smuzhiyun 
1095*4882a593Smuzhiyun 	dev_dbg(dev, "%s: size=%u flags=0x%X sema=%u\n",
1096*4882a593Smuzhiyun 		__func__, transfer_size, flags,
1097*4882a593Smuzhiyun 		file_data->limit_write_sem.count);
1098*4882a593Smuzhiyun 
1099*4882a593Smuzhiyun 	if (flags & USBTMC_FLAG_APPEND) {
1100*4882a593Smuzhiyun 		spin_lock_irq(&file_data->err_lock);
1101*4882a593Smuzhiyun 		retval = file_data->out_status;
1102*4882a593Smuzhiyun 		spin_unlock_irq(&file_data->err_lock);
1103*4882a593Smuzhiyun 		if (retval < 0)
1104*4882a593Smuzhiyun 			return retval;
1105*4882a593Smuzhiyun 	} else {
1106*4882a593Smuzhiyun 		spin_lock_irq(&file_data->err_lock);
1107*4882a593Smuzhiyun 		file_data->out_transfer_size = 0;
1108*4882a593Smuzhiyun 		file_data->out_status = 0;
1109*4882a593Smuzhiyun 		spin_unlock_irq(&file_data->err_lock);
1110*4882a593Smuzhiyun 	}
1111*4882a593Smuzhiyun 
1112*4882a593Smuzhiyun 	remaining = transfer_size;
1113*4882a593Smuzhiyun 	if (remaining > INT_MAX)
1114*4882a593Smuzhiyun 		remaining = INT_MAX;
1115*4882a593Smuzhiyun 
1116*4882a593Smuzhiyun 	timeout = file_data->timeout;
1117*4882a593Smuzhiyun 	expire = msecs_to_jiffies(timeout);
1118*4882a593Smuzhiyun 
1119*4882a593Smuzhiyun 	while (remaining > 0) {
1120*4882a593Smuzhiyun 		u32 this_part, aligned;
1121*4882a593Smuzhiyun 		u8 *buffer = NULL;
1122*4882a593Smuzhiyun 
1123*4882a593Smuzhiyun 		if (flags & USBTMC_FLAG_ASYNC) {
1124*4882a593Smuzhiyun 			if (down_trylock(&file_data->limit_write_sem)) {
1125*4882a593Smuzhiyun 				retval = (done)?(0):(-EAGAIN);
1126*4882a593Smuzhiyun 				goto exit;
1127*4882a593Smuzhiyun 			}
1128*4882a593Smuzhiyun 		} else {
1129*4882a593Smuzhiyun 			retval = down_timeout(&file_data->limit_write_sem,
1130*4882a593Smuzhiyun 					      expire);
1131*4882a593Smuzhiyun 			if (retval < 0) {
1132*4882a593Smuzhiyun 				retval = -ETIMEDOUT;
1133*4882a593Smuzhiyun 				goto error;
1134*4882a593Smuzhiyun 			}
1135*4882a593Smuzhiyun 		}
1136*4882a593Smuzhiyun 
1137*4882a593Smuzhiyun 		spin_lock_irq(&file_data->err_lock);
1138*4882a593Smuzhiyun 		retval = file_data->out_status;
1139*4882a593Smuzhiyun 		spin_unlock_irq(&file_data->err_lock);
1140*4882a593Smuzhiyun 		if (retval < 0) {
1141*4882a593Smuzhiyun 			up(&file_data->limit_write_sem);
1142*4882a593Smuzhiyun 			goto error;
1143*4882a593Smuzhiyun 		}
1144*4882a593Smuzhiyun 
1145*4882a593Smuzhiyun 		/* prepare next urb to send */
1146*4882a593Smuzhiyun 		urb = usbtmc_create_urb();
1147*4882a593Smuzhiyun 		if (!urb) {
1148*4882a593Smuzhiyun 			retval = -ENOMEM;
1149*4882a593Smuzhiyun 			up(&file_data->limit_write_sem);
1150*4882a593Smuzhiyun 			goto error;
1151*4882a593Smuzhiyun 		}
1152*4882a593Smuzhiyun 		buffer = urb->transfer_buffer;
1153*4882a593Smuzhiyun 
1154*4882a593Smuzhiyun 		if (remaining > bufsize)
1155*4882a593Smuzhiyun 			this_part = bufsize;
1156*4882a593Smuzhiyun 		else
1157*4882a593Smuzhiyun 			this_part = remaining;
1158*4882a593Smuzhiyun 
1159*4882a593Smuzhiyun 		if (copy_from_user(buffer, user_buffer + done, this_part)) {
1160*4882a593Smuzhiyun 			retval = -EFAULT;
1161*4882a593Smuzhiyun 			up(&file_data->limit_write_sem);
1162*4882a593Smuzhiyun 			goto error;
1163*4882a593Smuzhiyun 		}
1164*4882a593Smuzhiyun 
1165*4882a593Smuzhiyun 		print_hex_dump_debug("usbtmc ", DUMP_PREFIX_NONE,
1166*4882a593Smuzhiyun 			16, 1, buffer, this_part, true);
1167*4882a593Smuzhiyun 
1168*4882a593Smuzhiyun 		/* fill bulk with 32 bit alignment to meet USBTMC specification
1169*4882a593Smuzhiyun 		 * (size + 3 & ~3) rounds up and simplifies user code
1170*4882a593Smuzhiyun 		 */
1171*4882a593Smuzhiyun 		aligned = (this_part + 3) & ~3;
1172*4882a593Smuzhiyun 		dev_dbg(dev, "write(size:%u align:%u done:%u)\n",
1173*4882a593Smuzhiyun 			(unsigned int)this_part,
1174*4882a593Smuzhiyun 			(unsigned int)aligned,
1175*4882a593Smuzhiyun 			(unsigned int)done);
1176*4882a593Smuzhiyun 
1177*4882a593Smuzhiyun 		usb_fill_bulk_urb(urb, data->usb_dev,
1178*4882a593Smuzhiyun 			usb_sndbulkpipe(data->usb_dev, data->bulk_out),
1179*4882a593Smuzhiyun 			urb->transfer_buffer, aligned,
1180*4882a593Smuzhiyun 			usbtmc_write_bulk_cb, file_data);
1181*4882a593Smuzhiyun 
1182*4882a593Smuzhiyun 		usb_anchor_urb(urb, &file_data->submitted);
1183*4882a593Smuzhiyun 		retval = usb_submit_urb(urb, GFP_KERNEL);
1184*4882a593Smuzhiyun 		if (unlikely(retval)) {
1185*4882a593Smuzhiyun 			usb_unanchor_urb(urb);
1186*4882a593Smuzhiyun 			up(&file_data->limit_write_sem);
1187*4882a593Smuzhiyun 			goto error;
1188*4882a593Smuzhiyun 		}
1189*4882a593Smuzhiyun 
1190*4882a593Smuzhiyun 		usb_free_urb(urb);
1191*4882a593Smuzhiyun 		urb = NULL; /* urb will be finally released by usb driver */
1192*4882a593Smuzhiyun 
1193*4882a593Smuzhiyun 		remaining -= this_part;
1194*4882a593Smuzhiyun 		done += this_part;
1195*4882a593Smuzhiyun 	}
1196*4882a593Smuzhiyun 
1197*4882a593Smuzhiyun 	/* All urbs are on the fly */
1198*4882a593Smuzhiyun 	if (!(flags & USBTMC_FLAG_ASYNC)) {
1199*4882a593Smuzhiyun 		if (!usb_wait_anchor_empty_timeout(&file_data->submitted,
1200*4882a593Smuzhiyun 						   timeout)) {
1201*4882a593Smuzhiyun 			retval = -ETIMEDOUT;
1202*4882a593Smuzhiyun 			goto error;
1203*4882a593Smuzhiyun 		}
1204*4882a593Smuzhiyun 	}
1205*4882a593Smuzhiyun 
1206*4882a593Smuzhiyun 	retval = 0;
1207*4882a593Smuzhiyun 	goto exit;
1208*4882a593Smuzhiyun 
1209*4882a593Smuzhiyun error:
1210*4882a593Smuzhiyun 	usb_kill_anchored_urbs(&file_data->submitted);
1211*4882a593Smuzhiyun exit:
1212*4882a593Smuzhiyun 	usb_free_urb(urb);
1213*4882a593Smuzhiyun 
1214*4882a593Smuzhiyun 	spin_lock_irq(&file_data->err_lock);
1215*4882a593Smuzhiyun 	if (!(flags & USBTMC_FLAG_ASYNC))
1216*4882a593Smuzhiyun 		done = file_data->out_transfer_size;
1217*4882a593Smuzhiyun 	if (!retval && file_data->out_status)
1218*4882a593Smuzhiyun 		retval = file_data->out_status;
1219*4882a593Smuzhiyun 	spin_unlock_irq(&file_data->err_lock);
1220*4882a593Smuzhiyun 
1221*4882a593Smuzhiyun 	*transferred = done;
1222*4882a593Smuzhiyun 
1223*4882a593Smuzhiyun 	dev_dbg(dev, "%s: done=%u, retval=%d, urbstat=%d\n",
1224*4882a593Smuzhiyun 		__func__, done, retval, file_data->out_status);
1225*4882a593Smuzhiyun 
1226*4882a593Smuzhiyun 	return retval;
1227*4882a593Smuzhiyun }
1228*4882a593Smuzhiyun 
usbtmc_ioctl_generic_write(struct usbtmc_file_data * file_data,void __user * arg)1229*4882a593Smuzhiyun static ssize_t usbtmc_ioctl_generic_write(struct usbtmc_file_data *file_data,
1230*4882a593Smuzhiyun 					  void __user *arg)
1231*4882a593Smuzhiyun {
1232*4882a593Smuzhiyun 	struct usbtmc_message msg;
1233*4882a593Smuzhiyun 	ssize_t retval = 0;
1234*4882a593Smuzhiyun 
1235*4882a593Smuzhiyun 	/* mutex already locked */
1236*4882a593Smuzhiyun 
1237*4882a593Smuzhiyun 	if (copy_from_user(&msg, arg, sizeof(struct usbtmc_message)))
1238*4882a593Smuzhiyun 		return -EFAULT;
1239*4882a593Smuzhiyun 
1240*4882a593Smuzhiyun 	retval = usbtmc_generic_write(file_data, msg.message,
1241*4882a593Smuzhiyun 				      msg.transfer_size, &msg.transferred,
1242*4882a593Smuzhiyun 				      msg.flags);
1243*4882a593Smuzhiyun 
1244*4882a593Smuzhiyun 	if (put_user(msg.transferred,
1245*4882a593Smuzhiyun 		     &((struct usbtmc_message __user *)arg)->transferred))
1246*4882a593Smuzhiyun 		return -EFAULT;
1247*4882a593Smuzhiyun 
1248*4882a593Smuzhiyun 	return retval;
1249*4882a593Smuzhiyun }
1250*4882a593Smuzhiyun 
1251*4882a593Smuzhiyun /*
1252*4882a593Smuzhiyun  * Get the generic write result
1253*4882a593Smuzhiyun  */
usbtmc_ioctl_write_result(struct usbtmc_file_data * file_data,void __user * arg)1254*4882a593Smuzhiyun static ssize_t usbtmc_ioctl_write_result(struct usbtmc_file_data *file_data,
1255*4882a593Smuzhiyun 				void __user *arg)
1256*4882a593Smuzhiyun {
1257*4882a593Smuzhiyun 	u32 transferred;
1258*4882a593Smuzhiyun 	int retval;
1259*4882a593Smuzhiyun 
1260*4882a593Smuzhiyun 	spin_lock_irq(&file_data->err_lock);
1261*4882a593Smuzhiyun 	transferred = file_data->out_transfer_size;
1262*4882a593Smuzhiyun 	retval = file_data->out_status;
1263*4882a593Smuzhiyun 	spin_unlock_irq(&file_data->err_lock);
1264*4882a593Smuzhiyun 
1265*4882a593Smuzhiyun 	if (put_user(transferred, (__u32 __user *)arg))
1266*4882a593Smuzhiyun 		return -EFAULT;
1267*4882a593Smuzhiyun 
1268*4882a593Smuzhiyun 	return retval;
1269*4882a593Smuzhiyun }
1270*4882a593Smuzhiyun 
1271*4882a593Smuzhiyun /*
1272*4882a593Smuzhiyun  * Sends a REQUEST_DEV_DEP_MSG_IN message on the Bulk-OUT endpoint.
1273*4882a593Smuzhiyun  * @transfer_size: number of bytes to request from the device.
1274*4882a593Smuzhiyun  *
1275*4882a593Smuzhiyun  * See the USBTMC specification, Table 4.
1276*4882a593Smuzhiyun  *
1277*4882a593Smuzhiyun  * Also updates bTag_last_write.
1278*4882a593Smuzhiyun  */
send_request_dev_dep_msg_in(struct usbtmc_file_data * file_data,u32 transfer_size)1279*4882a593Smuzhiyun static int send_request_dev_dep_msg_in(struct usbtmc_file_data *file_data,
1280*4882a593Smuzhiyun 				       u32 transfer_size)
1281*4882a593Smuzhiyun {
1282*4882a593Smuzhiyun 	struct usbtmc_device_data *data = file_data->data;
1283*4882a593Smuzhiyun 	int retval;
1284*4882a593Smuzhiyun 	u8 *buffer;
1285*4882a593Smuzhiyun 	int actual;
1286*4882a593Smuzhiyun 
1287*4882a593Smuzhiyun 	buffer = kmalloc(USBTMC_HEADER_SIZE, GFP_KERNEL);
1288*4882a593Smuzhiyun 	if (!buffer)
1289*4882a593Smuzhiyun 		return -ENOMEM;
1290*4882a593Smuzhiyun 	/* Setup IO buffer for REQUEST_DEV_DEP_MSG_IN message
1291*4882a593Smuzhiyun 	 * Refer to class specs for details
1292*4882a593Smuzhiyun 	 */
1293*4882a593Smuzhiyun 	buffer[0] = 2;
1294*4882a593Smuzhiyun 	buffer[1] = data->bTag;
1295*4882a593Smuzhiyun 	buffer[2] = ~data->bTag;
1296*4882a593Smuzhiyun 	buffer[3] = 0; /* Reserved */
1297*4882a593Smuzhiyun 	buffer[4] = transfer_size >> 0;
1298*4882a593Smuzhiyun 	buffer[5] = transfer_size >> 8;
1299*4882a593Smuzhiyun 	buffer[6] = transfer_size >> 16;
1300*4882a593Smuzhiyun 	buffer[7] = transfer_size >> 24;
1301*4882a593Smuzhiyun 	buffer[8] = file_data->term_char_enabled * 2;
1302*4882a593Smuzhiyun 	/* Use term character? */
1303*4882a593Smuzhiyun 	buffer[9] = file_data->term_char;
1304*4882a593Smuzhiyun 	buffer[10] = 0; /* Reserved */
1305*4882a593Smuzhiyun 	buffer[11] = 0; /* Reserved */
1306*4882a593Smuzhiyun 
1307*4882a593Smuzhiyun 	/* Send bulk URB */
1308*4882a593Smuzhiyun 	retval = usb_bulk_msg(data->usb_dev,
1309*4882a593Smuzhiyun 			      usb_sndbulkpipe(data->usb_dev,
1310*4882a593Smuzhiyun 					      data->bulk_out),
1311*4882a593Smuzhiyun 			      buffer, USBTMC_HEADER_SIZE,
1312*4882a593Smuzhiyun 			      &actual, file_data->timeout);
1313*4882a593Smuzhiyun 
1314*4882a593Smuzhiyun 	/* Store bTag (in case we need to abort) */
1315*4882a593Smuzhiyun 	data->bTag_last_write = data->bTag;
1316*4882a593Smuzhiyun 
1317*4882a593Smuzhiyun 	/* Increment bTag -- and increment again if zero */
1318*4882a593Smuzhiyun 	data->bTag++;
1319*4882a593Smuzhiyun 	if (!data->bTag)
1320*4882a593Smuzhiyun 		data->bTag++;
1321*4882a593Smuzhiyun 
1322*4882a593Smuzhiyun 	kfree(buffer);
1323*4882a593Smuzhiyun 	if (retval < 0)
1324*4882a593Smuzhiyun 		dev_err(&data->intf->dev, "%s returned %d\n",
1325*4882a593Smuzhiyun 			__func__, retval);
1326*4882a593Smuzhiyun 
1327*4882a593Smuzhiyun 	return retval;
1328*4882a593Smuzhiyun }
1329*4882a593Smuzhiyun 
usbtmc_read(struct file * filp,char __user * buf,size_t count,loff_t * f_pos)1330*4882a593Smuzhiyun static ssize_t usbtmc_read(struct file *filp, char __user *buf,
1331*4882a593Smuzhiyun 			   size_t count, loff_t *f_pos)
1332*4882a593Smuzhiyun {
1333*4882a593Smuzhiyun 	struct usbtmc_file_data *file_data;
1334*4882a593Smuzhiyun 	struct usbtmc_device_data *data;
1335*4882a593Smuzhiyun 	struct device *dev;
1336*4882a593Smuzhiyun 	const u32 bufsize = USBTMC_BUFSIZE;
1337*4882a593Smuzhiyun 	u32 n_characters;
1338*4882a593Smuzhiyun 	u8 *buffer;
1339*4882a593Smuzhiyun 	int actual;
1340*4882a593Smuzhiyun 	u32 done = 0;
1341*4882a593Smuzhiyun 	u32 remaining;
1342*4882a593Smuzhiyun 	int retval;
1343*4882a593Smuzhiyun 
1344*4882a593Smuzhiyun 	/* Get pointer to private data structure */
1345*4882a593Smuzhiyun 	file_data = filp->private_data;
1346*4882a593Smuzhiyun 	data = file_data->data;
1347*4882a593Smuzhiyun 	dev = &data->intf->dev;
1348*4882a593Smuzhiyun 
1349*4882a593Smuzhiyun 	buffer = kmalloc(bufsize, GFP_KERNEL);
1350*4882a593Smuzhiyun 	if (!buffer)
1351*4882a593Smuzhiyun 		return -ENOMEM;
1352*4882a593Smuzhiyun 
1353*4882a593Smuzhiyun 	mutex_lock(&data->io_mutex);
1354*4882a593Smuzhiyun 	if (data->zombie) {
1355*4882a593Smuzhiyun 		retval = -ENODEV;
1356*4882a593Smuzhiyun 		goto exit;
1357*4882a593Smuzhiyun 	}
1358*4882a593Smuzhiyun 
1359*4882a593Smuzhiyun 	if (count > INT_MAX)
1360*4882a593Smuzhiyun 		count = INT_MAX;
1361*4882a593Smuzhiyun 
1362*4882a593Smuzhiyun 	dev_dbg(dev, "%s(count:%zu)\n", __func__, count);
1363*4882a593Smuzhiyun 
1364*4882a593Smuzhiyun 	retval = send_request_dev_dep_msg_in(file_data, count);
1365*4882a593Smuzhiyun 
1366*4882a593Smuzhiyun 	if (retval < 0) {
1367*4882a593Smuzhiyun 		if (file_data->auto_abort)
1368*4882a593Smuzhiyun 			usbtmc_ioctl_abort_bulk_out(data);
1369*4882a593Smuzhiyun 		goto exit;
1370*4882a593Smuzhiyun 	}
1371*4882a593Smuzhiyun 
1372*4882a593Smuzhiyun 	/* Loop until we have fetched everything we requested */
1373*4882a593Smuzhiyun 	remaining = count;
1374*4882a593Smuzhiyun 	actual = 0;
1375*4882a593Smuzhiyun 
1376*4882a593Smuzhiyun 	/* Send bulk URB */
1377*4882a593Smuzhiyun 	retval = usb_bulk_msg(data->usb_dev,
1378*4882a593Smuzhiyun 			      usb_rcvbulkpipe(data->usb_dev,
1379*4882a593Smuzhiyun 					      data->bulk_in),
1380*4882a593Smuzhiyun 			      buffer, bufsize, &actual,
1381*4882a593Smuzhiyun 			      file_data->timeout);
1382*4882a593Smuzhiyun 
1383*4882a593Smuzhiyun 	dev_dbg(dev, "%s: bulk_msg retval(%u), actual(%d)\n",
1384*4882a593Smuzhiyun 		__func__, retval, actual);
1385*4882a593Smuzhiyun 
1386*4882a593Smuzhiyun 	/* Store bTag (in case we need to abort) */
1387*4882a593Smuzhiyun 	data->bTag_last_read = data->bTag;
1388*4882a593Smuzhiyun 
1389*4882a593Smuzhiyun 	if (retval < 0) {
1390*4882a593Smuzhiyun 		if (file_data->auto_abort)
1391*4882a593Smuzhiyun 			usbtmc_ioctl_abort_bulk_in(data);
1392*4882a593Smuzhiyun 		goto exit;
1393*4882a593Smuzhiyun 	}
1394*4882a593Smuzhiyun 
1395*4882a593Smuzhiyun 	/* Sanity checks for the header */
1396*4882a593Smuzhiyun 	if (actual < USBTMC_HEADER_SIZE) {
1397*4882a593Smuzhiyun 		dev_err(dev, "Device sent too small first packet: %u < %u\n",
1398*4882a593Smuzhiyun 			actual, USBTMC_HEADER_SIZE);
1399*4882a593Smuzhiyun 		if (file_data->auto_abort)
1400*4882a593Smuzhiyun 			usbtmc_ioctl_abort_bulk_in(data);
1401*4882a593Smuzhiyun 		goto exit;
1402*4882a593Smuzhiyun 	}
1403*4882a593Smuzhiyun 
1404*4882a593Smuzhiyun 	if (buffer[0] != 2) {
1405*4882a593Smuzhiyun 		dev_err(dev, "Device sent reply with wrong MsgID: %u != 2\n",
1406*4882a593Smuzhiyun 			buffer[0]);
1407*4882a593Smuzhiyun 		if (file_data->auto_abort)
1408*4882a593Smuzhiyun 			usbtmc_ioctl_abort_bulk_in(data);
1409*4882a593Smuzhiyun 		goto exit;
1410*4882a593Smuzhiyun 	}
1411*4882a593Smuzhiyun 
1412*4882a593Smuzhiyun 	if (buffer[1] != data->bTag_last_write) {
1413*4882a593Smuzhiyun 		dev_err(dev, "Device sent reply with wrong bTag: %u != %u\n",
1414*4882a593Smuzhiyun 		buffer[1], data->bTag_last_write);
1415*4882a593Smuzhiyun 		if (file_data->auto_abort)
1416*4882a593Smuzhiyun 			usbtmc_ioctl_abort_bulk_in(data);
1417*4882a593Smuzhiyun 		goto exit;
1418*4882a593Smuzhiyun 	}
1419*4882a593Smuzhiyun 
1420*4882a593Smuzhiyun 	/* How many characters did the instrument send? */
1421*4882a593Smuzhiyun 	n_characters = buffer[4] +
1422*4882a593Smuzhiyun 		       (buffer[5] << 8) +
1423*4882a593Smuzhiyun 		       (buffer[6] << 16) +
1424*4882a593Smuzhiyun 		       (buffer[7] << 24);
1425*4882a593Smuzhiyun 
1426*4882a593Smuzhiyun 	file_data->bmTransferAttributes = buffer[8];
1427*4882a593Smuzhiyun 
1428*4882a593Smuzhiyun 	dev_dbg(dev, "Bulk-IN header: N_characters(%u), bTransAttr(%u)\n",
1429*4882a593Smuzhiyun 		n_characters, buffer[8]);
1430*4882a593Smuzhiyun 
1431*4882a593Smuzhiyun 	if (n_characters > remaining) {
1432*4882a593Smuzhiyun 		dev_err(dev, "Device wants to return more data than requested: %u > %zu\n",
1433*4882a593Smuzhiyun 			n_characters, count);
1434*4882a593Smuzhiyun 		if (file_data->auto_abort)
1435*4882a593Smuzhiyun 			usbtmc_ioctl_abort_bulk_in(data);
1436*4882a593Smuzhiyun 		goto exit;
1437*4882a593Smuzhiyun 	}
1438*4882a593Smuzhiyun 
1439*4882a593Smuzhiyun 	print_hex_dump_debug("usbtmc ", DUMP_PREFIX_NONE,
1440*4882a593Smuzhiyun 			     16, 1, buffer, actual, true);
1441*4882a593Smuzhiyun 
1442*4882a593Smuzhiyun 	remaining = n_characters;
1443*4882a593Smuzhiyun 
1444*4882a593Smuzhiyun 	/* Remove the USBTMC header */
1445*4882a593Smuzhiyun 	actual -= USBTMC_HEADER_SIZE;
1446*4882a593Smuzhiyun 
1447*4882a593Smuzhiyun 	/* Remove padding if it exists */
1448*4882a593Smuzhiyun 	if (actual > remaining)
1449*4882a593Smuzhiyun 		actual = remaining;
1450*4882a593Smuzhiyun 
1451*4882a593Smuzhiyun 	remaining -= actual;
1452*4882a593Smuzhiyun 
1453*4882a593Smuzhiyun 	/* Copy buffer to user space */
1454*4882a593Smuzhiyun 	if (copy_to_user(buf, &buffer[USBTMC_HEADER_SIZE], actual)) {
1455*4882a593Smuzhiyun 		/* There must have been an addressing problem */
1456*4882a593Smuzhiyun 		retval = -EFAULT;
1457*4882a593Smuzhiyun 		goto exit;
1458*4882a593Smuzhiyun 	}
1459*4882a593Smuzhiyun 
1460*4882a593Smuzhiyun 	if ((actual + USBTMC_HEADER_SIZE) == bufsize) {
1461*4882a593Smuzhiyun 		retval = usbtmc_generic_read(file_data, buf + actual,
1462*4882a593Smuzhiyun 					     remaining,
1463*4882a593Smuzhiyun 					     &done,
1464*4882a593Smuzhiyun 					     USBTMC_FLAG_IGNORE_TRAILER);
1465*4882a593Smuzhiyun 		if (retval < 0)
1466*4882a593Smuzhiyun 			goto exit;
1467*4882a593Smuzhiyun 	}
1468*4882a593Smuzhiyun 	done += actual;
1469*4882a593Smuzhiyun 
1470*4882a593Smuzhiyun 	/* Update file position value */
1471*4882a593Smuzhiyun 	*f_pos = *f_pos + done;
1472*4882a593Smuzhiyun 	retval = done;
1473*4882a593Smuzhiyun 
1474*4882a593Smuzhiyun exit:
1475*4882a593Smuzhiyun 	mutex_unlock(&data->io_mutex);
1476*4882a593Smuzhiyun 	kfree(buffer);
1477*4882a593Smuzhiyun 	return retval;
1478*4882a593Smuzhiyun }
1479*4882a593Smuzhiyun 
usbtmc_write(struct file * filp,const char __user * buf,size_t count,loff_t * f_pos)1480*4882a593Smuzhiyun static ssize_t usbtmc_write(struct file *filp, const char __user *buf,
1481*4882a593Smuzhiyun 			    size_t count, loff_t *f_pos)
1482*4882a593Smuzhiyun {
1483*4882a593Smuzhiyun 	struct usbtmc_file_data *file_data;
1484*4882a593Smuzhiyun 	struct usbtmc_device_data *data;
1485*4882a593Smuzhiyun 	struct urb *urb = NULL;
1486*4882a593Smuzhiyun 	ssize_t retval = 0;
1487*4882a593Smuzhiyun 	u8 *buffer;
1488*4882a593Smuzhiyun 	u32 remaining, done;
1489*4882a593Smuzhiyun 	u32 transfersize, aligned, buflen;
1490*4882a593Smuzhiyun 
1491*4882a593Smuzhiyun 	file_data = filp->private_data;
1492*4882a593Smuzhiyun 	data = file_data->data;
1493*4882a593Smuzhiyun 
1494*4882a593Smuzhiyun 	mutex_lock(&data->io_mutex);
1495*4882a593Smuzhiyun 
1496*4882a593Smuzhiyun 	if (data->zombie) {
1497*4882a593Smuzhiyun 		retval = -ENODEV;
1498*4882a593Smuzhiyun 		goto exit;
1499*4882a593Smuzhiyun 	}
1500*4882a593Smuzhiyun 
1501*4882a593Smuzhiyun 	done = 0;
1502*4882a593Smuzhiyun 
1503*4882a593Smuzhiyun 	spin_lock_irq(&file_data->err_lock);
1504*4882a593Smuzhiyun 	file_data->out_transfer_size = 0;
1505*4882a593Smuzhiyun 	file_data->out_status = 0;
1506*4882a593Smuzhiyun 	spin_unlock_irq(&file_data->err_lock);
1507*4882a593Smuzhiyun 
1508*4882a593Smuzhiyun 	if (!count)
1509*4882a593Smuzhiyun 		goto exit;
1510*4882a593Smuzhiyun 
1511*4882a593Smuzhiyun 	if (down_trylock(&file_data->limit_write_sem)) {
1512*4882a593Smuzhiyun 		/* previous calls were async */
1513*4882a593Smuzhiyun 		retval = -EBUSY;
1514*4882a593Smuzhiyun 		goto exit;
1515*4882a593Smuzhiyun 	}
1516*4882a593Smuzhiyun 
1517*4882a593Smuzhiyun 	urb = usbtmc_create_urb();
1518*4882a593Smuzhiyun 	if (!urb) {
1519*4882a593Smuzhiyun 		retval = -ENOMEM;
1520*4882a593Smuzhiyun 		up(&file_data->limit_write_sem);
1521*4882a593Smuzhiyun 		goto exit;
1522*4882a593Smuzhiyun 	}
1523*4882a593Smuzhiyun 
1524*4882a593Smuzhiyun 	buffer = urb->transfer_buffer;
1525*4882a593Smuzhiyun 	buflen = urb->transfer_buffer_length;
1526*4882a593Smuzhiyun 
1527*4882a593Smuzhiyun 	if (count > INT_MAX) {
1528*4882a593Smuzhiyun 		transfersize = INT_MAX;
1529*4882a593Smuzhiyun 		buffer[8] = 0;
1530*4882a593Smuzhiyun 	} else {
1531*4882a593Smuzhiyun 		transfersize = count;
1532*4882a593Smuzhiyun 		buffer[8] = file_data->eom_val;
1533*4882a593Smuzhiyun 	}
1534*4882a593Smuzhiyun 
1535*4882a593Smuzhiyun 	/* Setup IO buffer for DEV_DEP_MSG_OUT message */
1536*4882a593Smuzhiyun 	buffer[0] = 1;
1537*4882a593Smuzhiyun 	buffer[1] = data->bTag;
1538*4882a593Smuzhiyun 	buffer[2] = ~data->bTag;
1539*4882a593Smuzhiyun 	buffer[3] = 0; /* Reserved */
1540*4882a593Smuzhiyun 	buffer[4] = transfersize >> 0;
1541*4882a593Smuzhiyun 	buffer[5] = transfersize >> 8;
1542*4882a593Smuzhiyun 	buffer[6] = transfersize >> 16;
1543*4882a593Smuzhiyun 	buffer[7] = transfersize >> 24;
1544*4882a593Smuzhiyun 	/* buffer[8] is set above... */
1545*4882a593Smuzhiyun 	buffer[9] = 0; /* Reserved */
1546*4882a593Smuzhiyun 	buffer[10] = 0; /* Reserved */
1547*4882a593Smuzhiyun 	buffer[11] = 0; /* Reserved */
1548*4882a593Smuzhiyun 
1549*4882a593Smuzhiyun 	remaining = transfersize;
1550*4882a593Smuzhiyun 
1551*4882a593Smuzhiyun 	if (transfersize + USBTMC_HEADER_SIZE > buflen) {
1552*4882a593Smuzhiyun 		transfersize = buflen - USBTMC_HEADER_SIZE;
1553*4882a593Smuzhiyun 		aligned = buflen;
1554*4882a593Smuzhiyun 	} else {
1555*4882a593Smuzhiyun 		aligned = (transfersize + (USBTMC_HEADER_SIZE + 3)) & ~3;
1556*4882a593Smuzhiyun 	}
1557*4882a593Smuzhiyun 
1558*4882a593Smuzhiyun 	if (copy_from_user(&buffer[USBTMC_HEADER_SIZE], buf, transfersize)) {
1559*4882a593Smuzhiyun 		retval = -EFAULT;
1560*4882a593Smuzhiyun 		up(&file_data->limit_write_sem);
1561*4882a593Smuzhiyun 		goto exit;
1562*4882a593Smuzhiyun 	}
1563*4882a593Smuzhiyun 
1564*4882a593Smuzhiyun 	dev_dbg(&data->intf->dev, "%s(size:%u align:%u)\n", __func__,
1565*4882a593Smuzhiyun 		(unsigned int)transfersize, (unsigned int)aligned);
1566*4882a593Smuzhiyun 
1567*4882a593Smuzhiyun 	print_hex_dump_debug("usbtmc ", DUMP_PREFIX_NONE,
1568*4882a593Smuzhiyun 			     16, 1, buffer, aligned, true);
1569*4882a593Smuzhiyun 
1570*4882a593Smuzhiyun 	usb_fill_bulk_urb(urb, data->usb_dev,
1571*4882a593Smuzhiyun 		usb_sndbulkpipe(data->usb_dev, data->bulk_out),
1572*4882a593Smuzhiyun 		urb->transfer_buffer, aligned,
1573*4882a593Smuzhiyun 		usbtmc_write_bulk_cb, file_data);
1574*4882a593Smuzhiyun 
1575*4882a593Smuzhiyun 	usb_anchor_urb(urb, &file_data->submitted);
1576*4882a593Smuzhiyun 	retval = usb_submit_urb(urb, GFP_KERNEL);
1577*4882a593Smuzhiyun 	if (unlikely(retval)) {
1578*4882a593Smuzhiyun 		usb_unanchor_urb(urb);
1579*4882a593Smuzhiyun 		up(&file_data->limit_write_sem);
1580*4882a593Smuzhiyun 		goto exit;
1581*4882a593Smuzhiyun 	}
1582*4882a593Smuzhiyun 
1583*4882a593Smuzhiyun 	remaining -= transfersize;
1584*4882a593Smuzhiyun 
1585*4882a593Smuzhiyun 	data->bTag_last_write = data->bTag;
1586*4882a593Smuzhiyun 	data->bTag++;
1587*4882a593Smuzhiyun 
1588*4882a593Smuzhiyun 	if (!data->bTag)
1589*4882a593Smuzhiyun 		data->bTag++;
1590*4882a593Smuzhiyun 
1591*4882a593Smuzhiyun 	/* call generic_write even when remaining = 0 */
1592*4882a593Smuzhiyun 	retval = usbtmc_generic_write(file_data, buf + transfersize, remaining,
1593*4882a593Smuzhiyun 				      &done, USBTMC_FLAG_APPEND);
1594*4882a593Smuzhiyun 	/* truncate alignment bytes */
1595*4882a593Smuzhiyun 	if (done > remaining)
1596*4882a593Smuzhiyun 		done = remaining;
1597*4882a593Smuzhiyun 
1598*4882a593Smuzhiyun 	/*add size of first urb*/
1599*4882a593Smuzhiyun 	done += transfersize;
1600*4882a593Smuzhiyun 
1601*4882a593Smuzhiyun 	if (retval < 0) {
1602*4882a593Smuzhiyun 		usb_kill_anchored_urbs(&file_data->submitted);
1603*4882a593Smuzhiyun 
1604*4882a593Smuzhiyun 		dev_err(&data->intf->dev,
1605*4882a593Smuzhiyun 			"Unable to send data, error %d\n", (int)retval);
1606*4882a593Smuzhiyun 		if (file_data->auto_abort)
1607*4882a593Smuzhiyun 			usbtmc_ioctl_abort_bulk_out(data);
1608*4882a593Smuzhiyun 		goto exit;
1609*4882a593Smuzhiyun 	}
1610*4882a593Smuzhiyun 
1611*4882a593Smuzhiyun 	retval = done;
1612*4882a593Smuzhiyun exit:
1613*4882a593Smuzhiyun 	usb_free_urb(urb);
1614*4882a593Smuzhiyun 	mutex_unlock(&data->io_mutex);
1615*4882a593Smuzhiyun 	return retval;
1616*4882a593Smuzhiyun }
1617*4882a593Smuzhiyun 
usbtmc_ioctl_clear(struct usbtmc_device_data * data)1618*4882a593Smuzhiyun static int usbtmc_ioctl_clear(struct usbtmc_device_data *data)
1619*4882a593Smuzhiyun {
1620*4882a593Smuzhiyun 	struct device *dev;
1621*4882a593Smuzhiyun 	u8 *buffer;
1622*4882a593Smuzhiyun 	int rv;
1623*4882a593Smuzhiyun 	int n;
1624*4882a593Smuzhiyun 	int actual = 0;
1625*4882a593Smuzhiyun 
1626*4882a593Smuzhiyun 	dev = &data->intf->dev;
1627*4882a593Smuzhiyun 
1628*4882a593Smuzhiyun 	dev_dbg(dev, "Sending INITIATE_CLEAR request\n");
1629*4882a593Smuzhiyun 
1630*4882a593Smuzhiyun 	buffer = kmalloc(USBTMC_BUFSIZE, GFP_KERNEL);
1631*4882a593Smuzhiyun 	if (!buffer)
1632*4882a593Smuzhiyun 		return -ENOMEM;
1633*4882a593Smuzhiyun 
1634*4882a593Smuzhiyun 	rv = usb_control_msg(data->usb_dev,
1635*4882a593Smuzhiyun 			     usb_rcvctrlpipe(data->usb_dev, 0),
1636*4882a593Smuzhiyun 			     USBTMC_REQUEST_INITIATE_CLEAR,
1637*4882a593Smuzhiyun 			     USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_INTERFACE,
1638*4882a593Smuzhiyun 			     0, 0, buffer, 1, USB_CTRL_GET_TIMEOUT);
1639*4882a593Smuzhiyun 	if (rv < 0) {
1640*4882a593Smuzhiyun 		dev_err(dev, "usb_control_msg returned %d\n", rv);
1641*4882a593Smuzhiyun 		goto exit;
1642*4882a593Smuzhiyun 	}
1643*4882a593Smuzhiyun 
1644*4882a593Smuzhiyun 	dev_dbg(dev, "INITIATE_CLEAR returned %x\n", buffer[0]);
1645*4882a593Smuzhiyun 
1646*4882a593Smuzhiyun 	if (buffer[0] != USBTMC_STATUS_SUCCESS) {
1647*4882a593Smuzhiyun 		dev_err(dev, "INITIATE_CLEAR returned %x\n", buffer[0]);
1648*4882a593Smuzhiyun 		rv = -EPERM;
1649*4882a593Smuzhiyun 		goto exit;
1650*4882a593Smuzhiyun 	}
1651*4882a593Smuzhiyun 
1652*4882a593Smuzhiyun 	n = 0;
1653*4882a593Smuzhiyun 
1654*4882a593Smuzhiyun usbtmc_clear_check_status:
1655*4882a593Smuzhiyun 
1656*4882a593Smuzhiyun 	dev_dbg(dev, "Sending CHECK_CLEAR_STATUS request\n");
1657*4882a593Smuzhiyun 
1658*4882a593Smuzhiyun 	rv = usb_control_msg(data->usb_dev,
1659*4882a593Smuzhiyun 			     usb_rcvctrlpipe(data->usb_dev, 0),
1660*4882a593Smuzhiyun 			     USBTMC_REQUEST_CHECK_CLEAR_STATUS,
1661*4882a593Smuzhiyun 			     USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_INTERFACE,
1662*4882a593Smuzhiyun 			     0, 0, buffer, 2, USB_CTRL_GET_TIMEOUT);
1663*4882a593Smuzhiyun 	if (rv < 0) {
1664*4882a593Smuzhiyun 		dev_err(dev, "usb_control_msg returned %d\n", rv);
1665*4882a593Smuzhiyun 		goto exit;
1666*4882a593Smuzhiyun 	}
1667*4882a593Smuzhiyun 
1668*4882a593Smuzhiyun 	dev_dbg(dev, "CHECK_CLEAR_STATUS returned %x\n", buffer[0]);
1669*4882a593Smuzhiyun 
1670*4882a593Smuzhiyun 	if (buffer[0] == USBTMC_STATUS_SUCCESS)
1671*4882a593Smuzhiyun 		goto usbtmc_clear_bulk_out_halt;
1672*4882a593Smuzhiyun 
1673*4882a593Smuzhiyun 	if (buffer[0] != USBTMC_STATUS_PENDING) {
1674*4882a593Smuzhiyun 		dev_err(dev, "CHECK_CLEAR_STATUS returned %x\n", buffer[0]);
1675*4882a593Smuzhiyun 		rv = -EPERM;
1676*4882a593Smuzhiyun 		goto exit;
1677*4882a593Smuzhiyun 	}
1678*4882a593Smuzhiyun 
1679*4882a593Smuzhiyun 	if ((buffer[1] & 1) != 0) {
1680*4882a593Smuzhiyun 		do {
1681*4882a593Smuzhiyun 			dev_dbg(dev, "Reading from bulk in EP\n");
1682*4882a593Smuzhiyun 
1683*4882a593Smuzhiyun 			actual = 0;
1684*4882a593Smuzhiyun 			rv = usb_bulk_msg(data->usb_dev,
1685*4882a593Smuzhiyun 					  usb_rcvbulkpipe(data->usb_dev,
1686*4882a593Smuzhiyun 							  data->bulk_in),
1687*4882a593Smuzhiyun 					  buffer, USBTMC_BUFSIZE,
1688*4882a593Smuzhiyun 					  &actual, USB_CTRL_GET_TIMEOUT);
1689*4882a593Smuzhiyun 
1690*4882a593Smuzhiyun 			print_hex_dump_debug("usbtmc ", DUMP_PREFIX_NONE,
1691*4882a593Smuzhiyun 					     16, 1, buffer, actual, true);
1692*4882a593Smuzhiyun 
1693*4882a593Smuzhiyun 			n++;
1694*4882a593Smuzhiyun 
1695*4882a593Smuzhiyun 			if (rv < 0) {
1696*4882a593Smuzhiyun 				dev_err(dev, "usb_control_msg returned %d\n",
1697*4882a593Smuzhiyun 					rv);
1698*4882a593Smuzhiyun 				goto exit;
1699*4882a593Smuzhiyun 			}
1700*4882a593Smuzhiyun 		} while ((actual == USBTMC_BUFSIZE) &&
1701*4882a593Smuzhiyun 			  (n < USBTMC_MAX_READS_TO_CLEAR_BULK_IN));
1702*4882a593Smuzhiyun 	} else {
1703*4882a593Smuzhiyun 		/* do not stress device with subsequent requests */
1704*4882a593Smuzhiyun 		msleep(50);
1705*4882a593Smuzhiyun 		n++;
1706*4882a593Smuzhiyun 	}
1707*4882a593Smuzhiyun 
1708*4882a593Smuzhiyun 	if (n >= USBTMC_MAX_READS_TO_CLEAR_BULK_IN) {
1709*4882a593Smuzhiyun 		dev_err(dev, "Couldn't clear device buffer within %d cycles\n",
1710*4882a593Smuzhiyun 			USBTMC_MAX_READS_TO_CLEAR_BULK_IN);
1711*4882a593Smuzhiyun 		rv = -EPERM;
1712*4882a593Smuzhiyun 		goto exit;
1713*4882a593Smuzhiyun 	}
1714*4882a593Smuzhiyun 
1715*4882a593Smuzhiyun 	goto usbtmc_clear_check_status;
1716*4882a593Smuzhiyun 
1717*4882a593Smuzhiyun usbtmc_clear_bulk_out_halt:
1718*4882a593Smuzhiyun 
1719*4882a593Smuzhiyun 	rv = usb_clear_halt(data->usb_dev,
1720*4882a593Smuzhiyun 			    usb_sndbulkpipe(data->usb_dev, data->bulk_out));
1721*4882a593Smuzhiyun 	if (rv < 0) {
1722*4882a593Smuzhiyun 		dev_err(dev, "usb_clear_halt returned %d\n", rv);
1723*4882a593Smuzhiyun 		goto exit;
1724*4882a593Smuzhiyun 	}
1725*4882a593Smuzhiyun 	rv = 0;
1726*4882a593Smuzhiyun 
1727*4882a593Smuzhiyun exit:
1728*4882a593Smuzhiyun 	kfree(buffer);
1729*4882a593Smuzhiyun 	return rv;
1730*4882a593Smuzhiyun }
1731*4882a593Smuzhiyun 
usbtmc_ioctl_clear_out_halt(struct usbtmc_device_data * data)1732*4882a593Smuzhiyun static int usbtmc_ioctl_clear_out_halt(struct usbtmc_device_data *data)
1733*4882a593Smuzhiyun {
1734*4882a593Smuzhiyun 	int rv;
1735*4882a593Smuzhiyun 
1736*4882a593Smuzhiyun 	rv = usb_clear_halt(data->usb_dev,
1737*4882a593Smuzhiyun 			    usb_sndbulkpipe(data->usb_dev, data->bulk_out));
1738*4882a593Smuzhiyun 
1739*4882a593Smuzhiyun 	if (rv < 0)
1740*4882a593Smuzhiyun 		dev_err(&data->usb_dev->dev, "%s returned %d\n", __func__, rv);
1741*4882a593Smuzhiyun 	return rv;
1742*4882a593Smuzhiyun }
1743*4882a593Smuzhiyun 
usbtmc_ioctl_clear_in_halt(struct usbtmc_device_data * data)1744*4882a593Smuzhiyun static int usbtmc_ioctl_clear_in_halt(struct usbtmc_device_data *data)
1745*4882a593Smuzhiyun {
1746*4882a593Smuzhiyun 	int rv;
1747*4882a593Smuzhiyun 
1748*4882a593Smuzhiyun 	rv = usb_clear_halt(data->usb_dev,
1749*4882a593Smuzhiyun 			    usb_rcvbulkpipe(data->usb_dev, data->bulk_in));
1750*4882a593Smuzhiyun 
1751*4882a593Smuzhiyun 	if (rv < 0)
1752*4882a593Smuzhiyun 		dev_err(&data->usb_dev->dev, "%s returned %d\n", __func__, rv);
1753*4882a593Smuzhiyun 	return rv;
1754*4882a593Smuzhiyun }
1755*4882a593Smuzhiyun 
usbtmc_ioctl_cancel_io(struct usbtmc_file_data * file_data)1756*4882a593Smuzhiyun static int usbtmc_ioctl_cancel_io(struct usbtmc_file_data *file_data)
1757*4882a593Smuzhiyun {
1758*4882a593Smuzhiyun 	spin_lock_irq(&file_data->err_lock);
1759*4882a593Smuzhiyun 	file_data->in_status = -ECANCELED;
1760*4882a593Smuzhiyun 	file_data->out_status = -ECANCELED;
1761*4882a593Smuzhiyun 	spin_unlock_irq(&file_data->err_lock);
1762*4882a593Smuzhiyun 	usb_kill_anchored_urbs(&file_data->submitted);
1763*4882a593Smuzhiyun 	return 0;
1764*4882a593Smuzhiyun }
1765*4882a593Smuzhiyun 
usbtmc_ioctl_cleanup_io(struct usbtmc_file_data * file_data)1766*4882a593Smuzhiyun static int usbtmc_ioctl_cleanup_io(struct usbtmc_file_data *file_data)
1767*4882a593Smuzhiyun {
1768*4882a593Smuzhiyun 	usb_kill_anchored_urbs(&file_data->submitted);
1769*4882a593Smuzhiyun 	usb_scuttle_anchored_urbs(&file_data->in_anchor);
1770*4882a593Smuzhiyun 	spin_lock_irq(&file_data->err_lock);
1771*4882a593Smuzhiyun 	file_data->in_status = 0;
1772*4882a593Smuzhiyun 	file_data->in_transfer_size = 0;
1773*4882a593Smuzhiyun 	file_data->out_status = 0;
1774*4882a593Smuzhiyun 	file_data->out_transfer_size = 0;
1775*4882a593Smuzhiyun 	spin_unlock_irq(&file_data->err_lock);
1776*4882a593Smuzhiyun 
1777*4882a593Smuzhiyun 	file_data->in_urbs_used = 0;
1778*4882a593Smuzhiyun 	return 0;
1779*4882a593Smuzhiyun }
1780*4882a593Smuzhiyun 
get_capabilities(struct usbtmc_device_data * data)1781*4882a593Smuzhiyun static int get_capabilities(struct usbtmc_device_data *data)
1782*4882a593Smuzhiyun {
1783*4882a593Smuzhiyun 	struct device *dev = &data->usb_dev->dev;
1784*4882a593Smuzhiyun 	char *buffer;
1785*4882a593Smuzhiyun 	int rv = 0;
1786*4882a593Smuzhiyun 
1787*4882a593Smuzhiyun 	buffer = kmalloc(0x18, GFP_KERNEL);
1788*4882a593Smuzhiyun 	if (!buffer)
1789*4882a593Smuzhiyun 		return -ENOMEM;
1790*4882a593Smuzhiyun 
1791*4882a593Smuzhiyun 	rv = usb_control_msg(data->usb_dev, usb_rcvctrlpipe(data->usb_dev, 0),
1792*4882a593Smuzhiyun 			     USBTMC_REQUEST_GET_CAPABILITIES,
1793*4882a593Smuzhiyun 			     USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_INTERFACE,
1794*4882a593Smuzhiyun 			     0, 0, buffer, 0x18, USB_CTRL_GET_TIMEOUT);
1795*4882a593Smuzhiyun 	if (rv < 0) {
1796*4882a593Smuzhiyun 		dev_err(dev, "usb_control_msg returned %d\n", rv);
1797*4882a593Smuzhiyun 		goto err_out;
1798*4882a593Smuzhiyun 	}
1799*4882a593Smuzhiyun 
1800*4882a593Smuzhiyun 	dev_dbg(dev, "GET_CAPABILITIES returned %x\n", buffer[0]);
1801*4882a593Smuzhiyun 	if (buffer[0] != USBTMC_STATUS_SUCCESS) {
1802*4882a593Smuzhiyun 		dev_err(dev, "GET_CAPABILITIES returned %x\n", buffer[0]);
1803*4882a593Smuzhiyun 		rv = -EPERM;
1804*4882a593Smuzhiyun 		goto err_out;
1805*4882a593Smuzhiyun 	}
1806*4882a593Smuzhiyun 	dev_dbg(dev, "Interface capabilities are %x\n", buffer[4]);
1807*4882a593Smuzhiyun 	dev_dbg(dev, "Device capabilities are %x\n", buffer[5]);
1808*4882a593Smuzhiyun 	dev_dbg(dev, "USB488 interface capabilities are %x\n", buffer[14]);
1809*4882a593Smuzhiyun 	dev_dbg(dev, "USB488 device capabilities are %x\n", buffer[15]);
1810*4882a593Smuzhiyun 
1811*4882a593Smuzhiyun 	data->capabilities.interface_capabilities = buffer[4];
1812*4882a593Smuzhiyun 	data->capabilities.device_capabilities = buffer[5];
1813*4882a593Smuzhiyun 	data->capabilities.usb488_interface_capabilities = buffer[14];
1814*4882a593Smuzhiyun 	data->capabilities.usb488_device_capabilities = buffer[15];
1815*4882a593Smuzhiyun 	data->usb488_caps = (buffer[14] & 0x07) | ((buffer[15] & 0x0f) << 4);
1816*4882a593Smuzhiyun 	rv = 0;
1817*4882a593Smuzhiyun 
1818*4882a593Smuzhiyun err_out:
1819*4882a593Smuzhiyun 	kfree(buffer);
1820*4882a593Smuzhiyun 	return rv;
1821*4882a593Smuzhiyun }
1822*4882a593Smuzhiyun 
1823*4882a593Smuzhiyun #define capability_attribute(name)					\
1824*4882a593Smuzhiyun static ssize_t name##_show(struct device *dev,				\
1825*4882a593Smuzhiyun 			   struct device_attribute *attr, char *buf)	\
1826*4882a593Smuzhiyun {									\
1827*4882a593Smuzhiyun 	struct usb_interface *intf = to_usb_interface(dev);		\
1828*4882a593Smuzhiyun 	struct usbtmc_device_data *data = usb_get_intfdata(intf);	\
1829*4882a593Smuzhiyun 									\
1830*4882a593Smuzhiyun 	return sprintf(buf, "%d\n", data->capabilities.name);		\
1831*4882a593Smuzhiyun }									\
1832*4882a593Smuzhiyun static DEVICE_ATTR_RO(name)
1833*4882a593Smuzhiyun 
1834*4882a593Smuzhiyun capability_attribute(interface_capabilities);
1835*4882a593Smuzhiyun capability_attribute(device_capabilities);
1836*4882a593Smuzhiyun capability_attribute(usb488_interface_capabilities);
1837*4882a593Smuzhiyun capability_attribute(usb488_device_capabilities);
1838*4882a593Smuzhiyun 
1839*4882a593Smuzhiyun static struct attribute *usbtmc_attrs[] = {
1840*4882a593Smuzhiyun 	&dev_attr_interface_capabilities.attr,
1841*4882a593Smuzhiyun 	&dev_attr_device_capabilities.attr,
1842*4882a593Smuzhiyun 	&dev_attr_usb488_interface_capabilities.attr,
1843*4882a593Smuzhiyun 	&dev_attr_usb488_device_capabilities.attr,
1844*4882a593Smuzhiyun 	NULL,
1845*4882a593Smuzhiyun };
1846*4882a593Smuzhiyun ATTRIBUTE_GROUPS(usbtmc);
1847*4882a593Smuzhiyun 
usbtmc_ioctl_indicator_pulse(struct usbtmc_device_data * data)1848*4882a593Smuzhiyun static int usbtmc_ioctl_indicator_pulse(struct usbtmc_device_data *data)
1849*4882a593Smuzhiyun {
1850*4882a593Smuzhiyun 	struct device *dev;
1851*4882a593Smuzhiyun 	u8 *buffer;
1852*4882a593Smuzhiyun 	int rv;
1853*4882a593Smuzhiyun 
1854*4882a593Smuzhiyun 	dev = &data->intf->dev;
1855*4882a593Smuzhiyun 
1856*4882a593Smuzhiyun 	buffer = kmalloc(2, GFP_KERNEL);
1857*4882a593Smuzhiyun 	if (!buffer)
1858*4882a593Smuzhiyun 		return -ENOMEM;
1859*4882a593Smuzhiyun 
1860*4882a593Smuzhiyun 	rv = usb_control_msg(data->usb_dev,
1861*4882a593Smuzhiyun 			     usb_rcvctrlpipe(data->usb_dev, 0),
1862*4882a593Smuzhiyun 			     USBTMC_REQUEST_INDICATOR_PULSE,
1863*4882a593Smuzhiyun 			     USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_INTERFACE,
1864*4882a593Smuzhiyun 			     0, 0, buffer, 0x01, USB_CTRL_GET_TIMEOUT);
1865*4882a593Smuzhiyun 
1866*4882a593Smuzhiyun 	if (rv < 0) {
1867*4882a593Smuzhiyun 		dev_err(dev, "usb_control_msg returned %d\n", rv);
1868*4882a593Smuzhiyun 		goto exit;
1869*4882a593Smuzhiyun 	}
1870*4882a593Smuzhiyun 
1871*4882a593Smuzhiyun 	dev_dbg(dev, "INDICATOR_PULSE returned %x\n", buffer[0]);
1872*4882a593Smuzhiyun 
1873*4882a593Smuzhiyun 	if (buffer[0] != USBTMC_STATUS_SUCCESS) {
1874*4882a593Smuzhiyun 		dev_err(dev, "INDICATOR_PULSE returned %x\n", buffer[0]);
1875*4882a593Smuzhiyun 		rv = -EPERM;
1876*4882a593Smuzhiyun 		goto exit;
1877*4882a593Smuzhiyun 	}
1878*4882a593Smuzhiyun 	rv = 0;
1879*4882a593Smuzhiyun 
1880*4882a593Smuzhiyun exit:
1881*4882a593Smuzhiyun 	kfree(buffer);
1882*4882a593Smuzhiyun 	return rv;
1883*4882a593Smuzhiyun }
1884*4882a593Smuzhiyun 
usbtmc_ioctl_request(struct usbtmc_device_data * data,void __user * arg)1885*4882a593Smuzhiyun static int usbtmc_ioctl_request(struct usbtmc_device_data *data,
1886*4882a593Smuzhiyun 				void __user *arg)
1887*4882a593Smuzhiyun {
1888*4882a593Smuzhiyun 	struct device *dev = &data->intf->dev;
1889*4882a593Smuzhiyun 	struct usbtmc_ctrlrequest request;
1890*4882a593Smuzhiyun 	u8 *buffer = NULL;
1891*4882a593Smuzhiyun 	int rv;
1892*4882a593Smuzhiyun 	unsigned int is_in, pipe;
1893*4882a593Smuzhiyun 	unsigned long res;
1894*4882a593Smuzhiyun 
1895*4882a593Smuzhiyun 	res = copy_from_user(&request, arg, sizeof(struct usbtmc_ctrlrequest));
1896*4882a593Smuzhiyun 	if (res)
1897*4882a593Smuzhiyun 		return -EFAULT;
1898*4882a593Smuzhiyun 
1899*4882a593Smuzhiyun 	if (request.req.wLength > USBTMC_BUFSIZE)
1900*4882a593Smuzhiyun 		return -EMSGSIZE;
1901*4882a593Smuzhiyun 
1902*4882a593Smuzhiyun 	is_in = request.req.bRequestType & USB_DIR_IN;
1903*4882a593Smuzhiyun 
1904*4882a593Smuzhiyun 	if (request.req.wLength) {
1905*4882a593Smuzhiyun 		buffer = kmalloc(request.req.wLength, GFP_KERNEL);
1906*4882a593Smuzhiyun 		if (!buffer)
1907*4882a593Smuzhiyun 			return -ENOMEM;
1908*4882a593Smuzhiyun 
1909*4882a593Smuzhiyun 		if (!is_in) {
1910*4882a593Smuzhiyun 			/* Send control data to device */
1911*4882a593Smuzhiyun 			res = copy_from_user(buffer, request.data,
1912*4882a593Smuzhiyun 					     request.req.wLength);
1913*4882a593Smuzhiyun 			if (res) {
1914*4882a593Smuzhiyun 				rv = -EFAULT;
1915*4882a593Smuzhiyun 				goto exit;
1916*4882a593Smuzhiyun 			}
1917*4882a593Smuzhiyun 		}
1918*4882a593Smuzhiyun 	}
1919*4882a593Smuzhiyun 
1920*4882a593Smuzhiyun 	if (is_in)
1921*4882a593Smuzhiyun 		pipe = usb_rcvctrlpipe(data->usb_dev, 0);
1922*4882a593Smuzhiyun 	else
1923*4882a593Smuzhiyun 		pipe = usb_sndctrlpipe(data->usb_dev, 0);
1924*4882a593Smuzhiyun 	rv = usb_control_msg(data->usb_dev,
1925*4882a593Smuzhiyun 			pipe,
1926*4882a593Smuzhiyun 			request.req.bRequest,
1927*4882a593Smuzhiyun 			request.req.bRequestType,
1928*4882a593Smuzhiyun 			request.req.wValue,
1929*4882a593Smuzhiyun 			request.req.wIndex,
1930*4882a593Smuzhiyun 			buffer, request.req.wLength, USB_CTRL_GET_TIMEOUT);
1931*4882a593Smuzhiyun 
1932*4882a593Smuzhiyun 	if (rv < 0) {
1933*4882a593Smuzhiyun 		dev_err(dev, "%s failed %d\n", __func__, rv);
1934*4882a593Smuzhiyun 		goto exit;
1935*4882a593Smuzhiyun 	}
1936*4882a593Smuzhiyun 
1937*4882a593Smuzhiyun 	if (rv && is_in) {
1938*4882a593Smuzhiyun 		/* Read control data from device */
1939*4882a593Smuzhiyun 		res = copy_to_user(request.data, buffer, rv);
1940*4882a593Smuzhiyun 		if (res)
1941*4882a593Smuzhiyun 			rv = -EFAULT;
1942*4882a593Smuzhiyun 	}
1943*4882a593Smuzhiyun 
1944*4882a593Smuzhiyun  exit:
1945*4882a593Smuzhiyun 	kfree(buffer);
1946*4882a593Smuzhiyun 	return rv;
1947*4882a593Smuzhiyun }
1948*4882a593Smuzhiyun 
1949*4882a593Smuzhiyun /*
1950*4882a593Smuzhiyun  * Get the usb timeout value
1951*4882a593Smuzhiyun  */
usbtmc_ioctl_get_timeout(struct usbtmc_file_data * file_data,void __user * arg)1952*4882a593Smuzhiyun static int usbtmc_ioctl_get_timeout(struct usbtmc_file_data *file_data,
1953*4882a593Smuzhiyun 				void __user *arg)
1954*4882a593Smuzhiyun {
1955*4882a593Smuzhiyun 	u32 timeout;
1956*4882a593Smuzhiyun 
1957*4882a593Smuzhiyun 	timeout = file_data->timeout;
1958*4882a593Smuzhiyun 
1959*4882a593Smuzhiyun 	return put_user(timeout, (__u32 __user *)arg);
1960*4882a593Smuzhiyun }
1961*4882a593Smuzhiyun 
1962*4882a593Smuzhiyun /*
1963*4882a593Smuzhiyun  * Set the usb timeout value
1964*4882a593Smuzhiyun  */
usbtmc_ioctl_set_timeout(struct usbtmc_file_data * file_data,void __user * arg)1965*4882a593Smuzhiyun static int usbtmc_ioctl_set_timeout(struct usbtmc_file_data *file_data,
1966*4882a593Smuzhiyun 				void __user *arg)
1967*4882a593Smuzhiyun {
1968*4882a593Smuzhiyun 	u32 timeout;
1969*4882a593Smuzhiyun 
1970*4882a593Smuzhiyun 	if (get_user(timeout, (__u32 __user *)arg))
1971*4882a593Smuzhiyun 		return -EFAULT;
1972*4882a593Smuzhiyun 
1973*4882a593Smuzhiyun 	/* Note that timeout = 0 means
1974*4882a593Smuzhiyun 	 * MAX_SCHEDULE_TIMEOUT in usb_control_msg
1975*4882a593Smuzhiyun 	 */
1976*4882a593Smuzhiyun 	if (timeout < USBTMC_MIN_TIMEOUT)
1977*4882a593Smuzhiyun 		return -EINVAL;
1978*4882a593Smuzhiyun 
1979*4882a593Smuzhiyun 	file_data->timeout = timeout;
1980*4882a593Smuzhiyun 
1981*4882a593Smuzhiyun 	return 0;
1982*4882a593Smuzhiyun }
1983*4882a593Smuzhiyun 
1984*4882a593Smuzhiyun /*
1985*4882a593Smuzhiyun  * enables/disables sending EOM on write
1986*4882a593Smuzhiyun  */
usbtmc_ioctl_eom_enable(struct usbtmc_file_data * file_data,void __user * arg)1987*4882a593Smuzhiyun static int usbtmc_ioctl_eom_enable(struct usbtmc_file_data *file_data,
1988*4882a593Smuzhiyun 				void __user *arg)
1989*4882a593Smuzhiyun {
1990*4882a593Smuzhiyun 	u8 eom_enable;
1991*4882a593Smuzhiyun 
1992*4882a593Smuzhiyun 	if (copy_from_user(&eom_enable, arg, sizeof(eom_enable)))
1993*4882a593Smuzhiyun 		return -EFAULT;
1994*4882a593Smuzhiyun 
1995*4882a593Smuzhiyun 	if (eom_enable > 1)
1996*4882a593Smuzhiyun 		return -EINVAL;
1997*4882a593Smuzhiyun 
1998*4882a593Smuzhiyun 	file_data->eom_val = eom_enable;
1999*4882a593Smuzhiyun 
2000*4882a593Smuzhiyun 	return 0;
2001*4882a593Smuzhiyun }
2002*4882a593Smuzhiyun 
2003*4882a593Smuzhiyun /*
2004*4882a593Smuzhiyun  * Configure termination character for read()
2005*4882a593Smuzhiyun  */
usbtmc_ioctl_config_termc(struct usbtmc_file_data * file_data,void __user * arg)2006*4882a593Smuzhiyun static int usbtmc_ioctl_config_termc(struct usbtmc_file_data *file_data,
2007*4882a593Smuzhiyun 				void __user *arg)
2008*4882a593Smuzhiyun {
2009*4882a593Smuzhiyun 	struct usbtmc_termchar termc;
2010*4882a593Smuzhiyun 
2011*4882a593Smuzhiyun 	if (copy_from_user(&termc, arg, sizeof(termc)))
2012*4882a593Smuzhiyun 		return -EFAULT;
2013*4882a593Smuzhiyun 
2014*4882a593Smuzhiyun 	if ((termc.term_char_enabled > 1) ||
2015*4882a593Smuzhiyun 		(termc.term_char_enabled &&
2016*4882a593Smuzhiyun 		!(file_data->data->capabilities.device_capabilities & 1)))
2017*4882a593Smuzhiyun 		return -EINVAL;
2018*4882a593Smuzhiyun 
2019*4882a593Smuzhiyun 	file_data->term_char = termc.term_char;
2020*4882a593Smuzhiyun 	file_data->term_char_enabled = termc.term_char_enabled;
2021*4882a593Smuzhiyun 
2022*4882a593Smuzhiyun 	return 0;
2023*4882a593Smuzhiyun }
2024*4882a593Smuzhiyun 
usbtmc_ioctl(struct file * file,unsigned int cmd,unsigned long arg)2025*4882a593Smuzhiyun static long usbtmc_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
2026*4882a593Smuzhiyun {
2027*4882a593Smuzhiyun 	struct usbtmc_file_data *file_data;
2028*4882a593Smuzhiyun 	struct usbtmc_device_data *data;
2029*4882a593Smuzhiyun 	int retval = -EBADRQC;
2030*4882a593Smuzhiyun 	__u8 tmp_byte;
2031*4882a593Smuzhiyun 
2032*4882a593Smuzhiyun 	file_data = file->private_data;
2033*4882a593Smuzhiyun 	data = file_data->data;
2034*4882a593Smuzhiyun 
2035*4882a593Smuzhiyun 	mutex_lock(&data->io_mutex);
2036*4882a593Smuzhiyun 	if (data->zombie) {
2037*4882a593Smuzhiyun 		retval = -ENODEV;
2038*4882a593Smuzhiyun 		goto skip_io_on_zombie;
2039*4882a593Smuzhiyun 	}
2040*4882a593Smuzhiyun 
2041*4882a593Smuzhiyun 	switch (cmd) {
2042*4882a593Smuzhiyun 	case USBTMC_IOCTL_CLEAR_OUT_HALT:
2043*4882a593Smuzhiyun 		retval = usbtmc_ioctl_clear_out_halt(data);
2044*4882a593Smuzhiyun 		break;
2045*4882a593Smuzhiyun 
2046*4882a593Smuzhiyun 	case USBTMC_IOCTL_CLEAR_IN_HALT:
2047*4882a593Smuzhiyun 		retval = usbtmc_ioctl_clear_in_halt(data);
2048*4882a593Smuzhiyun 		break;
2049*4882a593Smuzhiyun 
2050*4882a593Smuzhiyun 	case USBTMC_IOCTL_INDICATOR_PULSE:
2051*4882a593Smuzhiyun 		retval = usbtmc_ioctl_indicator_pulse(data);
2052*4882a593Smuzhiyun 		break;
2053*4882a593Smuzhiyun 
2054*4882a593Smuzhiyun 	case USBTMC_IOCTL_CLEAR:
2055*4882a593Smuzhiyun 		retval = usbtmc_ioctl_clear(data);
2056*4882a593Smuzhiyun 		break;
2057*4882a593Smuzhiyun 
2058*4882a593Smuzhiyun 	case USBTMC_IOCTL_ABORT_BULK_OUT:
2059*4882a593Smuzhiyun 		retval = usbtmc_ioctl_abort_bulk_out(data);
2060*4882a593Smuzhiyun 		break;
2061*4882a593Smuzhiyun 
2062*4882a593Smuzhiyun 	case USBTMC_IOCTL_ABORT_BULK_IN:
2063*4882a593Smuzhiyun 		retval = usbtmc_ioctl_abort_bulk_in(data);
2064*4882a593Smuzhiyun 		break;
2065*4882a593Smuzhiyun 
2066*4882a593Smuzhiyun 	case USBTMC_IOCTL_CTRL_REQUEST:
2067*4882a593Smuzhiyun 		retval = usbtmc_ioctl_request(data, (void __user *)arg);
2068*4882a593Smuzhiyun 		break;
2069*4882a593Smuzhiyun 
2070*4882a593Smuzhiyun 	case USBTMC_IOCTL_GET_TIMEOUT:
2071*4882a593Smuzhiyun 		retval = usbtmc_ioctl_get_timeout(file_data,
2072*4882a593Smuzhiyun 						  (void __user *)arg);
2073*4882a593Smuzhiyun 		break;
2074*4882a593Smuzhiyun 
2075*4882a593Smuzhiyun 	case USBTMC_IOCTL_SET_TIMEOUT:
2076*4882a593Smuzhiyun 		retval = usbtmc_ioctl_set_timeout(file_data,
2077*4882a593Smuzhiyun 						  (void __user *)arg);
2078*4882a593Smuzhiyun 		break;
2079*4882a593Smuzhiyun 
2080*4882a593Smuzhiyun 	case USBTMC_IOCTL_EOM_ENABLE:
2081*4882a593Smuzhiyun 		retval = usbtmc_ioctl_eom_enable(file_data,
2082*4882a593Smuzhiyun 						 (void __user *)arg);
2083*4882a593Smuzhiyun 		break;
2084*4882a593Smuzhiyun 
2085*4882a593Smuzhiyun 	case USBTMC_IOCTL_CONFIG_TERMCHAR:
2086*4882a593Smuzhiyun 		retval = usbtmc_ioctl_config_termc(file_data,
2087*4882a593Smuzhiyun 						   (void __user *)arg);
2088*4882a593Smuzhiyun 		break;
2089*4882a593Smuzhiyun 
2090*4882a593Smuzhiyun 	case USBTMC_IOCTL_WRITE:
2091*4882a593Smuzhiyun 		retval = usbtmc_ioctl_generic_write(file_data,
2092*4882a593Smuzhiyun 						    (void __user *)arg);
2093*4882a593Smuzhiyun 		break;
2094*4882a593Smuzhiyun 
2095*4882a593Smuzhiyun 	case USBTMC_IOCTL_READ:
2096*4882a593Smuzhiyun 		retval = usbtmc_ioctl_generic_read(file_data,
2097*4882a593Smuzhiyun 						   (void __user *)arg);
2098*4882a593Smuzhiyun 		break;
2099*4882a593Smuzhiyun 
2100*4882a593Smuzhiyun 	case USBTMC_IOCTL_WRITE_RESULT:
2101*4882a593Smuzhiyun 		retval = usbtmc_ioctl_write_result(file_data,
2102*4882a593Smuzhiyun 						   (void __user *)arg);
2103*4882a593Smuzhiyun 		break;
2104*4882a593Smuzhiyun 
2105*4882a593Smuzhiyun 	case USBTMC_IOCTL_API_VERSION:
2106*4882a593Smuzhiyun 		retval = put_user(USBTMC_API_VERSION,
2107*4882a593Smuzhiyun 				  (__u32 __user *)arg);
2108*4882a593Smuzhiyun 		break;
2109*4882a593Smuzhiyun 
2110*4882a593Smuzhiyun 	case USBTMC488_IOCTL_GET_CAPS:
2111*4882a593Smuzhiyun 		retval = put_user(data->usb488_caps,
2112*4882a593Smuzhiyun 				  (unsigned char __user *)arg);
2113*4882a593Smuzhiyun 		break;
2114*4882a593Smuzhiyun 
2115*4882a593Smuzhiyun 	case USBTMC488_IOCTL_READ_STB:
2116*4882a593Smuzhiyun 		retval = usbtmc488_ioctl_read_stb(file_data,
2117*4882a593Smuzhiyun 						  (void __user *)arg);
2118*4882a593Smuzhiyun 		break;
2119*4882a593Smuzhiyun 
2120*4882a593Smuzhiyun 	case USBTMC488_IOCTL_REN_CONTROL:
2121*4882a593Smuzhiyun 		retval = usbtmc488_ioctl_simple(data, (void __user *)arg,
2122*4882a593Smuzhiyun 						USBTMC488_REQUEST_REN_CONTROL);
2123*4882a593Smuzhiyun 		break;
2124*4882a593Smuzhiyun 
2125*4882a593Smuzhiyun 	case USBTMC488_IOCTL_GOTO_LOCAL:
2126*4882a593Smuzhiyun 		retval = usbtmc488_ioctl_simple(data, (void __user *)arg,
2127*4882a593Smuzhiyun 						USBTMC488_REQUEST_GOTO_LOCAL);
2128*4882a593Smuzhiyun 		break;
2129*4882a593Smuzhiyun 
2130*4882a593Smuzhiyun 	case USBTMC488_IOCTL_LOCAL_LOCKOUT:
2131*4882a593Smuzhiyun 		retval = usbtmc488_ioctl_simple(data, (void __user *)arg,
2132*4882a593Smuzhiyun 						USBTMC488_REQUEST_LOCAL_LOCKOUT);
2133*4882a593Smuzhiyun 		break;
2134*4882a593Smuzhiyun 
2135*4882a593Smuzhiyun 	case USBTMC488_IOCTL_TRIGGER:
2136*4882a593Smuzhiyun 		retval = usbtmc488_ioctl_trigger(file_data);
2137*4882a593Smuzhiyun 		break;
2138*4882a593Smuzhiyun 
2139*4882a593Smuzhiyun 	case USBTMC488_IOCTL_WAIT_SRQ:
2140*4882a593Smuzhiyun 		retval = usbtmc488_ioctl_wait_srq(file_data,
2141*4882a593Smuzhiyun 						  (__u32 __user *)arg);
2142*4882a593Smuzhiyun 		break;
2143*4882a593Smuzhiyun 
2144*4882a593Smuzhiyun 	case USBTMC_IOCTL_MSG_IN_ATTR:
2145*4882a593Smuzhiyun 		retval = put_user(file_data->bmTransferAttributes,
2146*4882a593Smuzhiyun 				  (__u8 __user *)arg);
2147*4882a593Smuzhiyun 		break;
2148*4882a593Smuzhiyun 
2149*4882a593Smuzhiyun 	case USBTMC_IOCTL_AUTO_ABORT:
2150*4882a593Smuzhiyun 		retval = get_user(tmp_byte, (unsigned char __user *)arg);
2151*4882a593Smuzhiyun 		if (retval == 0)
2152*4882a593Smuzhiyun 			file_data->auto_abort = !!tmp_byte;
2153*4882a593Smuzhiyun 		break;
2154*4882a593Smuzhiyun 
2155*4882a593Smuzhiyun 	case USBTMC_IOCTL_CANCEL_IO:
2156*4882a593Smuzhiyun 		retval = usbtmc_ioctl_cancel_io(file_data);
2157*4882a593Smuzhiyun 		break;
2158*4882a593Smuzhiyun 
2159*4882a593Smuzhiyun 	case USBTMC_IOCTL_CLEANUP_IO:
2160*4882a593Smuzhiyun 		retval = usbtmc_ioctl_cleanup_io(file_data);
2161*4882a593Smuzhiyun 		break;
2162*4882a593Smuzhiyun 	}
2163*4882a593Smuzhiyun 
2164*4882a593Smuzhiyun skip_io_on_zombie:
2165*4882a593Smuzhiyun 	mutex_unlock(&data->io_mutex);
2166*4882a593Smuzhiyun 	return retval;
2167*4882a593Smuzhiyun }
2168*4882a593Smuzhiyun 
usbtmc_fasync(int fd,struct file * file,int on)2169*4882a593Smuzhiyun static int usbtmc_fasync(int fd, struct file *file, int on)
2170*4882a593Smuzhiyun {
2171*4882a593Smuzhiyun 	struct usbtmc_file_data *file_data = file->private_data;
2172*4882a593Smuzhiyun 
2173*4882a593Smuzhiyun 	return fasync_helper(fd, file, on, &file_data->data->fasync);
2174*4882a593Smuzhiyun }
2175*4882a593Smuzhiyun 
usbtmc_poll(struct file * file,poll_table * wait)2176*4882a593Smuzhiyun static __poll_t usbtmc_poll(struct file *file, poll_table *wait)
2177*4882a593Smuzhiyun {
2178*4882a593Smuzhiyun 	struct usbtmc_file_data *file_data = file->private_data;
2179*4882a593Smuzhiyun 	struct usbtmc_device_data *data = file_data->data;
2180*4882a593Smuzhiyun 	__poll_t mask;
2181*4882a593Smuzhiyun 
2182*4882a593Smuzhiyun 	mutex_lock(&data->io_mutex);
2183*4882a593Smuzhiyun 
2184*4882a593Smuzhiyun 	if (data->zombie) {
2185*4882a593Smuzhiyun 		mask = EPOLLHUP | EPOLLERR;
2186*4882a593Smuzhiyun 		goto no_poll;
2187*4882a593Smuzhiyun 	}
2188*4882a593Smuzhiyun 
2189*4882a593Smuzhiyun 	poll_wait(file, &data->waitq, wait);
2190*4882a593Smuzhiyun 
2191*4882a593Smuzhiyun 	/* Note that EPOLLPRI is now assigned to SRQ, and
2192*4882a593Smuzhiyun 	 * EPOLLIN|EPOLLRDNORM to normal read data.
2193*4882a593Smuzhiyun 	 */
2194*4882a593Smuzhiyun 	mask = 0;
2195*4882a593Smuzhiyun 	if (atomic_read(&file_data->srq_asserted))
2196*4882a593Smuzhiyun 		mask |= EPOLLPRI;
2197*4882a593Smuzhiyun 
2198*4882a593Smuzhiyun 	/* Note that the anchor submitted includes all urbs for BULK IN
2199*4882a593Smuzhiyun 	 * and OUT. So EPOLLOUT is signaled when BULK OUT is empty and
2200*4882a593Smuzhiyun 	 * all BULK IN urbs are completed and moved to in_anchor.
2201*4882a593Smuzhiyun 	 */
2202*4882a593Smuzhiyun 	if (usb_anchor_empty(&file_data->submitted))
2203*4882a593Smuzhiyun 		mask |= (EPOLLOUT | EPOLLWRNORM);
2204*4882a593Smuzhiyun 	if (!usb_anchor_empty(&file_data->in_anchor))
2205*4882a593Smuzhiyun 		mask |= (EPOLLIN | EPOLLRDNORM);
2206*4882a593Smuzhiyun 
2207*4882a593Smuzhiyun 	spin_lock_irq(&file_data->err_lock);
2208*4882a593Smuzhiyun 	if (file_data->in_status || file_data->out_status)
2209*4882a593Smuzhiyun 		mask |= EPOLLERR;
2210*4882a593Smuzhiyun 	spin_unlock_irq(&file_data->err_lock);
2211*4882a593Smuzhiyun 
2212*4882a593Smuzhiyun 	dev_dbg(&data->intf->dev, "poll mask = %x\n", mask);
2213*4882a593Smuzhiyun 
2214*4882a593Smuzhiyun no_poll:
2215*4882a593Smuzhiyun 	mutex_unlock(&data->io_mutex);
2216*4882a593Smuzhiyun 	return mask;
2217*4882a593Smuzhiyun }
2218*4882a593Smuzhiyun 
2219*4882a593Smuzhiyun static const struct file_operations fops = {
2220*4882a593Smuzhiyun 	.owner		= THIS_MODULE,
2221*4882a593Smuzhiyun 	.read		= usbtmc_read,
2222*4882a593Smuzhiyun 	.write		= usbtmc_write,
2223*4882a593Smuzhiyun 	.open		= usbtmc_open,
2224*4882a593Smuzhiyun 	.release	= usbtmc_release,
2225*4882a593Smuzhiyun 	.flush		= usbtmc_flush,
2226*4882a593Smuzhiyun 	.unlocked_ioctl	= usbtmc_ioctl,
2227*4882a593Smuzhiyun 	.compat_ioctl	= compat_ptr_ioctl,
2228*4882a593Smuzhiyun 	.fasync         = usbtmc_fasync,
2229*4882a593Smuzhiyun 	.poll           = usbtmc_poll,
2230*4882a593Smuzhiyun 	.llseek		= default_llseek,
2231*4882a593Smuzhiyun };
2232*4882a593Smuzhiyun 
2233*4882a593Smuzhiyun static struct usb_class_driver usbtmc_class = {
2234*4882a593Smuzhiyun 	.name =		"usbtmc%d",
2235*4882a593Smuzhiyun 	.fops =		&fops,
2236*4882a593Smuzhiyun 	.minor_base =	USBTMC_MINOR_BASE,
2237*4882a593Smuzhiyun };
2238*4882a593Smuzhiyun 
usbtmc_interrupt(struct urb * urb)2239*4882a593Smuzhiyun static void usbtmc_interrupt(struct urb *urb)
2240*4882a593Smuzhiyun {
2241*4882a593Smuzhiyun 	struct usbtmc_device_data *data = urb->context;
2242*4882a593Smuzhiyun 	struct device *dev = &data->intf->dev;
2243*4882a593Smuzhiyun 	int status = urb->status;
2244*4882a593Smuzhiyun 	int rv;
2245*4882a593Smuzhiyun 
2246*4882a593Smuzhiyun 	dev_dbg(&data->intf->dev, "int status: %d len %d\n",
2247*4882a593Smuzhiyun 		status, urb->actual_length);
2248*4882a593Smuzhiyun 
2249*4882a593Smuzhiyun 	switch (status) {
2250*4882a593Smuzhiyun 	case 0: /* SUCCESS */
2251*4882a593Smuzhiyun 		/* check for valid STB notification */
2252*4882a593Smuzhiyun 		if (data->iin_buffer[0] > 0x81) {
2253*4882a593Smuzhiyun 			data->bNotify1 = data->iin_buffer[0];
2254*4882a593Smuzhiyun 			data->bNotify2 = data->iin_buffer[1];
2255*4882a593Smuzhiyun 			atomic_set(&data->iin_data_valid, 1);
2256*4882a593Smuzhiyun 			wake_up_interruptible(&data->waitq);
2257*4882a593Smuzhiyun 			goto exit;
2258*4882a593Smuzhiyun 		}
2259*4882a593Smuzhiyun 		/* check for SRQ notification */
2260*4882a593Smuzhiyun 		if (data->iin_buffer[0] == 0x81) {
2261*4882a593Smuzhiyun 			unsigned long flags;
2262*4882a593Smuzhiyun 			struct list_head *elem;
2263*4882a593Smuzhiyun 
2264*4882a593Smuzhiyun 			if (data->fasync)
2265*4882a593Smuzhiyun 				kill_fasync(&data->fasync,
2266*4882a593Smuzhiyun 					SIGIO, POLL_PRI);
2267*4882a593Smuzhiyun 
2268*4882a593Smuzhiyun 			spin_lock_irqsave(&data->dev_lock, flags);
2269*4882a593Smuzhiyun 			list_for_each(elem, &data->file_list) {
2270*4882a593Smuzhiyun 				struct usbtmc_file_data *file_data;
2271*4882a593Smuzhiyun 
2272*4882a593Smuzhiyun 				file_data = list_entry(elem,
2273*4882a593Smuzhiyun 						       struct usbtmc_file_data,
2274*4882a593Smuzhiyun 						       file_elem);
2275*4882a593Smuzhiyun 				file_data->srq_byte = data->iin_buffer[1];
2276*4882a593Smuzhiyun 				atomic_set(&file_data->srq_asserted, 1);
2277*4882a593Smuzhiyun 			}
2278*4882a593Smuzhiyun 			spin_unlock_irqrestore(&data->dev_lock, flags);
2279*4882a593Smuzhiyun 
2280*4882a593Smuzhiyun 			dev_dbg(dev, "srq received bTag %x stb %x\n",
2281*4882a593Smuzhiyun 				(unsigned int)data->iin_buffer[0],
2282*4882a593Smuzhiyun 				(unsigned int)data->iin_buffer[1]);
2283*4882a593Smuzhiyun 			wake_up_interruptible_all(&data->waitq);
2284*4882a593Smuzhiyun 			goto exit;
2285*4882a593Smuzhiyun 		}
2286*4882a593Smuzhiyun 		dev_warn(dev, "invalid notification: %x\n",
2287*4882a593Smuzhiyun 			 data->iin_buffer[0]);
2288*4882a593Smuzhiyun 		break;
2289*4882a593Smuzhiyun 	case -EOVERFLOW:
2290*4882a593Smuzhiyun 		dev_err(dev, "overflow with length %d, actual length is %d\n",
2291*4882a593Smuzhiyun 			data->iin_wMaxPacketSize, urb->actual_length);
2292*4882a593Smuzhiyun 		fallthrough;
2293*4882a593Smuzhiyun 	default:
2294*4882a593Smuzhiyun 		/* urb terminated, clean up */
2295*4882a593Smuzhiyun 		dev_dbg(dev, "urb terminated, status: %d\n", status);
2296*4882a593Smuzhiyun 		return;
2297*4882a593Smuzhiyun 	}
2298*4882a593Smuzhiyun exit:
2299*4882a593Smuzhiyun 	rv = usb_submit_urb(urb, GFP_ATOMIC);
2300*4882a593Smuzhiyun 	if (rv)
2301*4882a593Smuzhiyun 		dev_err(dev, "usb_submit_urb failed: %d\n", rv);
2302*4882a593Smuzhiyun }
2303*4882a593Smuzhiyun 
usbtmc_free_int(struct usbtmc_device_data * data)2304*4882a593Smuzhiyun static void usbtmc_free_int(struct usbtmc_device_data *data)
2305*4882a593Smuzhiyun {
2306*4882a593Smuzhiyun 	if (!data->iin_ep_present || !data->iin_urb)
2307*4882a593Smuzhiyun 		return;
2308*4882a593Smuzhiyun 	usb_kill_urb(data->iin_urb);
2309*4882a593Smuzhiyun 	kfree(data->iin_buffer);
2310*4882a593Smuzhiyun 	data->iin_buffer = NULL;
2311*4882a593Smuzhiyun 	usb_free_urb(data->iin_urb);
2312*4882a593Smuzhiyun 	data->iin_urb = NULL;
2313*4882a593Smuzhiyun 	kref_put(&data->kref, usbtmc_delete);
2314*4882a593Smuzhiyun }
2315*4882a593Smuzhiyun 
usbtmc_probe(struct usb_interface * intf,const struct usb_device_id * id)2316*4882a593Smuzhiyun static int usbtmc_probe(struct usb_interface *intf,
2317*4882a593Smuzhiyun 			const struct usb_device_id *id)
2318*4882a593Smuzhiyun {
2319*4882a593Smuzhiyun 	struct usbtmc_device_data *data;
2320*4882a593Smuzhiyun 	struct usb_host_interface *iface_desc;
2321*4882a593Smuzhiyun 	struct usb_endpoint_descriptor *bulk_in, *bulk_out, *int_in;
2322*4882a593Smuzhiyun 	int retcode;
2323*4882a593Smuzhiyun 
2324*4882a593Smuzhiyun 	dev_dbg(&intf->dev, "%s called\n", __func__);
2325*4882a593Smuzhiyun 
2326*4882a593Smuzhiyun 	data = kzalloc(sizeof(*data), GFP_KERNEL);
2327*4882a593Smuzhiyun 	if (!data)
2328*4882a593Smuzhiyun 		return -ENOMEM;
2329*4882a593Smuzhiyun 
2330*4882a593Smuzhiyun 	data->intf = intf;
2331*4882a593Smuzhiyun 	data->id = id;
2332*4882a593Smuzhiyun 	data->usb_dev = usb_get_dev(interface_to_usbdev(intf));
2333*4882a593Smuzhiyun 	usb_set_intfdata(intf, data);
2334*4882a593Smuzhiyun 	kref_init(&data->kref);
2335*4882a593Smuzhiyun 	mutex_init(&data->io_mutex);
2336*4882a593Smuzhiyun 	init_waitqueue_head(&data->waitq);
2337*4882a593Smuzhiyun 	atomic_set(&data->iin_data_valid, 0);
2338*4882a593Smuzhiyun 	INIT_LIST_HEAD(&data->file_list);
2339*4882a593Smuzhiyun 	spin_lock_init(&data->dev_lock);
2340*4882a593Smuzhiyun 
2341*4882a593Smuzhiyun 	data->zombie = 0;
2342*4882a593Smuzhiyun 
2343*4882a593Smuzhiyun 	/* Initialize USBTMC bTag and other fields */
2344*4882a593Smuzhiyun 	data->bTag	= 1;
2345*4882a593Smuzhiyun 	/*  2 <= bTag <= 127   USBTMC-USB488 subclass specification 4.3.1 */
2346*4882a593Smuzhiyun 	data->iin_bTag = 2;
2347*4882a593Smuzhiyun 
2348*4882a593Smuzhiyun 	/* USBTMC devices have only one setting, so use that */
2349*4882a593Smuzhiyun 	iface_desc = data->intf->cur_altsetting;
2350*4882a593Smuzhiyun 	data->ifnum = iface_desc->desc.bInterfaceNumber;
2351*4882a593Smuzhiyun 
2352*4882a593Smuzhiyun 	/* Find bulk endpoints */
2353*4882a593Smuzhiyun 	retcode = usb_find_common_endpoints(iface_desc,
2354*4882a593Smuzhiyun 			&bulk_in, &bulk_out, NULL, NULL);
2355*4882a593Smuzhiyun 	if (retcode) {
2356*4882a593Smuzhiyun 		dev_err(&intf->dev, "bulk endpoints not found\n");
2357*4882a593Smuzhiyun 		goto err_put;
2358*4882a593Smuzhiyun 	}
2359*4882a593Smuzhiyun 
2360*4882a593Smuzhiyun 	retcode = -EINVAL;
2361*4882a593Smuzhiyun 	data->bulk_in = bulk_in->bEndpointAddress;
2362*4882a593Smuzhiyun 	data->wMaxPacketSize = usb_endpoint_maxp(bulk_in);
2363*4882a593Smuzhiyun 	if (!data->wMaxPacketSize)
2364*4882a593Smuzhiyun 		goto err_put;
2365*4882a593Smuzhiyun 	dev_dbg(&intf->dev, "Found bulk in endpoint at %u\n", data->bulk_in);
2366*4882a593Smuzhiyun 
2367*4882a593Smuzhiyun 	data->bulk_out = bulk_out->bEndpointAddress;
2368*4882a593Smuzhiyun 	dev_dbg(&intf->dev, "Found Bulk out endpoint at %u\n", data->bulk_out);
2369*4882a593Smuzhiyun 
2370*4882a593Smuzhiyun 	/* Find int endpoint */
2371*4882a593Smuzhiyun 	retcode = usb_find_int_in_endpoint(iface_desc, &int_in);
2372*4882a593Smuzhiyun 	if (!retcode) {
2373*4882a593Smuzhiyun 		data->iin_ep_present = 1;
2374*4882a593Smuzhiyun 		data->iin_ep = int_in->bEndpointAddress;
2375*4882a593Smuzhiyun 		data->iin_wMaxPacketSize = usb_endpoint_maxp(int_in);
2376*4882a593Smuzhiyun 		data->iin_interval = int_in->bInterval;
2377*4882a593Smuzhiyun 		dev_dbg(&intf->dev, "Found Int in endpoint at %u\n",
2378*4882a593Smuzhiyun 				data->iin_ep);
2379*4882a593Smuzhiyun 	}
2380*4882a593Smuzhiyun 
2381*4882a593Smuzhiyun 	retcode = get_capabilities(data);
2382*4882a593Smuzhiyun 	if (retcode)
2383*4882a593Smuzhiyun 		dev_err(&intf->dev, "can't read capabilities\n");
2384*4882a593Smuzhiyun 
2385*4882a593Smuzhiyun 	if (data->iin_ep_present) {
2386*4882a593Smuzhiyun 		/* allocate int urb */
2387*4882a593Smuzhiyun 		data->iin_urb = usb_alloc_urb(0, GFP_KERNEL);
2388*4882a593Smuzhiyun 		if (!data->iin_urb) {
2389*4882a593Smuzhiyun 			retcode = -ENOMEM;
2390*4882a593Smuzhiyun 			goto error_register;
2391*4882a593Smuzhiyun 		}
2392*4882a593Smuzhiyun 
2393*4882a593Smuzhiyun 		/* Protect interrupt in endpoint data until iin_urb is freed */
2394*4882a593Smuzhiyun 		kref_get(&data->kref);
2395*4882a593Smuzhiyun 
2396*4882a593Smuzhiyun 		/* allocate buffer for interrupt in */
2397*4882a593Smuzhiyun 		data->iin_buffer = kmalloc(data->iin_wMaxPacketSize,
2398*4882a593Smuzhiyun 					GFP_KERNEL);
2399*4882a593Smuzhiyun 		if (!data->iin_buffer) {
2400*4882a593Smuzhiyun 			retcode = -ENOMEM;
2401*4882a593Smuzhiyun 			goto error_register;
2402*4882a593Smuzhiyun 		}
2403*4882a593Smuzhiyun 
2404*4882a593Smuzhiyun 		/* fill interrupt urb */
2405*4882a593Smuzhiyun 		usb_fill_int_urb(data->iin_urb, data->usb_dev,
2406*4882a593Smuzhiyun 				usb_rcvintpipe(data->usb_dev, data->iin_ep),
2407*4882a593Smuzhiyun 				data->iin_buffer, data->iin_wMaxPacketSize,
2408*4882a593Smuzhiyun 				usbtmc_interrupt,
2409*4882a593Smuzhiyun 				data, data->iin_interval);
2410*4882a593Smuzhiyun 
2411*4882a593Smuzhiyun 		retcode = usb_submit_urb(data->iin_urb, GFP_KERNEL);
2412*4882a593Smuzhiyun 		if (retcode) {
2413*4882a593Smuzhiyun 			dev_err(&intf->dev, "Failed to submit iin_urb\n");
2414*4882a593Smuzhiyun 			goto error_register;
2415*4882a593Smuzhiyun 		}
2416*4882a593Smuzhiyun 	}
2417*4882a593Smuzhiyun 
2418*4882a593Smuzhiyun 	retcode = usb_register_dev(intf, &usbtmc_class);
2419*4882a593Smuzhiyun 	if (retcode) {
2420*4882a593Smuzhiyun 		dev_err(&intf->dev, "Not able to get a minor (base %u, slice default): %d\n",
2421*4882a593Smuzhiyun 			USBTMC_MINOR_BASE,
2422*4882a593Smuzhiyun 			retcode);
2423*4882a593Smuzhiyun 		goto error_register;
2424*4882a593Smuzhiyun 	}
2425*4882a593Smuzhiyun 	dev_dbg(&intf->dev, "Using minor number %d\n", intf->minor);
2426*4882a593Smuzhiyun 
2427*4882a593Smuzhiyun 	return 0;
2428*4882a593Smuzhiyun 
2429*4882a593Smuzhiyun error_register:
2430*4882a593Smuzhiyun 	usbtmc_free_int(data);
2431*4882a593Smuzhiyun err_put:
2432*4882a593Smuzhiyun 	kref_put(&data->kref, usbtmc_delete);
2433*4882a593Smuzhiyun 	return retcode;
2434*4882a593Smuzhiyun }
2435*4882a593Smuzhiyun 
usbtmc_disconnect(struct usb_interface * intf)2436*4882a593Smuzhiyun static void usbtmc_disconnect(struct usb_interface *intf)
2437*4882a593Smuzhiyun {
2438*4882a593Smuzhiyun 	struct usbtmc_device_data *data  = usb_get_intfdata(intf);
2439*4882a593Smuzhiyun 	struct list_head *elem;
2440*4882a593Smuzhiyun 
2441*4882a593Smuzhiyun 	usb_deregister_dev(intf, &usbtmc_class);
2442*4882a593Smuzhiyun 	mutex_lock(&data->io_mutex);
2443*4882a593Smuzhiyun 	data->zombie = 1;
2444*4882a593Smuzhiyun 	wake_up_interruptible_all(&data->waitq);
2445*4882a593Smuzhiyun 	list_for_each(elem, &data->file_list) {
2446*4882a593Smuzhiyun 		struct usbtmc_file_data *file_data;
2447*4882a593Smuzhiyun 
2448*4882a593Smuzhiyun 		file_data = list_entry(elem,
2449*4882a593Smuzhiyun 				       struct usbtmc_file_data,
2450*4882a593Smuzhiyun 				       file_elem);
2451*4882a593Smuzhiyun 		usb_kill_anchored_urbs(&file_data->submitted);
2452*4882a593Smuzhiyun 		usb_scuttle_anchored_urbs(&file_data->in_anchor);
2453*4882a593Smuzhiyun 	}
2454*4882a593Smuzhiyun 	mutex_unlock(&data->io_mutex);
2455*4882a593Smuzhiyun 	usbtmc_free_int(data);
2456*4882a593Smuzhiyun 	kref_put(&data->kref, usbtmc_delete);
2457*4882a593Smuzhiyun }
2458*4882a593Smuzhiyun 
usbtmc_draw_down(struct usbtmc_file_data * file_data)2459*4882a593Smuzhiyun static void usbtmc_draw_down(struct usbtmc_file_data *file_data)
2460*4882a593Smuzhiyun {
2461*4882a593Smuzhiyun 	int time;
2462*4882a593Smuzhiyun 
2463*4882a593Smuzhiyun 	time = usb_wait_anchor_empty_timeout(&file_data->submitted, 1000);
2464*4882a593Smuzhiyun 	if (!time)
2465*4882a593Smuzhiyun 		usb_kill_anchored_urbs(&file_data->submitted);
2466*4882a593Smuzhiyun 	usb_scuttle_anchored_urbs(&file_data->in_anchor);
2467*4882a593Smuzhiyun }
2468*4882a593Smuzhiyun 
usbtmc_suspend(struct usb_interface * intf,pm_message_t message)2469*4882a593Smuzhiyun static int usbtmc_suspend(struct usb_interface *intf, pm_message_t message)
2470*4882a593Smuzhiyun {
2471*4882a593Smuzhiyun 	struct usbtmc_device_data *data = usb_get_intfdata(intf);
2472*4882a593Smuzhiyun 	struct list_head *elem;
2473*4882a593Smuzhiyun 
2474*4882a593Smuzhiyun 	if (!data)
2475*4882a593Smuzhiyun 		return 0;
2476*4882a593Smuzhiyun 
2477*4882a593Smuzhiyun 	mutex_lock(&data->io_mutex);
2478*4882a593Smuzhiyun 	list_for_each(elem, &data->file_list) {
2479*4882a593Smuzhiyun 		struct usbtmc_file_data *file_data;
2480*4882a593Smuzhiyun 
2481*4882a593Smuzhiyun 		file_data = list_entry(elem,
2482*4882a593Smuzhiyun 				       struct usbtmc_file_data,
2483*4882a593Smuzhiyun 				       file_elem);
2484*4882a593Smuzhiyun 		usbtmc_draw_down(file_data);
2485*4882a593Smuzhiyun 	}
2486*4882a593Smuzhiyun 
2487*4882a593Smuzhiyun 	if (data->iin_ep_present && data->iin_urb)
2488*4882a593Smuzhiyun 		usb_kill_urb(data->iin_urb);
2489*4882a593Smuzhiyun 
2490*4882a593Smuzhiyun 	mutex_unlock(&data->io_mutex);
2491*4882a593Smuzhiyun 	return 0;
2492*4882a593Smuzhiyun }
2493*4882a593Smuzhiyun 
usbtmc_resume(struct usb_interface * intf)2494*4882a593Smuzhiyun static int usbtmc_resume(struct usb_interface *intf)
2495*4882a593Smuzhiyun {
2496*4882a593Smuzhiyun 	struct usbtmc_device_data *data = usb_get_intfdata(intf);
2497*4882a593Smuzhiyun 	int retcode = 0;
2498*4882a593Smuzhiyun 
2499*4882a593Smuzhiyun 	if (data->iin_ep_present && data->iin_urb)
2500*4882a593Smuzhiyun 		retcode = usb_submit_urb(data->iin_urb, GFP_KERNEL);
2501*4882a593Smuzhiyun 	if (retcode)
2502*4882a593Smuzhiyun 		dev_err(&intf->dev, "Failed to submit iin_urb\n");
2503*4882a593Smuzhiyun 
2504*4882a593Smuzhiyun 	return retcode;
2505*4882a593Smuzhiyun }
2506*4882a593Smuzhiyun 
usbtmc_pre_reset(struct usb_interface * intf)2507*4882a593Smuzhiyun static int usbtmc_pre_reset(struct usb_interface *intf)
2508*4882a593Smuzhiyun {
2509*4882a593Smuzhiyun 	struct usbtmc_device_data *data  = usb_get_intfdata(intf);
2510*4882a593Smuzhiyun 	struct list_head *elem;
2511*4882a593Smuzhiyun 
2512*4882a593Smuzhiyun 	if (!data)
2513*4882a593Smuzhiyun 		return 0;
2514*4882a593Smuzhiyun 
2515*4882a593Smuzhiyun 	mutex_lock(&data->io_mutex);
2516*4882a593Smuzhiyun 
2517*4882a593Smuzhiyun 	list_for_each(elem, &data->file_list) {
2518*4882a593Smuzhiyun 		struct usbtmc_file_data *file_data;
2519*4882a593Smuzhiyun 
2520*4882a593Smuzhiyun 		file_data = list_entry(elem,
2521*4882a593Smuzhiyun 				       struct usbtmc_file_data,
2522*4882a593Smuzhiyun 				       file_elem);
2523*4882a593Smuzhiyun 		usbtmc_ioctl_cancel_io(file_data);
2524*4882a593Smuzhiyun 	}
2525*4882a593Smuzhiyun 
2526*4882a593Smuzhiyun 	return 0;
2527*4882a593Smuzhiyun }
2528*4882a593Smuzhiyun 
usbtmc_post_reset(struct usb_interface * intf)2529*4882a593Smuzhiyun static int usbtmc_post_reset(struct usb_interface *intf)
2530*4882a593Smuzhiyun {
2531*4882a593Smuzhiyun 	struct usbtmc_device_data *data  = usb_get_intfdata(intf);
2532*4882a593Smuzhiyun 
2533*4882a593Smuzhiyun 	mutex_unlock(&data->io_mutex);
2534*4882a593Smuzhiyun 
2535*4882a593Smuzhiyun 	return 0;
2536*4882a593Smuzhiyun }
2537*4882a593Smuzhiyun 
2538*4882a593Smuzhiyun static struct usb_driver usbtmc_driver = {
2539*4882a593Smuzhiyun 	.name		= "usbtmc",
2540*4882a593Smuzhiyun 	.id_table	= usbtmc_devices,
2541*4882a593Smuzhiyun 	.probe		= usbtmc_probe,
2542*4882a593Smuzhiyun 	.disconnect	= usbtmc_disconnect,
2543*4882a593Smuzhiyun 	.suspend	= usbtmc_suspend,
2544*4882a593Smuzhiyun 	.resume		= usbtmc_resume,
2545*4882a593Smuzhiyun 	.pre_reset	= usbtmc_pre_reset,
2546*4882a593Smuzhiyun 	.post_reset	= usbtmc_post_reset,
2547*4882a593Smuzhiyun 	.dev_groups	= usbtmc_groups,
2548*4882a593Smuzhiyun };
2549*4882a593Smuzhiyun 
2550*4882a593Smuzhiyun module_usb_driver(usbtmc_driver);
2551*4882a593Smuzhiyun 
2552*4882a593Smuzhiyun MODULE_LICENSE("GPL");
2553