2 * linux/drivers/acorn/scsi/scsi.h
4 * Copyright (C) 2002 Russell King
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.
10 * Commonly used scsi driver functions.
13 #include <linux/scatterlist.h>
15 #define BELT_AND_BRACES
18 * The scatter-gather list handling. This contains all
19 * the yucky stuff that needs to be fixed properly.
23 * copy_SCp_to_sg() Assumes contiguous allocation at @sg of at-most @max
24 * entries of uninitialized memory. SCp is from scsi-ml and has a valid
25 * (possibly chained) sg-list
27 static inline int copy_SCp_to_sg(struct scatterlist
*sg
, struct scsi_pointer
*SCp
, int max
)
29 int bufs
= SCp
->buffers_residual
;
31 /* FIXME: It should be easy for drivers to loop on copy_SCp_to_sg().
32 * and to remove this BUG_ON. Use min() in-its-place
34 BUG_ON(bufs
+ 1 > max
);
36 sg_set_buf(sg
, SCp
->ptr
, SCp
->this_residual
);
39 struct scatterlist
*src_sg
;
42 for_each_sg(sg_next(SCp
->buffer
), src_sg
, bufs
, i
)
50 static inline int next_SCp(struct scsi_pointer
*SCp
)
52 int ret
= SCp
->buffers_residual
;
54 SCp
->buffer
= sg_next(SCp
->buffer
);
55 SCp
->buffers_residual
--;
56 SCp
->ptr
= sg_virt(SCp
->buffer
);
57 SCp
->this_residual
= SCp
->buffer
->length
;
60 SCp
->this_residual
= 0;
65 static inline unsigned char get_next_SCp_byte(struct scsi_pointer
*SCp
)
70 SCp
->this_residual
-= 1;
75 static inline void put_next_SCp_byte(struct scsi_pointer
*SCp
, unsigned char c
)
79 SCp
->this_residual
-= 1;
82 static inline void init_SCp(struct scsi_cmnd
*SCpnt
)
84 memset(&SCpnt
->SCp
, 0, sizeof(struct scsi_pointer
));
86 if (scsi_bufflen(SCpnt
)) {
87 unsigned long len
= 0;
89 SCpnt
->SCp
.buffer
= scsi_sglist(SCpnt
);
90 SCpnt
->SCp
.buffers_residual
= scsi_sg_count(SCpnt
) - 1;
91 SCpnt
->SCp
.ptr
= sg_virt(SCpnt
->SCp
.buffer
);
92 SCpnt
->SCp
.this_residual
= SCpnt
->SCp
.buffer
->length
;
93 SCpnt
->SCp
.phase
= scsi_bufflen(SCpnt
);
95 #ifdef BELT_AND_BRACES
97 * Calculate correct buffer length. Some commands
98 * come in with the wrong scsi_bufflen.
100 struct scatterlist
*sg
;
101 unsigned i
, sg_count
= scsi_sg_count(SCpnt
);
103 scsi_for_each_sg(SCpnt
, sg
, sg_count
, i
)
106 if (scsi_bufflen(SCpnt
) != len
) {
108 "scsi%d.%c: bad request buffer "
109 "length %d, should be %ld\n",
110 SCpnt
->device
->host
->host_no
,
111 '0' + SCpnt
->device
->id
,
112 scsi_bufflen(SCpnt
), len
);
114 * FIXME: Totaly naive fixup. We should abort
118 min_t(unsigned long, len
,
119 scsi_bufflen(SCpnt
));
124 SCpnt
->SCp
.ptr
= NULL
;
125 SCpnt
->SCp
.this_residual
= 0;
126 SCpnt
->SCp
.phase
= 0;