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
--;
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(struct scsi_pointer
*SCp
)
57 SCp
->this_residual
-= 1;
62 static inline void put_next_SCp_byte(struct scsi_pointer
*SCp
, unsigned char c
)
66 SCp
->this_residual
-= 1;
69 static inline void init_SCp(struct scsi_cmnd
*SCpnt
)
71 memset(&SCpnt
->SCp
, 0, sizeof(struct scsi_pointer
));
74 unsigned long len
= 0;
77 SCpnt
->SCp
.buffer
= (struct scatterlist
*) SCpnt
->request_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
;
83 SCpnt
->SCp
.phase
= SCpnt
->request_bufflen
;
85 #ifdef BELT_AND_BRACES
87 * Calculate correct buffer length. Some commands
88 * come in with the wrong request_bufflen.
90 for (buf
= 0; buf
<= SCpnt
->SCp
.buffers_residual
; buf
++)
91 len
+= SCpnt
->SCp
.buffer
[buf
].length
;
93 if (SCpnt
->request_bufflen
!= len
)
94 printk(KERN_WARNING
"scsi%d.%c: bad request buffer "
95 "length %d, should be %ld\n", SCpnt
->device
->host
->host_no
,
96 '0' + SCpnt
->device
->id
, SCpnt
->request_bufflen
, len
);
97 SCpnt
->request_bufflen
= len
;
100 SCpnt
->SCp
.ptr
= (unsigned char *)SCpnt
->request_buffer
;
101 SCpnt
->SCp
.this_residual
= SCpnt
->request_bufflen
;
102 SCpnt
->SCp
.phase
= SCpnt
->request_bufflen
;
106 * If the upper SCSI layers pass a buffer, but zero length,
107 * we aren't interested in the buffer pointer.
109 if (SCpnt
->SCp
.this_residual
== 0 && SCpnt
->SCp
.ptr
) {
110 #if 0 //def BELT_AND_BRACES
111 printk(KERN_WARNING
"scsi%d.%c: zero length buffer passed for "
112 "command ", SCpnt
->host
->host_no
, '0' + SCpnt
->target
);
113 __scsi_print_command(SCpnt
->cmnd
);
115 SCpnt
->SCp
.ptr
= NULL
;