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