Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   1) // SPDX-License-Identifier: GPL-2.0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   3)  * The USB Monitor, inspired by Dave Harding's USBMon.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   4)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   5)  * This is a text format reader.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   6)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   7) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   8) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   9) #include <linux/list.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  10) #include <linux/usb.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  11) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  12) #include <linux/sched/signal.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  13) #include <linux/time.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  14) #include <linux/ktime.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  15) #include <linux/export.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  16) #include <linux/mutex.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  17) #include <linux/debugfs.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  18) #include <linux/scatterlist.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  19) #include <linux/uaccess.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  20) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  21) #include "usb_mon.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  22) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  23) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  24)  * No, we do not want arbitrarily long data strings.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  25)  * Use the binary interface if you want to capture bulk data!
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  26)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  27) #define DATA_MAX  32
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  28) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  29) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  30)  * Defined by USB 2.0 clause 9.3, table 9.2.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  31)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  32) #define SETUP_MAX  8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  33) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  34) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  35)  * This limit exists to prevent OOMs when the user process stops reading.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  36)  * If usbmon were available to unprivileged processes, it might be open
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  37)  * to a local DoS. But we have to keep to root in order to prevent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  38)  * password sniffing from HID devices.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  39)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  40) #define EVENT_MAX  (4*PAGE_SIZE / sizeof(struct mon_event_text))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  41) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  42) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  43)  * Potentially unlimited number; we limit it for similar allocations.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  44)  * The usbfs limits this to 128, but we're not quite as generous.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  45)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  46) #define ISODESC_MAX   5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  47) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  48) #define PRINTF_DFL  250   /* with 5 ISOs segs */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  49) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  50) struct mon_iso_desc {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  51) 	int status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  52) 	unsigned int offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  53) 	unsigned int length;	/* Unsigned here, signed in URB. Historic. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  54) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  55) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  56) struct mon_event_text {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  57) 	struct list_head e_link;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  58) 	int type;		/* submit, complete, etc. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  59) 	unsigned long id;	/* From pointer, most of the time */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  60) 	unsigned int tstamp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  61) 	int busnum;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  62) 	char devnum;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  63) 	char epnum;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  64) 	char is_in;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  65) 	char xfertype;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  66) 	int length;		/* Depends on type: xfer length or act length */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  67) 	int status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  68) 	int interval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  69) 	int start_frame;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  70) 	int error_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  71) 	char setup_flag;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  72) 	char data_flag;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  73) 	int numdesc;		/* Full number */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  74) 	struct mon_iso_desc isodesc[ISODESC_MAX];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  75) 	unsigned char setup[SETUP_MAX];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  76) 	unsigned char data[DATA_MAX];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  77) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  78) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  79) #define SLAB_NAME_SZ  30
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  80) struct mon_reader_text {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  81) 	struct kmem_cache *e_slab;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  82) 	int nevents;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  83) 	struct list_head e_list;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  84) 	struct mon_reader r;	/* In C, parent class can be placed anywhere */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  85) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  86) 	wait_queue_head_t wait;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  87) 	int printf_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  88) 	size_t printf_offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  89) 	size_t printf_togo;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  90) 	char *printf_buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  91) 	struct mutex printf_lock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  92) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  93) 	char slab_name[SLAB_NAME_SZ];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  94) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  95) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  96) static struct dentry *mon_dir;		/* Usually /sys/kernel/debug/usbmon */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  97) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  98) static void mon_text_ctor(void *);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  99) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) struct mon_text_ptr {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) 	int cnt, limit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) 	char *pbuf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) static struct mon_event_text *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106)     mon_text_read_wait(struct mon_reader_text *rp, struct file *file);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) static void mon_text_read_head_t(struct mon_reader_text *rp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) 	struct mon_text_ptr *p, const struct mon_event_text *ep);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) static void mon_text_read_head_u(struct mon_reader_text *rp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) 	struct mon_text_ptr *p, const struct mon_event_text *ep);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) static void mon_text_read_statset(struct mon_reader_text *rp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) 	struct mon_text_ptr *p, const struct mon_event_text *ep);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) static void mon_text_read_intstat(struct mon_reader_text *rp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) 	struct mon_text_ptr *p, const struct mon_event_text *ep);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) static void mon_text_read_isostat(struct mon_reader_text *rp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) 	struct mon_text_ptr *p, const struct mon_event_text *ep);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) static void mon_text_read_isodesc(struct mon_reader_text *rp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) 	struct mon_text_ptr *p, const struct mon_event_text *ep);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) static void mon_text_read_data(struct mon_reader_text *rp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120)     struct mon_text_ptr *p, const struct mon_event_text *ep);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123)  * mon_text_submit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124)  * mon_text_complete
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126)  * May be called from an interrupt.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128)  * This is called with the whole mon_bus locked, so no additional lock.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) static inline char mon_text_get_setup(struct mon_event_text *ep,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132)     struct urb *urb, char ev_type, struct mon_bus *mbus)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) 	if (ep->xfertype != USB_ENDPOINT_XFER_CONTROL || ev_type != 'S')
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) 		return '-';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) 	if (urb->setup_packet == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) 		return 'Z';	/* '0' would be not as pretty. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) 	memcpy(ep->setup, urb->setup_packet, SETUP_MAX);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) static inline char mon_text_get_data(struct mon_event_text *ep, struct urb *urb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146)     int len, char ev_type, struct mon_bus *mbus)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) 	void *src;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) 	if (len <= 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) 		return 'L';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) 	if (len >= DATA_MAX)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) 		len = DATA_MAX;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) 	if (ep->is_in) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) 		if (ev_type != 'C')
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) 			return '<';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) 		if (ev_type != 'S')
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) 			return '>';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) 	if (urb->num_sgs == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) 		src = urb->transfer_buffer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) 		if (src == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) 			return 'Z';	/* '0' would be not as pretty. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) 		struct scatterlist *sg = urb->sg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) 		if (PageHighMem(sg_page(sg)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) 			return 'D';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) 		/* For the text interface we copy only the first sg buffer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) 		len = min_t(int, sg->length, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) 		src = sg_virt(sg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) 	memcpy(ep->data, src, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) static inline unsigned int mon_get_timestamp(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) 	struct timespec64 now;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) 	unsigned int stamp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) 	ktime_get_ts64(&now);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) 	stamp = now.tv_sec & 0xFFF;  /* 2^32 = 4294967296. Limit to 4096s. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) 	stamp = stamp * USEC_PER_SEC + now.tv_nsec / NSEC_PER_USEC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) 	return stamp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) static void mon_text_event(struct mon_reader_text *rp, struct urb *urb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194)     char ev_type, int status)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) 	struct mon_event_text *ep;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) 	unsigned int stamp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) 	struct usb_iso_packet_descriptor *fp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) 	struct mon_iso_desc *dp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) 	int i, ndesc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) 	stamp = mon_get_timestamp();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) 	if (rp->nevents >= EVENT_MAX ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) 	    (ep = kmem_cache_alloc(rp->e_slab, GFP_ATOMIC)) == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) 		rp->r.m_bus->cnt_text_lost++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) 	ep->type = ev_type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) 	ep->id = (unsigned long) urb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) 	ep->busnum = urb->dev->bus->busnum;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) 	ep->devnum = urb->dev->devnum;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) 	ep->epnum = usb_endpoint_num(&urb->ep->desc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) 	ep->xfertype = usb_endpoint_type(&urb->ep->desc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) 	ep->is_in = usb_urb_dir_in(urb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) 	ep->tstamp = stamp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) 	ep->length = (ev_type == 'S') ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) 	    urb->transfer_buffer_length : urb->actual_length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) 	/* Collecting status makes debugging sense for submits, too */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) 	ep->status = status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) 	if (ep->xfertype == USB_ENDPOINT_XFER_INT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) 		ep->interval = urb->interval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) 	} else if (ep->xfertype == USB_ENDPOINT_XFER_ISOC) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) 		ep->interval = urb->interval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) 		ep->start_frame = urb->start_frame;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) 		ep->error_count = urb->error_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) 	ep->numdesc = urb->number_of_packets;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) 	if (ep->xfertype == USB_ENDPOINT_XFER_ISOC &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) 			urb->number_of_packets > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) 		if ((ndesc = urb->number_of_packets) > ISODESC_MAX)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) 			ndesc = ISODESC_MAX;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) 		fp = urb->iso_frame_desc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) 		dp = ep->isodesc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) 		for (i = 0; i < ndesc; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) 			dp->status = fp->status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) 			dp->offset = fp->offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) 			dp->length = (ev_type == 'S') ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) 			    fp->length : fp->actual_length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) 			fp++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) 			dp++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) 		/* Wasteful, but simple to understand: ISO 'C' is sparse. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) 		if (ev_type == 'C')
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) 			ep->length = urb->transfer_buffer_length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) 	ep->setup_flag = mon_text_get_setup(ep, urb, ev_type, rp->r.m_bus);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) 	ep->data_flag = mon_text_get_data(ep, urb, ep->length, ev_type,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) 			rp->r.m_bus);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) 	rp->nevents++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) 	list_add_tail(&ep->e_link, &rp->e_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) 	wake_up(&rp->wait);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) static void mon_text_submit(void *data, struct urb *urb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) 	struct mon_reader_text *rp = data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) 	mon_text_event(rp, urb, 'S', -EINPROGRESS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) static void mon_text_complete(void *data, struct urb *urb, int status)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) 	struct mon_reader_text *rp = data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) 	mon_text_event(rp, urb, 'C', status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) static void mon_text_error(void *data, struct urb *urb, int error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) 	struct mon_reader_text *rp = data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) 	struct mon_event_text *ep;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) 	if (rp->nevents >= EVENT_MAX ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) 	    (ep = kmem_cache_alloc(rp->e_slab, GFP_ATOMIC)) == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) 		rp->r.m_bus->cnt_text_lost++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) 	ep->type = 'E';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) 	ep->id = (unsigned long) urb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) 	ep->busnum = urb->dev->bus->busnum;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) 	ep->devnum = urb->dev->devnum;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) 	ep->epnum = usb_endpoint_num(&urb->ep->desc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) 	ep->xfertype = usb_endpoint_type(&urb->ep->desc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) 	ep->is_in = usb_urb_dir_in(urb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) 	ep->tstamp = mon_get_timestamp();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) 	ep->length = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) 	ep->status = error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) 	ep->setup_flag = '-';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) 	ep->data_flag = 'E';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) 	rp->nevents++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) 	list_add_tail(&ep->e_link, &rp->e_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) 	wake_up(&rp->wait);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302)  * Fetch next event from the circular buffer.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) static struct mon_event_text *mon_text_fetch(struct mon_reader_text *rp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305)     struct mon_bus *mbus)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) 	struct list_head *p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) 	unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) 	spin_lock_irqsave(&mbus->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) 	if (list_empty(&rp->e_list)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) 		spin_unlock_irqrestore(&mbus->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) 		return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) 	p = rp->e_list.next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) 	list_del(p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) 	--rp->nevents;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) 	spin_unlock_irqrestore(&mbus->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) 	return list_entry(p, struct mon_event_text, e_link);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) static int mon_text_open(struct inode *inode, struct file *file)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) 	struct mon_bus *mbus;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) 	struct mon_reader_text *rp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) 	int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) 	mutex_lock(&mon_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) 	mbus = inode->i_private;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) 	rp = kzalloc(sizeof(struct mon_reader_text), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) 	if (rp == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) 		rc = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) 		goto err_alloc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) 	INIT_LIST_HEAD(&rp->e_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) 	init_waitqueue_head(&rp->wait);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) 	mutex_init(&rp->printf_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) 	rp->printf_size = PRINTF_DFL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) 	rp->printf_buf = kmalloc(rp->printf_size, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) 	if (rp->printf_buf == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) 		rc = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) 		goto err_alloc_pr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) 	rp->r.m_bus = mbus;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) 	rp->r.r_data = rp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) 	rp->r.rnf_submit = mon_text_submit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) 	rp->r.rnf_error = mon_text_error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) 	rp->r.rnf_complete = mon_text_complete;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) 	snprintf(rp->slab_name, SLAB_NAME_SZ, "mon_text_%p", rp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) 	rp->e_slab = kmem_cache_create(rp->slab_name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) 	    sizeof(struct mon_event_text), sizeof(long), 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) 	    mon_text_ctor);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) 	if (rp->e_slab == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) 		rc = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) 		goto err_slab;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) 	mon_reader_add(mbus, &rp->r);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) 	file->private_data = rp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) 	mutex_unlock(&mon_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) // err_busy:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) //	kmem_cache_destroy(rp->e_slab);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) err_slab:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) 	kfree(rp->printf_buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) err_alloc_pr:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) 	kfree(rp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) err_alloc:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) 	mutex_unlock(&mon_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) 	return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) static ssize_t mon_text_copy_to_user(struct mon_reader_text *rp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382)     char __user * const buf, const size_t nbytes)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) 	const size_t togo = min(nbytes, rp->printf_togo);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) 	if (copy_to_user(buf, &rp->printf_buf[rp->printf_offset], togo))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) 		return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) 	rp->printf_togo -= togo;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) 	rp->printf_offset += togo;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) 	return togo;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) /* ppos is not advanced since the llseek operation is not permitted. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) static ssize_t mon_text_read_t(struct file *file, char __user *buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395)     size_t nbytes, loff_t *ppos)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) 	struct mon_reader_text *rp = file->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) 	struct mon_event_text *ep;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) 	struct mon_text_ptr ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) 	ssize_t ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) 	mutex_lock(&rp->printf_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) 	if (rp->printf_togo == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) 		ep = mon_text_read_wait(rp, file);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) 		if (IS_ERR(ep)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) 			mutex_unlock(&rp->printf_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) 			return PTR_ERR(ep);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) 		ptr.cnt = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) 		ptr.pbuf = rp->printf_buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) 		ptr.limit = rp->printf_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) 		mon_text_read_head_t(rp, &ptr, ep);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) 		mon_text_read_statset(rp, &ptr, ep);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) 		ptr.cnt += scnprintf(ptr.pbuf + ptr.cnt, ptr.limit - ptr.cnt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) 		    " %d", ep->length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) 		mon_text_read_data(rp, &ptr, ep);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) 		rp->printf_togo = ptr.cnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) 		rp->printf_offset = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) 		kmem_cache_free(rp->e_slab, ep);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) 	ret = mon_text_copy_to_user(rp, buf, nbytes);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) 	mutex_unlock(&rp->printf_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) /* ppos is not advanced since the llseek operation is not permitted. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) static ssize_t mon_text_read_u(struct file *file, char __user *buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434)     size_t nbytes, loff_t *ppos)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) 	struct mon_reader_text *rp = file->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) 	struct mon_event_text *ep;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) 	struct mon_text_ptr ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) 	ssize_t ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) 	mutex_lock(&rp->printf_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) 	if (rp->printf_togo == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) 		ep = mon_text_read_wait(rp, file);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) 		if (IS_ERR(ep)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) 			mutex_unlock(&rp->printf_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) 			return PTR_ERR(ep);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) 		ptr.cnt = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) 		ptr.pbuf = rp->printf_buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) 		ptr.limit = rp->printf_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) 		mon_text_read_head_u(rp, &ptr, ep);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) 		if (ep->type == 'E') {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) 			mon_text_read_statset(rp, &ptr, ep);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) 		} else if (ep->xfertype == USB_ENDPOINT_XFER_ISOC) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) 			mon_text_read_isostat(rp, &ptr, ep);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) 			mon_text_read_isodesc(rp, &ptr, ep);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) 		} else if (ep->xfertype == USB_ENDPOINT_XFER_INT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) 			mon_text_read_intstat(rp, &ptr, ep);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) 		} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) 			mon_text_read_statset(rp, &ptr, ep);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) 		ptr.cnt += scnprintf(ptr.pbuf + ptr.cnt, ptr.limit - ptr.cnt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) 		    " %d", ep->length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) 		mon_text_read_data(rp, &ptr, ep);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) 		rp->printf_togo = ptr.cnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) 		rp->printf_offset = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) 		kmem_cache_free(rp->e_slab, ep);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) 	ret = mon_text_copy_to_user(rp, buf, nbytes);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) 	mutex_unlock(&rp->printf_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) static struct mon_event_text *mon_text_read_wait(struct mon_reader_text *rp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481)     struct file *file)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) 	struct mon_bus *mbus = rp->r.m_bus;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) 	DECLARE_WAITQUEUE(waita, current);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) 	struct mon_event_text *ep;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) 	add_wait_queue(&rp->wait, &waita);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) 	set_current_state(TASK_INTERRUPTIBLE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) 	while ((ep = mon_text_fetch(rp, mbus)) == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) 		if (file->f_flags & O_NONBLOCK) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) 			set_current_state(TASK_RUNNING);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) 			remove_wait_queue(&rp->wait, &waita);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) 			return ERR_PTR(-EWOULDBLOCK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) 		 * We do not count nwaiters, because ->release is supposed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) 		 * to be called when all openers are gone only.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) 		schedule();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) 		if (signal_pending(current)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) 			remove_wait_queue(&rp->wait, &waita);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) 			return ERR_PTR(-EINTR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) 		set_current_state(TASK_INTERRUPTIBLE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) 	set_current_state(TASK_RUNNING);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) 	remove_wait_queue(&rp->wait, &waita);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) 	return ep;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) static void mon_text_read_head_t(struct mon_reader_text *rp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) 	struct mon_text_ptr *p, const struct mon_event_text *ep)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) 	char udir, utype;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) 	udir = (ep->is_in ? 'i' : 'o');
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) 	switch (ep->xfertype) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) 	case USB_ENDPOINT_XFER_ISOC:	utype = 'Z'; break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) 	case USB_ENDPOINT_XFER_INT:	utype = 'I'; break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) 	case USB_ENDPOINT_XFER_CONTROL:	utype = 'C'; break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) 	default: /* PIPE_BULK */  utype = 'B';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) 	p->cnt += scnprintf(p->pbuf + p->cnt, p->limit - p->cnt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) 	    "%lx %u %c %c%c:%03u:%02u",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) 	    ep->id, ep->tstamp, ep->type,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) 	    utype, udir, ep->devnum, ep->epnum);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) static void mon_text_read_head_u(struct mon_reader_text *rp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) 	struct mon_text_ptr *p, const struct mon_event_text *ep)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) 	char udir, utype;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) 	udir = (ep->is_in ? 'i' : 'o');
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) 	switch (ep->xfertype) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) 	case USB_ENDPOINT_XFER_ISOC:	utype = 'Z'; break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) 	case USB_ENDPOINT_XFER_INT:	utype = 'I'; break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) 	case USB_ENDPOINT_XFER_CONTROL:	utype = 'C'; break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) 	default: /* PIPE_BULK */  utype = 'B';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) 	p->cnt += scnprintf(p->pbuf + p->cnt, p->limit - p->cnt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) 	    "%lx %u %c %c%c:%d:%03u:%u",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) 	    ep->id, ep->tstamp, ep->type,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) 	    utype, udir, ep->busnum, ep->devnum, ep->epnum);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) static void mon_text_read_statset(struct mon_reader_text *rp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) 	struct mon_text_ptr *p, const struct mon_event_text *ep)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) 	if (ep->setup_flag == 0) {   /* Setup packet is present and captured */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) 		p->cnt += scnprintf(p->pbuf + p->cnt, p->limit - p->cnt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) 		    " s %02x %02x %04x %04x %04x",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) 		    ep->setup[0],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) 		    ep->setup[1],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) 		    (ep->setup[3] << 8) | ep->setup[2],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) 		    (ep->setup[5] << 8) | ep->setup[4],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) 		    (ep->setup[7] << 8) | ep->setup[6]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) 	} else if (ep->setup_flag != '-') { /* Unable to capture setup packet */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) 		p->cnt += scnprintf(p->pbuf + p->cnt, p->limit - p->cnt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) 		    " %c __ __ ____ ____ ____", ep->setup_flag);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) 	} else {                     /* No setup for this kind of URB */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) 		p->cnt += scnprintf(p->pbuf + p->cnt, p->limit - p->cnt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) 		    " %d", ep->status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) static void mon_text_read_intstat(struct mon_reader_text *rp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) 	struct mon_text_ptr *p, const struct mon_event_text *ep)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) 	p->cnt += scnprintf(p->pbuf + p->cnt, p->limit - p->cnt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) 	    " %d:%d", ep->status, ep->interval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) static void mon_text_read_isostat(struct mon_reader_text *rp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) 	struct mon_text_ptr *p, const struct mon_event_text *ep)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) 	if (ep->type == 'S') {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) 		p->cnt += scnprintf(p->pbuf + p->cnt, p->limit - p->cnt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) 		    " %d:%d:%d", ep->status, ep->interval, ep->start_frame);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) 		p->cnt += scnprintf(p->pbuf + p->cnt, p->limit - p->cnt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) 		    " %d:%d:%d:%d",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) 		    ep->status, ep->interval, ep->start_frame, ep->error_count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) static void mon_text_read_isodesc(struct mon_reader_text *rp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) 	struct mon_text_ptr *p, const struct mon_event_text *ep)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) 	int ndesc;	/* Display this many */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) 	const struct mon_iso_desc *dp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) 	p->cnt += scnprintf(p->pbuf + p->cnt, p->limit - p->cnt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) 	    " %d", ep->numdesc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) 	ndesc = ep->numdesc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) 	if (ndesc > ISODESC_MAX)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) 		ndesc = ISODESC_MAX;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) 	if (ndesc < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) 		ndesc = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) 	dp = ep->isodesc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) 	for (i = 0; i < ndesc; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) 		p->cnt += scnprintf(p->pbuf + p->cnt, p->limit - p->cnt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) 		    " %d:%u:%u", dp->status, dp->offset, dp->length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) 		dp++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) static void mon_text_read_data(struct mon_reader_text *rp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611)     struct mon_text_ptr *p, const struct mon_event_text *ep)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) 	int data_len, i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) 	if ((data_len = ep->length) > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) 		if (ep->data_flag == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) 			p->cnt += scnprintf(p->pbuf + p->cnt, p->limit - p->cnt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) 			    " =");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) 			if (data_len >= DATA_MAX)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) 				data_len = DATA_MAX;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) 			for (i = 0; i < data_len; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) 				if (i % 4 == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) 					p->cnt += scnprintf(p->pbuf + p->cnt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) 					    p->limit - p->cnt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) 					    " ");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) 				}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) 				p->cnt += scnprintf(p->pbuf + p->cnt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) 				    p->limit - p->cnt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) 				    "%02x", ep->data[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) 			p->cnt += scnprintf(p->pbuf + p->cnt, p->limit - p->cnt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) 			    "\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) 		} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) 			p->cnt += scnprintf(p->pbuf + p->cnt, p->limit - p->cnt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) 			    " %c\n", ep->data_flag);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) 		p->cnt += scnprintf(p->pbuf + p->cnt, p->limit - p->cnt, "\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) static int mon_text_release(struct inode *inode, struct file *file)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) 	struct mon_reader_text *rp = file->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) 	struct mon_bus *mbus;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) 	/* unsigned long flags; */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) 	struct list_head *p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) 	struct mon_event_text *ep;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) 	mutex_lock(&mon_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) 	mbus = inode->i_private;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) 	if (mbus->nreaders <= 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) 		printk(KERN_ERR TAG ": consistency error on close\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) 		mutex_unlock(&mon_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) 	mon_reader_del(mbus, &rp->r);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) 	 * In theory, e_list is protected by mbus->lock. However,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) 	 * after mon_reader_del has finished, the following is the case:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) 	 *  - we are not on reader list anymore, so new events won't be added;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) 	 *  - whole mbus may be dropped if it was orphaned.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) 	 * So, we better not touch mbus.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) 	/* spin_lock_irqsave(&mbus->lock, flags); */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) 	while (!list_empty(&rp->e_list)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) 		p = rp->e_list.next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) 		ep = list_entry(p, struct mon_event_text, e_link);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) 		list_del(p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) 		--rp->nevents;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) 		kmem_cache_free(rp->e_slab, ep);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) 	/* spin_unlock_irqrestore(&mbus->lock, flags); */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) 	kmem_cache_destroy(rp->e_slab);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) 	kfree(rp->printf_buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) 	kfree(rp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) 	mutex_unlock(&mon_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) static const struct file_operations mon_fops_text_t = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) 	.owner =	THIS_MODULE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) 	.open =		mon_text_open,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) 	.llseek =	no_llseek,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) 	.read =		mon_text_read_t,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) 	.release =	mon_text_release,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) static const struct file_operations mon_fops_text_u = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) 	.owner =	THIS_MODULE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) 	.open =		mon_text_open,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) 	.llseek =	no_llseek,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) 	.read =		mon_text_read_u,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) 	.release =	mon_text_release,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) int mon_text_add(struct mon_bus *mbus, const struct usb_bus *ubus)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) 	enum { NAMESZ = 10 };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) 	char name[NAMESZ];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) 	int busnum = ubus? ubus->busnum: 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) 	int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) 	if (mon_dir == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) 	if (ubus != NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) 		rc = snprintf(name, NAMESZ, "%dt", busnum);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) 		if (rc <= 0 || rc >= NAMESZ)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) 			goto err_print_t;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) 		mbus->dent_t = debugfs_create_file(name, 0600, mon_dir, mbus,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) 							     &mon_fops_text_t);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) 	rc = snprintf(name, NAMESZ, "%du", busnum);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) 	if (rc <= 0 || rc >= NAMESZ)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) 		goto err_print_u;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) 	mbus->dent_u = debugfs_create_file(name, 0600, mon_dir, mbus,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) 					   &mon_fops_text_u);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) 	rc = snprintf(name, NAMESZ, "%ds", busnum);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) 	if (rc <= 0 || rc >= NAMESZ)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) 		goto err_print_s;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) 	mbus->dent_s = debugfs_create_file(name, 0600, mon_dir, mbus,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) 					   &mon_fops_stat);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) 	return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) err_print_s:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) 	debugfs_remove(mbus->dent_u);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) 	mbus->dent_u = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) err_print_u:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) 	if (ubus != NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) 		debugfs_remove(mbus->dent_t);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) 		mbus->dent_t = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) err_print_t:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) void mon_text_del(struct mon_bus *mbus)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) 	debugfs_remove(mbus->dent_u);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) 	debugfs_remove(mbus->dent_t);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749) 	debugfs_remove(mbus->dent_s);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753)  * Slab interface: constructor.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) static void mon_text_ctor(void *mem)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) 	 * Nothing to initialize. No, really!
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) 	 * So, we fill it with garbage to emulate a reused object.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) 	memset(mem, 0xe5, sizeof(struct mon_event_text));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764) int __init mon_text_init(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) 	mon_dir = debugfs_create_dir("usbmon", usb_debug_root);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) void mon_text_exit(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772) 	debugfs_remove(mon_dir);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773) }