~ubuntu-branches/ubuntu/precise/linux-lowlatency/precise

« back to all changes in this revision

Viewing changes to drivers/scsi/be2iscsi/be.h

  • Committer: Package Import Robot
  • Author(s): Alessio Igor Bogani
  • Date: 2011-10-26 11:13:05 UTC
  • Revision ID: package-import@ubuntu.com-20111026111305-tz023xykf0i6eosh
Tags: upstream-3.2.0
ImportĀ upstreamĀ versionĀ 3.2.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/**
 
2
 * Copyright (C) 2005 - 2011 Emulex
 
3
 * All rights reserved.
 
4
 *
 
5
 * This program is free software; you can redistribute it and/or
 
6
 * modify it under the terms of the GNU General Public License version 2
 
7
 * as published by the Free Software Foundation.  The full GNU General
 
8
 * Public License is included in this distribution in the file called COPYING.
 
9
 *
 
10
 * Contact Information:
 
11
 * linux-drivers@emulex.com
 
12
 *
 
13
 * Emulex
 
14
 * 3333 Susan Street
 
15
 * Costa Mesa, CA 92626
 
16
 */
 
17
 
 
18
#ifndef BEISCSI_H
 
19
#define BEISCSI_H
 
20
 
 
21
#include <linux/pci.h>
 
22
#include <linux/if_vlan.h>
 
23
#include <linux/blk-iopoll.h>
 
24
#define FW_VER_LEN      32
 
25
#define MCC_Q_LEN       128
 
26
#define MCC_CQ_LEN      256
 
27
#define MAX_MCC_CMD     16
 
28
/* BladeEngine Generation numbers */
 
29
#define BE_GEN2 2
 
30
#define BE_GEN3 3
 
31
 
 
32
struct be_dma_mem {
 
33
        void *va;
 
34
        dma_addr_t dma;
 
35
        u32 size;
 
36
};
 
37
 
 
38
struct be_queue_info {
 
39
        struct be_dma_mem dma_mem;
 
40
        u16 len;
 
41
        u16 entry_size;         /* Size of an element in the queue */
 
42
        u16 id;
 
43
        u16 tail, head;
 
44
        bool created;
 
45
        atomic_t used;          /* Number of valid elements in the queue */
 
46
};
 
47
 
 
48
static inline u32 MODULO(u16 val, u16 limit)
 
49
{
 
50
        WARN_ON(limit & (limit - 1));
 
51
        return val & (limit - 1);
 
52
}
 
53
 
 
54
static inline void index_inc(u16 *index, u16 limit)
 
55
{
 
56
        *index = MODULO((*index + 1), limit);
 
57
}
 
58
 
 
59
static inline void *queue_head_node(struct be_queue_info *q)
 
60
{
 
61
        return q->dma_mem.va + q->head * q->entry_size;
 
62
}
 
63
 
 
64
static inline void *queue_get_wrb(struct be_queue_info *q, unsigned int wrb_num)
 
65
{
 
66
        return q->dma_mem.va + wrb_num * q->entry_size;
 
67
}
 
68
 
 
69
static inline void *queue_tail_node(struct be_queue_info *q)
 
70
{
 
71
        return q->dma_mem.va + q->tail * q->entry_size;
 
72
}
 
73
 
 
74
static inline void queue_head_inc(struct be_queue_info *q)
 
75
{
 
76
        index_inc(&q->head, q->len);
 
77
}
 
78
 
 
79
static inline void queue_tail_inc(struct be_queue_info *q)
 
80
{
 
81
        index_inc(&q->tail, q->len);
 
82
}
 
83
 
 
84
/*ISCSI */
 
85
 
 
86
struct be_eq_obj {
 
87
        struct be_queue_info q;
 
88
        struct beiscsi_hba *phba;
 
89
        struct be_queue_info *cq;
 
90
        struct blk_iopoll       iopoll;
 
91
};
 
92
 
 
93
struct be_mcc_obj {
 
94
        struct be_queue_info q;
 
95
        struct be_queue_info cq;
 
96
};
 
