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.1KB

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