scsi.h 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113
  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 = sg_virt(SCp->buffer);
  35. SCp->this_residual = SCp->buffer->length;
  36. } else {
  37. SCp->ptr = NULL;
  38. SCp->this_residual = 0;
  39. }
  40. return ret;
  41. }
  42. static inline unsigned char get_next_SCp_byte(struct scsi_pointer *SCp)
  43. {
  44. char c = *SCp->ptr;
  45. SCp->ptr += 1;
  46. SCp->this_residual -= 1;
  47. return c;
  48. }
  49. static inline void put_next_SCp_byte(struct scsi_pointer *SCp, unsigned char c)
  50. {
  51. *SCp->ptr = c;
  52. SCp->ptr += 1;
  53. SCp->this_residual -= 1;
  54. }
  55. static inline void init_SCp(struct scsi_cmnd *SCpnt)
  56. {
  57. memset(&SCpnt->SCp, 0, sizeof(struct scsi_pointer));
  58. if (SCpnt->use_sg) {
  59. unsigned long len = 0;
  60. int buf;
  61. SCpnt->SCp.buffer = (struct scatterlist *) SCpnt->request_buffer;
  62. SCpnt->SCp.buffers_residual = SCpnt->use_sg - 1;
  63. SCpnt->SCp.ptr = sg_virt(SCpnt->SCp.buffer);
  64. SCpnt->SCp.this_residual = SCpnt->SCp.buffer->length;
  65. SCpnt->SCp.phase = SCpnt->request_bufflen;
  66. #ifdef BELT_AND_BRACES
  67. /*
  68. * Calculate correct buffer length. Some commands
  69. * come in with the wrong request_bufflen.
  70. */
  71. for (buf = 0; buf <= SCpnt->SCp.buffers_residual; buf++)
  72. len += SCpnt->SCp.buffer[buf].length;
  73. if (SCpnt->request_bufflen != len)
  74. printk(KERN_WARNING "scsi%d.%c: bad request buffer "
  75. "length %d, should be %ld\n", SCpnt->device->host->host_no,
  76. '0' + SCpnt->device->id, SCpnt->request_bufflen, len);
  77. SCpnt->request_bufflen = len;
  78. #endif
  79. } else {
  80. SCpnt->SCp.ptr = (unsigned char *)SCpnt->request_buffer;
  81. SCpnt->SCp.this_residual = SCpnt->request_bufflen;
  82. SCpnt->SCp.phase = SCpnt->request_bufflen;
  83. }
  84. /*
  85. * If the upper SCSI layers pass a buffer, but zero length,
  86. * we aren't interested in the buffer pointer.
  87. */
  88. if (SCpnt->SCp.this_residual == 0 && SCpnt->SCp.ptr) {
  89. #if 0 //def BELT_AND_BRACES
  90. printk(KERN_WARNING "scsi%d.%c: zero length buffer passed for "
  91. "command ", SCpnt->host->host_no, '0' + SCpnt->target);
  92. __scsi_print_command(SCpnt->cmnd);
  93. #endif
  94. SCpnt->SCp.ptr = NULL;
  95. }
  96. }