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.
21 static inline int copy_SCp_to_sg(struct scatterlist
*sg
, struct scsi_pointer
*SCp
, int max
)
23 int bufs
= SCp
->buffers_residual
;
25 BUG_ON(bufs
+ 1 > max
);
27 sg_set_buf(sg
, SCp
->ptr
, SCp
->this_residual
);
30 memcpy(sg
+ 1, SCp
->buffer
+ 1,
31 sizeof(struct scatterlist
) * bufs
);
35 static inline int next_SCp(struct scsi_pointer
*SCp
)
37 int ret
= SCp
->buffers_residual
;
40 SCp
->buffers_residual
--;
41 SCp
->ptr
= sg_virt(SCp
->buffer
);
42 SCp
->this_residual
= SCp
->buffer
->length
;
45 SCp
->this_residual
= 0;
50 static inline unsigned char get_next_SCp_byte(struct scsi_pointer
*SCp
)
55 SCp
->this_residual
-= 1;
60 static inline void put_next_SCp_byte(struct scsi_pointer
*SCp
, unsigned char c
)
64 SCp
->this_residual
-= 1;
67 static inline void init_SCp(struct scsi_cmnd
*SCpnt
)
69 memset(&SCpnt
->SCp
, 0, sizeof(struct scsi_pointer
));
72 unsigned long len
= 0;
75 SCpnt
->SCp
.buffer
= (struct scatterlist
*) SCpnt
->request_buffer
;
76 SCpnt
->SCp
.buffers_residual
= SCpnt
->use_sg
- 1;
77 SCpnt
->SCp
.ptr
= sg_virt(SCpnt
->SCp
.buffer
);
78 SCpnt
->SCp
.this_residual
= SCpnt
->SCp
.buffer
->length
;
79 SCpnt
->SCp
.phase
= SCpnt
->request_bufflen
;
81 #ifdef BELT_AND_BRACES
83 * Calculate correct buffer length. Some commands
84 * come in with the wrong request_bufflen.
86 for (buf
= 0; buf
<= SCpnt
->SCp
.buffers_residual
; buf
++)
87 len
+= SCpnt
->SCp
.buffer
[buf
].length
;
89 if (SCpnt
->request_bufflen
!= len
)
90 printk(KERN_WARNING
"scsi%d.%c: bad request buffer "
91 "length %d, should be %ld\n", SCpnt
->device
->host
->host_no
,
92 '0' + SCpnt
->device
->id
, SCpnt
->request_bufflen
, len
);
93 SCpnt
->request_bufflen
= len
;
96 SCpnt
->SCp
.ptr
= (unsigned char *)SCpnt
->request_buffer
;
97 SCpnt
->SCp
.this_residual
= SCpnt
->request_bufflen
;
98 SCpnt
->SCp
.phase
= SCpnt
->request_bufflen
;
102 * If the upper SCSI layers pass a buffer, but zero length,
103 * we aren't interested in the buffer pointer.
105 if (SCpnt
->SCp
.this_residual
== 0 && SCpnt
->SCp
.ptr
) {
106 #if 0 //def BELT_AND_BRACES
107 printk(KERN_WARNING
"scsi%d.%c: zero length buffer passed for "
108 "command ", SCpnt
->host
->host_no
, '0' + SCpnt
->target
);
109 __scsi_print_command(SCpnt
->cmnd
);
111 SCpnt
->SCp
.ptr
= NULL
;