]> granicus.if.org Git - strace/blob - scsi.c
Cleanup after non-Linux code removal.
[strace] / scsi.c
1 #include "defs.h"
2
3 #include <sys/ioctl.h>
4 #include <scsi/sg.h>
5
6 static const struct xlat sg_io_dxfer_direction[] = {
7         {SG_DXFER_NONE,        "SG_DXFER_NONE"},
8         {SG_DXFER_TO_DEV,      "SG_DXFER_TO_DEV"},
9         {SG_DXFER_FROM_DEV,    "SG_DXFER_FROM_DEV"},
10         {SG_DXFER_TO_FROM_DEV, "SG_DXFER_TO_FROM_DEV"},
11         {0, NULL}
12 };
13
14 static void
15 print_sg_io_buffer(struct tcb *tcp, unsigned char *addr, int len)
16 {
17         unsigned char *buf = NULL;
18         int     allocated, i;
19
20         if (len == 0)
21                 return;
22         allocated = (len > max_strlen) ? max_strlen : len;
23         if (len < 0 ||
24             (buf = malloc(allocated)) == NULL ||
25             umoven(tcp, (unsigned long) addr, allocated, (char *) buf) < 0) {
26                 tprintf("%p", addr);
27                 free(buf);
28                 return;
29         }
30         tprintf("%02x", buf[0]);
31         for (i = 1; i < allocated; ++i)
32                 tprintf(", %02x", buf[i]);
33         free(buf);
34         if (allocated != len)
35                 tprints(", ...");
36 }
37
38 static void
39 print_sg_io_req(struct tcb *tcp, struct sg_io_hdr *sg_io)
40 {
41         tprintf("{'%c', ", sg_io->interface_id);
42         printxval(sg_io_dxfer_direction, sg_io->dxfer_direction,
43                   "SG_DXFER_???");
44         tprintf(", cmd[%u]=[", sg_io->cmd_len);
45         print_sg_io_buffer(tcp, sg_io->cmdp, sg_io->cmd_len);
46         tprintf("], mx_sb_len=%d, ", sg_io->mx_sb_len);
47         tprintf("iovec_count=%d, ", sg_io->iovec_count);
48         tprintf("dxfer_len=%u, ", sg_io->dxfer_len);
49         tprintf("timeout=%u, ", sg_io->timeout);
50         tprintf("flags=%#x", sg_io->flags);
51
52         if (sg_io->dxfer_direction == SG_DXFER_TO_DEV ||
53             sg_io->dxfer_direction == SG_DXFER_TO_FROM_DEV) {
54                 tprintf(", data[%u]=[", sg_io->dxfer_len);
55                 printstr(tcp, (unsigned long) sg_io->dxferp,
56                          sg_io->dxfer_len);
57                 tprints("]");
58         }
59 }
60
61 static void
62 print_sg_io_res(struct tcb *tcp, struct sg_io_hdr *sg_io)
63 {
64         if (sg_io->dxfer_direction == SG_DXFER_FROM_DEV ||
65             sg_io->dxfer_direction == SG_DXFER_TO_FROM_DEV) {
66                 tprintf(", data[%u]=[", sg_io->dxfer_len);
67                 printstr(tcp, (unsigned long) sg_io->dxferp,
68                          sg_io->dxfer_len);
69                 tprints("]");
70         }
71         tprintf(", status=%02x, ", sg_io->status);
72         tprintf("masked_status=%02x, ", sg_io->masked_status);
73         tprintf("sb[%u]=[", sg_io->sb_len_wr);
74         print_sg_io_buffer(tcp, sg_io->sbp, sg_io->sb_len_wr);
75         tprintf("], host_status=%#x, ", sg_io->host_status);
76         tprintf("driver_status=%#x, ", sg_io->driver_status);
77         tprintf("resid=%d, ", sg_io->resid);
78         tprintf("duration=%d, ", sg_io->duration);
79         tprintf("info=%#x}", sg_io->info);
80 }
81
82 int
83 scsi_ioctl(struct tcb *tcp, long code, long arg)
84 {
85         switch (code) {
86         case SG_IO:
87                 if (entering(tcp)) {
88                         struct sg_io_hdr sg_io;
89
90                         if (umove(tcp, arg, &sg_io) < 0)
91                                 tprintf(", %#lx", arg);
92                         else {
93                                 tprints(", ");
94                                 print_sg_io_req(tcp, &sg_io);
95                         }
96                 }
97                 if (exiting(tcp)) {
98                         struct sg_io_hdr sg_io;
99
100                         if (!syserror(tcp) && umove(tcp, arg, &sg_io) >= 0)
101                                 print_sg_io_res(tcp, &sg_io);
102                         else
103                                 tprints("}");
104                 }
105                 break;
106         default:
107                 if (entering(tcp))
108                         tprintf(", %#lx", arg);
109                 break;
110         }
111         return 1;
112 }