Project

General

Profile

Bug #16084 ยป watch.d

Joshua M. Clulow, 2023-11-27 11:19 PM

 
1
#!/usr/sbin/dtrace -qCs
2

    
3
inline unsigned int DEVCTL_IOC = (0xDC << 16);
4
inline unsigned int DEVCTL_AP_GETSTATE = (DEVCTL_IOC | 20);
5
inline unsigned int DEVCTL_AP_CONTROL = (DEVCTL_IOC | 21);
6

    
7
inline string iocn[int r] =
8
    r == DEVCTL_AP_GETSTATE ? "DEVCTL_AP_GETSTATE" :
9
    r == DEVCTL_AP_CONTROL ? "DEVCTL_AP_CONTROL" :
10
    "?";
11

    
12
/*
13
 * Commands for DEVCTL_AP_CONTROL on USB devices.
14
 * See also "uts/common/sys/usb/hubd/hubd_impl.h", etc.
15
 */
16
#define HUBD_GET_CFGADM_NAME            0x10    /* get driver's name */
17
#define HUBD_GET_CURRENT_CONFIG         0x20    /* get current config index */
18
#define HUBD_GET_DEVICE_PATH            0x40    /* get /devices path */
19
#define HUBD_REFRESH_DEVDB              0x80    /* refresh USB device DB */
20
#define USB_DESCR_TYPE_DEV                      0x01
21
#define USB_DESCR_TYPE_STRING                   0x03
22
/*
23
 * With USB_DESCR_TYPE_STRING sub-command, these are the various
24
 * string sub-options.
25
 */
26
#define HUBD_MFG_STR            1               /* get manufacturer string */
27
#define HUBD_PRODUCT_STR        2               /* get product-id string */
28
#define HUBD_SERIALNO_STR       3               /* get serial-no-id string */
29
#define HUBD_CFG_DESCR_STR      4               /* get config descr string */
30

    
31
inline string cmdn[int r] =
32
    r == HUBD_GET_CFGADM_NAME ? "HUBD_GET_CFGADM_NAME" :
33
    r == HUBD_GET_CURRENT_CONFIG ? "HUBD_GET_CURRENT_CONFIG" :
34
    r == HUBD_GET_DEVICE_PATH ? "HUBD_GET_DEVICE_PATH" :
35
    r == HUBD_REFRESH_DEVDB ? "HUBD_REFRESH_DEVDB" :
36
    r == USB_DESCR_TYPE_DEV ? "USB_DESCR_TYPE_DEV" :
37
    r == USB_DESCR_TYPE_STRING ? "USB_DESCR_TYPE_STRING" :
38
    "?";
39

    
40
inline string miscn[int r] =
41
    r == HUBD_MFG_STR ? "HUBD_MFG_STR" :
42
    r == HUBD_PRODUCT_STR ? "HUBD_PRODUCT_STR" :
43
    r == HUBD_SERIALNO_STR ? "HUBD_SERIALNO_STR" :
44
    r == HUBD_CFG_DESCR_STR ? "HUBD_CFG_DESCR_STR" :
45
    "?";
46

    
47
inline string watch =
48
    "/devices/pci@0,0/pci1028,577@1a/hub@1/hub@2/hub@7:1.2.7.2";
49

    
50
syscall::open:return
51
/pid == $target && (this->fd = (int)arg1) >= 0
52
  && fds[this->fd].fi_pathname == watch/
53
{
54
	printf("%4d -> %s\n", this->fd, fds[this->fd].fi_pathname);
55
	watching[this->fd] = 1;
56
}
57

    
58
syscall::ioctl:entry
59
/pid == $target && watching[(this->fd = (int)arg0)]/
60
{
61
	self->req = (int)arg1;
62

    
63
	printf("%4d ioctl(req %08X [%s])\n", this->fd, self->req,
64
	    iocn[self->req]);
65

    
66
	self->sizep = (userland uint32_t *)NULL;
67
	if (self->req == DEVCTL_AP_CONTROL) {
68
		/*
69
		 * We know in this case that the argument is a struct
70
		 * hubd_ioctl_data because it is a USB device.
71
		 */
72
		if (curpsinfo->pr_dmodel == PR_MODEL_ILP32) {
73
			this->d32 = (userland hubd_ioctl_data_32_t *)arg2;
74
			print(*this->d32);
75
			this->cmd = this->d32->cmd;
76
			this->misc = this->d32->misc_arg;
77
			this->getsize = this->d32->get_size;
78
			if (this->getsize && this->d32->bufsiz == 4) {
79
				self->sizep =
80
				    (userland uint32_t *)this->d32->buf;
81
			}
82
		} else {
83
			this->d64 = (userland hubd_ioctl_data_t *)arg2;
84
			print(*this->d64);
85
			this->cmd = this->d64->cmd;
86
			this->misc = this->d64->misc_arg;
87
			this->getsize = this->d64->get_size;
88
			if (this->getsize && this->d64->bufsiz == 4) {
89
				self->sizep =
90
				    (userland uint32_t *)this->d64->buf;
91
			}
92
		}
93
		ustack();
94

    
95
		printf("    command = %s\n", cmdn[this->cmd]);
96
		if (this->cmd == USB_DESCR_TYPE_STRING) {
97
			printf("    misc arg = %s\n", miscn[this->misc]);
98
		}
99
		if (this->getsize) {
100
			printf("    is a get size request!\n");
101
		}
102

    
103
		printf("\n");
104
	}
105
}
106

    
107
syscall::ioctl:return
108
/pid == $target && self->req/
109
{
110
	this->ret = (int)arg1;
111

    
112
	printf("%4d ioctl(req %08X [%s]) -> %d, 0x%X [errno %d]\n",
113
	    this->fd, self->req, iocn[self->req],
114
	    this->ret, this->ret, errno);
115

    
116
	if (this->ret == 0 && self->sizep != NULL) {
117
		printf("    returned size = %d (0x%x)\n",
118
		    *self->sizep, *self->sizep);
119
		printf("\n");
120
	}
121

    
122
	self->req = 0;
123
	self->sizep = 0;
124
}
125

    
126
syscall::close:entry
127
/pid == $target && watching[(this->fd = (int)arg0)]/
128
{
129
	printf("%4d closed\n\n", this->fd);
130
	watching[this->fd] = 0;
131
}
    (1-1/1)