scsi.h 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115
  1. /*
  2. * linux/drivers/acorn/scsi/scsi.h
  3. *
  4. * Copyright (C) 2002 Russell King
  5. *
  6. * This program is free software; you can redistribute it and/or modify
  7. * it under the terms of the GNU General Public License version 2 as
  8. * published by the Free Software Foundation.
  9. *
  10. * Commonly used scsi driver functions.
  11. */
  12. #include <linux/scatterlist.h>
  13. #define BELT_AND_BRACES
  14. /*
  15. * The scatter-gather list handling. This contains all
  16. * the yucky stuff that needs to be fixed properly.
  17. */
  18. static inline int copy_SCp_to_sg(struct scatterlist *sg, struct scsi_pointer *SCp, int max)
  19. {
  20. int bufs = SCp->buffers_residual;
  21. BUG_ON(bufs + 1 > max);
  22. sg_set_buf(sg, SCp->ptr, SCp->this_residual);
  23. if (bufs)
  24. memcpy(sg + 1, SCp->buffer + 1,
  25. sizeof(struct scatterlist) * bufs);
  26. return bufs + 1;
  27. }
  28. static inline int next_SCp(struct scsi_pointer *SCp)
  29. {
  30. int ret = SCp->buffers_residual;
  31. if (ret) {
  32. SCp->buffer++;
  33. SCp->buffers_residual--;
  34. SCp->ptr = (char *)
  35. (page_address(SCp->buffer->page) +
  36. SCp->buffer->offset);
  37. SCp->this_residual = SCp->buffer->length;
  38. } else {
  39. SCp->ptr = NULL;
  40. SCp->this_residual = 0;
  41. }
  42. return ret;
  43. }
  44. static inline unsigned char get_next_SCp_byte(struct scsi_pointer *SCp)
  45. {
  46. char c = *SCp->ptr;
  47. SCp->ptr += 1;
  48. SCp->this_residual -= 1;
  49. return c;
  50. }
  51. static inline void put_next_SCp_byte(struct scsi_pointer *SCp, unsigned char c)
  52. {
  53. *SCp->ptr = c;
  54. SCp->ptr += 1;
  55. SCp->this_residual -= 1;
  56. }
  57. static inline void init_SCp(Scsi_Cmnd *SCpnt)
  58. {
  59. memset(&SCpnt->SCp, 0, sizeof(struct scsi_pointer));
  60. if (SCpnt->use_sg) {
  61. unsigned long len = 0;
  62. int buf;
  63. SCpnt->SCp.buffer = (struct scatterlist *) SCpnt->buffer;
  64. SCpnt->SCp.buffers_residual = SCpnt->use_sg - 1;
  65. SCpnt->SCp.ptr = (char *)
  66. (page_address(SCpnt->SCp.buffer->page) +
  67. SCpnt->SCp.buffer->offset);
  68. SCpnt->SCp.this_residual = SCpnt->SCp.buffer->length;
  69. #ifdef BELT_AND_BRACES
  70. /*
  71. * Calculate correct buffer length. Some commands
  72. * come in with the wrong request_bufflen.
  73. */
  74. for (buf = 0; buf <= SCpnt->SCp.buffers_residual; buf++)
  75. len += SCpnt->SCp.buffer[buf].length;
  76. if (SCpnt->request_bufflen != len)
  77. printk(KERN_WARNING "scsi%d.%c: bad request buffer "
  78. "length %d, should be %ld\n", SCpnt->device->host->host_no,
  79. '0' + SCpnt->device->id, SCpnt->request_bufflen, len);
  80. SCpnt->request_bufflen = len;
  81. #endif
  82. } else {
  83. SCpnt->SCp.ptr = (unsigned char *)SCpnt->request_buffer;
  84. SCpnt->SCp.this_residual = SCpnt->request_bufflen;
  85. }
  86. /*
  87. * If the upper SCSI layers pass a buffer, but zero length,
  88. * we aren't interested in the buffer pointer.
  89. */
  90. if (SCpnt->SCp.this_residual == 0 && SCpnt->SCp.ptr) {
  91. #if 0 //def BELT_AND_BRACES
  92. printk(KERN_WARNING "scsi%d.%c: zero length buffer passed for "
  93. "command ", SCpnt->host->host_no, '0' + SCpnt->target);
  94. __scsi_print_command(SCpnt->cmnd);
  95. #endif
  96. SCpnt->SCp.ptr = NULL;
  97. }
  98. }