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. #define BELT_AND_BRACES
  13. /*
  14. * The scatter-gather list handling. This contains all
  15. * the yucky stuff that needs to be fixed properly.
  16. */
  17. static inline int copy_SCp_to_sg(struct scatterlist *sg, Scsi_Pointer *SCp, int max)
  18. {
  19. int bufs = SCp->buffers_residual;
  20. BUG_ON(bufs + 1 > max);
  21. sg->page = virt_to_page(SCp->ptr);
  22. sg->offset = offset_in_page(SCp->ptr);
  23. sg->length = SCp->this_residual;
  24. if (bufs)
  25. memcpy(sg + 1, SCp->buffer + 1,
  26. sizeof(struct scatterlist) * bufs);
  27. return bufs + 1;
  28. }
  29. static inline int next_SCp(Scsi_Pointer *SCp)
  30. {
  31. int ret = SCp->buffers_residual;
  32. if (ret) {
  33. SCp->buffer++;
  34. SCp->buffers_residual--;
  35. SCp->ptr = (char *)
  36. (page_address(SCp->buffer->page) +
  37. SCp->buffer->offset);
  38. SCp->this_residual = SCp->buffer->length;
  39. } else {
  40. SCp->ptr = NULL;
  41. SCp->this_residual = 0;
  42. }
  43. return ret;
  44. }
  45. static inline unsigned char get_next_SCp_byte(Scsi_Pointer *SCp)
  46. {
  47. char c = *SCp->ptr;
  48. SCp->ptr += 1;
  49. SCp->this_residual -= 1;
  50. return c;
  51. }
  52. static inline void put_next_SCp_byte(Scsi_Pointer *SCp, unsigned char c)
  53. {
  54. *SCp->ptr = c;
  55. SCp->ptr += 1;
  56. SCp->this_residual -= 1;
  57. }
  58. static inline void init_SCp(Scsi_Cmnd *SCpnt)
  59. {
  60. memset(&SCpnt->SCp, 0, sizeof(struct scsi_pointer));
  61. if (SCpnt->use_sg) {
  62. unsigned long len = 0;
  63. int buf;
  64. SCpnt->SCp.buffer = (struct scatterlist *) SCpnt->buffer;
  65. SCpnt->SCp.buffers_residual = SCpnt->use_sg - 1;
  66. SCpnt->SCp.ptr = (char *)
  67. (page_address(SCpnt->SCp.buffer->page) +
  68. SCpnt->SCp.buffer->offset);
  69. SCpnt->SCp.this_residual = SCpnt->SCp.buffer->length;
  70. #ifdef BELT_AND_BRACES
  71. /*
  72. * Calculate correct buffer length. Some commands
  73. * come in with the wrong request_bufflen.
  74. */
  75. for (buf = 0; buf <= SCpnt->SCp.buffers_residual; buf++)
  76. len += SCpnt->SCp.buffer[buf].length;
  77. if (SCpnt->request_bufflen != len)
  78. printk(KERN_WARNING "scsi%d.%c: bad request buffer "
  79. "length %d, should be %ld\n", SCpnt->device->host->host_no,
  80. '0' + SCpnt->device->id, SCpnt->request_bufflen, len);
  81. SCpnt->request_bufflen = len;
  82. #endif
  83. } else {
  84. SCpnt->SCp.ptr = (unsigned char *)SCpnt->request_buffer;
  85. SCpnt->SCp.this_residual = SCpnt->request_bufflen;
  86. }
  87. /*
  88. * If the upper SCSI layers pass a buffer, but zero length,
  89. * we aren't interested in the buffer pointer.
  90. */
  91. if (SCpnt->SCp.this_residual == 0 && SCpnt->SCp.ptr) {
  92. #if 0 //def BELT_AND_BRACES
  93. printk(KERN_WARNING "scsi%d.%c: zero length buffer passed for "
  94. "command ", SCpnt->host->host_no, '0' + SCpnt->target);
  95. __scsi_print_command(SCpnt->cmnd);
  96. #endif
  97. SCpnt->SCp.ptr = NULL;
  98. }
  99. }