arm_scsi.h 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136
  1. /* SPDX-License-Identifier: GPL-2.0-only */
  2. /*
  3. * Copyright (C) 2002 Russell King
  4. *
  5. * Commonly used functions by the ARM SCSI-II drivers.
  6. */
  7. #include <linux/scatterlist.h>
  8. #define BELT_AND_BRACES
  9. struct arm_cmd_priv {
  10. struct scsi_pointer scsi_pointer;
  11. };
  12. static inline struct scsi_pointer *arm_scsi_pointer(struct scsi_cmnd *cmd)
  13. {
  14. struct arm_cmd_priv *acmd = scsi_cmd_priv(cmd);
  15. return &acmd->scsi_pointer;
  16. }
  17. /*
  18. * The scatter-gather list handling. This contains all
  19. * the yucky stuff that needs to be fixed properly.
  20. */
  21. /*
  22. * copy_SCp_to_sg() Assumes contiguous allocation at @sg of at-most @max
  23. * entries of uninitialized memory. SCp is from scsi-ml and has a valid
  24. * (possibly chained) sg-list
  25. */
  26. static inline int copy_SCp_to_sg(struct scatterlist *sg, struct scsi_pointer *SCp, int max)
  27. {
  28. int bufs = SCp->buffers_residual;
  29. /* FIXME: It should be easy for drivers to loop on copy_SCp_to_sg().
  30. * and to remove this BUG_ON. Use min() in-its-place
  31. */
  32. BUG_ON(bufs + 1 > max);
  33. sg_set_buf(sg, SCp->ptr, SCp->this_residual);
  34. if (bufs) {
  35. struct scatterlist *src_sg;
  36. unsigned i;
  37. for_each_sg(sg_next(SCp->buffer), src_sg, bufs, i)
  38. *(++sg) = *src_sg;
  39. sg_mark_end(sg);
  40. }
  41. return bufs + 1;
  42. }
  43. static inline int next_SCp(struct scsi_pointer *SCp)
  44. {
  45. int ret = SCp->buffers_residual;
  46. if (ret) {
  47. SCp->buffer = sg_next(SCp->buffer);
  48. SCp->buffers_residual--;
  49. SCp->ptr = sg_virt(SCp->buffer);
  50. SCp->this_residual = SCp->buffer->length;
  51. } else {
  52. SCp->ptr = NULL;
  53. SCp->this_residual = 0;
  54. }
  55. return ret;
  56. }
  57. static inline unsigned char get_next_SCp_byte(struct scsi_pointer *SCp)
  58. {
  59. char c = *SCp->ptr;
  60. SCp->ptr += 1;
  61. SCp->this_residual -= 1;
  62. return c;
  63. }
  64. static inline void put_next_SCp_byte(struct scsi_pointer *SCp, unsigned char c)
  65. {
  66. *SCp->ptr = c;
  67. SCp->ptr += 1;
  68. SCp->this_residual -= 1;
  69. }
  70. static inline void init_SCp(struct scsi_cmnd *SCpnt)
  71. {
  72. struct scsi_pointer *scsi_pointer = arm_scsi_pointer(SCpnt);
  73. memset(scsi_pointer, 0, sizeof(struct scsi_pointer));
  74. if (scsi_bufflen(SCpnt)) {
  75. unsigned long len = 0;
  76. scsi_pointer->buffer = scsi_sglist(SCpnt);
  77. scsi_pointer->buffers_residual = scsi_sg_count(SCpnt) - 1;
  78. scsi_pointer->ptr = sg_virt(scsi_pointer->buffer);
  79. scsi_pointer->this_residual = scsi_pointer->buffer->length;
  80. scsi_pointer->phase = scsi_bufflen(SCpnt);
  81. #ifdef BELT_AND_BRACES
  82. { /*
  83. * Calculate correct buffer length. Some commands
  84. * come in with the wrong scsi_bufflen.
  85. */
  86. struct scatterlist *sg;
  87. unsigned i, sg_count = scsi_sg_count(SCpnt);
  88. scsi_for_each_sg(SCpnt, sg, sg_count, i)
  89. len += sg->length;
  90. if (scsi_bufflen(SCpnt) != len) {
  91. printk(KERN_WARNING
  92. "scsi%d.%c: bad request buffer "
  93. "length %d, should be %ld\n",
  94. SCpnt->device->host->host_no,
  95. '0' + SCpnt->device->id,
  96. scsi_bufflen(SCpnt), len);
  97. /*
  98. * FIXME: Totaly naive fixup. We should abort
  99. * with error
  100. */
  101. scsi_pointer->phase =
  102. min_t(unsigned long, len,
  103. scsi_bufflen(SCpnt));
  104. }
  105. }
  106. #endif
  107. } else {
  108. scsi_pointer->ptr = NULL;
  109. scsi_pointer->this_residual = 0;
  110. scsi_pointer->phase = 0;
  111. }
  112. }