^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) }