Merge branch 'release' of git://git.kernel.org/pub/scm/linux/kernel/git/aegl/linux-2.6
[pandora-kernel.git] / drivers / scsi / arm / scsi.h
1 /*
2  *  linux/drivers/acorn/scsi/scsi.h
3  *
4  *  Copyright (C) 2002 Russell King
5  *
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.
9  *
10  *  Commonly used scsi driver functions.
11  */
12
13 #include <linux/scatterlist.h>
14
15 #define BELT_AND_BRACES
16
17 /*
18  * The scatter-gather list handling.  This contains all
19  * the yucky stuff that needs to be fixed properly.
20  */
21 static inline int copy_SCp_to_sg(struct scatterlist *sg, struct scsi_pointer *SCp, int max)
22 {
23         int bufs = SCp->buffers_residual;
24
25         BUG_ON(bufs + 1 > max);
26
27         sg_set_buf(sg, SCp->ptr, SCp->this_residual);
28
29         if (bufs)
30                 memcpy(sg + 1, SCp->buffer + 1,
31                        sizeof(struct scatterlist) * bufs);
32         return bufs + 1;
33 }
34
35 static inline int next_SCp(struct scsi_pointer *SCp)
36 {
37         int ret = SCp->buffers_residual;
38         if (ret) {
39                 SCp->buffer++;
40                 SCp->buffers_residual--;
41                 SCp->ptr = (char *)
42                          (page_address(SCp->buffer->page) +
43                           SCp->buffer->offset);
44                 SCp->this_residual = SCp->buffer->length;
45         } else {
46                 SCp->ptr = NULL;
47                 SCp->this_residual = 0;
48         }
49         return ret;
50 }
51
52 static inline unsigned char get_next_SCp_byte(struct scsi_pointer *SCp)
53 {
54         char c = *SCp->ptr;
55
56         SCp->ptr += 1;
57         SCp->this_residual -= 1;
58
59         return c;
60 }
61
62 static inline void put_next_SCp_byte(struct scsi_pointer *SCp, unsigned char c)
63 {
64         *SCp->ptr = c;
65         SCp->ptr += 1;
66         SCp->this_residual -= 1;
67 }
68
69 static inline void init_SCp(Scsi_Cmnd *SCpnt)
70 {
71         memset(&SCpnt->SCp, 0, sizeof(struct scsi_pointer));
72
73         if (SCpnt->use_sg) {
74                 unsigned long len = 0;
75                 int buf;
76
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
84 #ifdef BELT_AND_BRACES
85                 /*
86                  * Calculate correct buffer length.  Some commands
87                  * come in with the wrong request_bufflen.
88                  */
89                 for (buf = 0; buf <= SCpnt->SCp.buffers_residual; buf++)
90                         len += SCpnt->SCp.buffer[buf].length;
91
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;
97 #endif
98         } else {
99                 SCpnt->SCp.ptr = (unsigned char *)SCpnt->request_buffer;
100                 SCpnt->SCp.this_residual = SCpnt->request_bufflen;
101         }
102
103         /*
104          * If the upper SCSI layers pass a buffer, but zero length,
105          * we aren't interested in the buffer pointer.
106          */
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);
112 #endif
113                 SCpnt->SCp.ptr = NULL;
114         }
115 }