97
 
 
98
struct be_ctrl_info {
 
99
        u8 __iomem *csr;
 
100
        u8 __iomem *db;         /* Door Bell */
 
101
        u8 __iomem *pcicfg;     /* PCI config space */
 
102
        struct pci_dev *pdev;
 
103
 
 
104
        /* Mbox used for cmd request/response */
 
105
        spinlock_t mbox_lock;   /* For serializing mbox cmds to BE card */
 
106
        struct be_dma_mem mbox_mem;
 
107
        /* Mbox mem is adjusted to align to 16 bytes. The allocated addr
 
108
         * is stored for freeing purpose */
 
109
        struct be_dma_mem mbox_mem_alloced;
 
110
 
 
111
        /* MCC Rings */
 
112
        struct be_mcc_obj mcc_obj;
 
113
        spinlock_t mcc_lock;    /* For serializing mcc cmds to BE card */
 
114
        spinlock_t mcc_cq_lock;
 
115
 
 
116
        wait_queue_head_t mcc_wait[MAX_MCC_CMD + 1];
 
117
        unsigned int mcc_tag[MAX_MCC_CMD];
 
118
        unsigned int mcc_numtag[MAX_MCC_CMD + 1];
 
119
        unsigned short mcc_alloc_index;
 
120
        unsigned short mcc_free_index;
 
121
        unsigned int mcc_tag_available;
 
122
};
 
123
 
 
124
#include "be_cmds.h"
 
125
 
 
126
#define PAGE_SHIFT_4K 12
 
127
#define PAGE_SIZE_4K (1 << PAGE_SHIFT_4K)
 
128
#define mcc_timeout             120000 /* 5s timeout */
 
129
 
 
130
/* Returns number of pages spanned by the data starting at the given addr */
 
131
#define PAGES_4K_SPANNED(_address, size)                                \
 
132
                ((u32)((((size_t)(_address) & (PAGE_SIZE_4K - 1)) +     \
 
133
                        (size) + (PAGE_SIZE_4K - 1)) >> PAGE_SHIFT_4K))
 
134
 
 
135
/* Byte offset into the page corresponding to given address */
 
136
#define OFFSET_IN_PAGE(addr)                                            \
 
137
                ((size_t)(addr) & (PAGE_SIZE_4K-1))
 
138
 
 
139
/* Returns bit offset within a DWORD of a bitfield */
 
140
#define AMAP_BIT_OFFSET(_struct, field)                                 \
 
141
                (((size_t)&(((_struct *)0)->field))%32)
 
142
 
 
143
/* Returns the bit mask of the field that is NOT shifted into location. */
 
144
static inline u32 amap_mask(u32 bitsize)
 
145
{
 
146
        return (bitsize == 32 ? 0xFFFFFFFF : (1 << bitsize) - 1);
 
147
}
 
148
 
 
149
static inline void amap_set(void *ptr, u32 dw_offset, u32 mask,
 
150
                                        u32 offset, u32 value)
 
151
{
 
152
        u32 *dw = (u32 *) ptr + dw_offset;
 
153
        *dw &= ~(mask << offset);
 
154
        *dw |= (mask & value) << offset;
 
155
}
 
156
 
 
157
#define AMAP_SET_BITS(_struct, field, ptr, val)                         \
 
158
                amap_set(ptr,                                           \
 
159
                        offsetof(_struct, field)/32,                    \
 
160
                        amap_mask(sizeof(((_struct *)0)->field)),       \
 
161
                        AMAP_BIT_OFFSET(_struct, field),                \
 
162
                        val)
 
163
 
 
164
static inline u32 amap_get(void *ptr, u32 dw_offset, u32 mask, u32 offset)
 
165
{
 
166
        u32 *dw = ptr;
 
167
        return mask & (*(dw + dw_offset) >> offset);
 
168
}
 
169
 
 
170
#define AMAP_GET_BITS(_struct, field, ptr)                              \
 
171
                amap_get(ptr,                                           \
 
172
                        offsetof(_struct, field)/32,                    \
 
173
                        amap_mask(sizeof(((_struct *)0)->field)),       \
 
174
                        AMAP_BIT_OFFSET(_struct, field))
 
175
 
 
176
#define be_dws_cpu_to_le(wrb, len) swap_dws(wrb, len)
 
177
#define be_dws_le_to_cpu(wrb, len) swap_dws(wrb, len)
 
178
static inline void swap_dws(void *wrb, int len)
 
179
{
 
180
#ifdef __BIG_ENDIAN
 
181
        u32 *dw = wrb;
 
182
        WARN_ON(len % 4);
 
183
        do {
 
184
                *dw = cpu_to_le32(*dw);
 
185
                dw++;
 
186
                len -= 4;
 
187
        } while (len);
 
188
#endif /* __BIG_ENDIAN */
 
189
}
 
190
#endif /* BEISCSI_H */