Mirror of strace – the linux syscall tracer
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

scsi.c 3.2KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166
  1. /*
  2. * Copyright (c) 2007 Vladimir Nadvornik <nadvornik@suse.cz>
  3. * Copyright (c) 2007-2018 Dmitry V. Levin <ldv@altlinux.org>
  4. * Copyright (c) 2007-2019 The strace developers.
  5. * All rights reserved.
  6. *
  7. * SPDX-License-Identifier: LGPL-2.1-or-later
  8. */
  9. #include "defs.h"
  10. #ifdef HAVE_SCSI_SG_H
  11. # include <scsi/sg.h>
  12. #endif
  13. #define XLAT_MACROS_ONLY
  14. # include "xlat/scsi_sg_commands.h"
  15. #undef XLAT_MACROS_ONLY
  16. #include "xlat/sg_scsi_reset.h"
  17. static int
  18. decode_sg_io(struct tcb *const tcp, const uint32_t iid,
  19. const kernel_ulong_t arg)
  20. {
  21. switch (iid) {
  22. case 'S':
  23. return decode_sg_io_v3(tcp, arg);
  24. case 'Q':
  25. return decode_sg_io_v4(tcp, arg);
  26. default:
  27. tprintf("[%u]", iid);
  28. return RVAL_IOCTL_DECODED;
  29. }
  30. }
  31. #ifdef HAVE_SCSI_SG_H
  32. static int
  33. decode_sg_scsi_id(struct tcb *const tcp, const kernel_ulong_t arg)
  34. {
  35. struct sg_scsi_id id;
  36. if (entering(tcp))
  37. return 0;
  38. tprints(", ");
  39. if (!umove_or_printaddr(tcp, arg, &id)) {
  40. tprintf("{host_no=%d"
  41. ", channel=%d"
  42. ", scsi_id=%#x"
  43. ", lun=%d"
  44. ", scsi_type=%#x"
  45. ", h_cmd_per_lun=%hd"
  46. ", d_queue_depth=%hd}",
  47. id.host_no,
  48. id.channel,
  49. id.scsi_id,
  50. id.lun,
  51. id.scsi_type,
  52. id.h_cmd_per_lun,
  53. id.d_queue_depth);
  54. }
  55. return RVAL_IOCTL_DECODED;
  56. }
  57. #endif /* HAVE_SCSI_SG_H */
  58. int
  59. scsi_ioctl(struct tcb *const tcp, const unsigned int code,
  60. const kernel_ulong_t arg)
  61. {
  62. switch (code) {
  63. case SG_IO:
  64. if (entering(tcp)) {
  65. uint32_t iid;
  66. tprints(", ");
  67. if (umove_or_printaddr(tcp, arg, &iid)) {
  68. break;
  69. } else {
  70. return decode_sg_io(tcp, iid, arg);
  71. }
  72. } else {
  73. uint32_t *piid = get_tcb_priv_data(tcp);
  74. if (piid)
  75. decode_sg_io(tcp, *piid, arg);
  76. tprints("}");
  77. break;
  78. }
  79. #ifdef HAVE_SCSI_SG_H
  80. /* returns struct sg_scsi_id */
  81. case SG_GET_SCSI_ID:
  82. return decode_sg_scsi_id(tcp, arg);
  83. /* returns struct sg_req_info */
  84. case SG_GET_REQUEST_TABLE:
  85. return decode_sg_req_info(tcp, arg);
  86. #endif /* HAVE_SCSI_SG_H */
  87. /* takes a value by pointer */
  88. case SG_SCSI_RESET: {
  89. unsigned int val;
  90. tprints(", ");
  91. if (!umove_or_printaddr(tcp, arg, &val)) {
  92. tprints("[");
  93. if (val & SG_SCSI_RESET_NO_ESCALATE) {
  94. printxval(sg_scsi_reset,
  95. SG_SCSI_RESET_NO_ESCALATE, 0);
  96. tprints("|");
  97. }
  98. printxval(sg_scsi_reset,
  99. val & ~SG_SCSI_RESET_NO_ESCALATE,
  100. "SG_SCSI_RESET_???");
  101. tprints("]");
  102. }
  103. break;
  104. }
  105. /* takes a signed int by pointer */
  106. case SG_NEXT_CMD_LEN:
  107. case SG_SET_COMMAND_Q:
  108. case SG_SET_DEBUG:
  109. case SG_SET_FORCE_LOW_DMA:
  110. case SG_SET_FORCE_PACK_ID:
  111. case SG_SET_KEEP_ORPHAN:
  112. case SG_SET_RESERVED_SIZE:
  113. case SG_SET_TIMEOUT:
  114. tprints(", ");
  115. printnum_int(tcp, arg, "%d");
  116. break;
  117. /* returns a signed int by pointer */
  118. case SG_EMULATED_HOST:
  119. case SG_GET_ACCESS_COUNT:
  120. case SG_GET_COMMAND_Q:
  121. case SG_GET_KEEP_ORPHAN:
  122. case SG_GET_LOW_DMA:
  123. case SG_GET_NUM_WAITING:
  124. case SG_GET_PACK_ID:
  125. case SG_GET_RESERVED_SIZE:
  126. case SG_GET_SG_TABLESIZE:
  127. case SG_GET_TRANSFORM:
  128. case SG_GET_VERSION_NUM:
  129. if (entering(tcp))
  130. return 0;
  131. tprints(", ");
  132. printnum_int(tcp, arg, "%d");
  133. break;
  134. /* takes an integer by value */
  135. case SG_SET_TRANSFORM:
  136. tprintf(", %#x", (unsigned int) arg);
  137. break;
  138. /* no arguments */
  139. case SG_GET_TIMEOUT:
  140. break;
  141. default:
  142. return RVAL_DECODED;
  143. }
  144. return RVAL_IOCTL_DECODED;
  145. }