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 #define BELT_AND_BRACES
16 * The scatter-gather list handling. This contains all
17 * the yucky stuff that needs to be fixed properly.
19 static inline int copy_SCp_to_sg(struct scatterlist
*sg
, Scsi_Pointer
*SCp
, int max
)
21 int bufs
= SCp
->buffers_residual
;
23 BUG_ON(bufs
+ 1 > max
);
25 sg
->page
= virt_to_page(SCp
->ptr
);
26 sg
->offset
= offset_in_page(SCp
->ptr
);
27 sg
->length
= SCp
->this_residual
;
30 memcpy(sg
+ 1, SCp
->buffer
+ 1,
31 sizeof(struct scatterlist
) * bufs
);
35 static inline int next_SCp(Scsi_Pointer
*SCp
)
37 int ret
= SCp
->buffers_residual
;
40 SCp
->buffers_residual
--;
42 (page_address(SCp
->buffer
->page
) +
44 SCp
->this_residual
= SCp
->buffer
->length
;
47 SCp
->this_residual
= 0;
52 static inline unsigned char get_next_SCp_byte(Scsi_Pointer
*SCp
)
57 SCp
->this_residual
-= 1;
62 static inline void put_next_SCp_byte(Scsi_Pointer
*SCp
, unsigned char c
)
66 SCp
->this_residual
-= 1;
69 static inline void init_SCp(Scsi_Cmnd
*SCpnt
)
71 memset(&SCpnt
->SCp
, 0, sizeof(struct scsi_pointer
));
74 unsigned long len
= 0;
77 SCpnt
->SCp
.buffer
= (struct scatterlist
*) SCpnt
->buffer
;
78 SCpnt
->SCp
.buffers_residual
= SCpnt
->use_sg
- 1;
79 SCpnt
->SCp
.ptr
= (char *)
80 (page_address(SCpnt
->SCp
.buffer
->page
) +
81 SCpnt
->SCp
.buffer
->offset
);
82 SCpnt
->SCp
.this_residual
= SCpnt
->SCp
.buffer
->length
;
84 #ifdef BELT_AND_BRACES
86 * Calculate correct buffer length. Some commands
87 * come in with the wrong request_bufflen.
89 for (buf
= 0; buf
<= SCpnt
->SCp
.buffers_residual
; buf
++)
90 len
+= SCpnt
->SCp
.buffer
[buf
].length
;
92 if (SCpnt
->request_bufflen
!= len
)
93 printk(KERN_WARNING
"scsi%d.%c: bad request buffer "
94 "length %d, should be %ld\n", SCpnt
->device
->host
->host_no
,
95 '0' + SCpnt
->device
->id
, SCpnt
->request_bufflen
, len
);
96 SCpnt
->request_bufflen
= len
;
99 SCpnt
->SCp
.ptr
= (unsigned char *)SCpnt
->request_buffer
;
100 SCpnt
->SCp
.this_residual
= SCpnt
->request_bufflen
;
104 * If the upper SCSI layers pass a buffer, but zero length,
105 * we aren't interested in the buffer pointer.
107 if (SCpnt
->SCp
.this_residual
== 0 && SCpnt
->SCp
.ptr
) {
108 #if 0 //def BELT_AND_BRACES
109 printk(KERN_WARNING
"scsi%d.%c: zero length buffer passed for "
110 "command ", SCpnt
->host
->host_no
, '0' + SCpnt
->target
);
111 __scsi_print_command(SCpnt
->cmnd
);
113 SCpnt
->SCp
.ptr
= NULL
;