diff options
author | Ingo Molnar <mingo@elte.hu> | 2009-10-29 04:02:15 -0400 |
---|---|---|
committer | Ingo Molnar <mingo@elte.hu> | 2009-10-29 04:02:20 -0400 |
commit | 9de09ace8d518141a4375e1d216ab64db4377799 (patch) | |
tree | da8e7a77f4ea91eb3bb73fc6da72ecf8c99e1c16 /drivers/scsi/bfa/bfa_core.c | |
parent | 1beee96bae0daf7f491356777c3080cc436950f5 (diff) | |
parent | 6d3f1e12f46a2f9a1bb7e7aa433df8dd31ce5647 (diff) |
Merge branch 'tracing/urgent' into tracing/core
Merge reason: Pick up fixes and move base from -rc1 to -rc5.
Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'drivers/scsi/bfa/bfa_core.c')
-rw-r--r-- | drivers/scsi/bfa/bfa_core.c | 402 |
1 files changed, 402 insertions, 0 deletions
diff --git a/drivers/scsi/bfa/bfa_core.c b/drivers/scsi/bfa/bfa_core.c new file mode 100644 index 000000000000..44e2d1155c51 --- /dev/null +++ b/drivers/scsi/bfa/bfa_core.c | |||
@@ -0,0 +1,402 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2005-2009 Brocade Communications Systems, Inc. | ||
3 | * All rights reserved | ||
4 | * www.brocade.com | ||
5 | * | ||
6 | * Linux driver for Brocade Fibre Channel Host Bus Adapter. | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify it | ||
9 | * under the terms of the GNU General Public License (GPL) Version 2 as | ||
10 | * published by the Free Software Foundation | ||
11 | * | ||
12 | * This program is distributed in the hope that it will be useful, but | ||
13 | * WITHOUT ANY WARRANTY; without even the implied warranty of | ||
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
15 | * General Public License for more details. | ||
16 | */ | ||
17 | |||
18 | #include <bfa.h> | ||
19 | #include <defs/bfa_defs_pci.h> | ||
20 | #include <cs/bfa_debug.h> | ||
21 | #include <bfa_iocfc.h> | ||
22 | |||
23 | #define DEF_CFG_NUM_FABRICS 1 | ||
24 | #define DEF_CFG_NUM_LPORTS 256 | ||
25 | #define DEF_CFG_NUM_CQS 4 | ||
26 | #define DEF_CFG_NUM_IOIM_REQS (BFA_IOIM_MAX) | ||
27 | #define DEF_CFG_NUM_TSKIM_REQS 128 | ||
28 | #define DEF_CFG_NUM_FCXP_REQS 64 | ||
29 | #define DEF_CFG_NUM_UF_BUFS 64 | ||
30 | #define DEF_CFG_NUM_RPORTS 1024 | ||
31 | #define DEF_CFG_NUM_ITNIMS (DEF_CFG_NUM_RPORTS) | ||
32 | #define DEF_CFG_NUM_TINS 256 | ||
33 | |||
34 | #define DEF_CFG_NUM_SGPGS 2048 | ||
35 | #define DEF_CFG_NUM_REQQ_ELEMS 256 | ||
36 | #define DEF_CFG_NUM_RSPQ_ELEMS 64 | ||
37 | #define DEF_CFG_NUM_SBOOT_TGTS 16 | ||
38 | #define DEF_CFG_NUM_SBOOT_LUNS 16 | ||
39 | |||
40 | /** | ||
41 | * Use this function query the memory requirement of the BFA library. | ||
42 | * This function needs to be called before bfa_attach() to get the | ||
43 | * memory required of the BFA layer for a given driver configuration. | ||
44 | * | ||
45 | * This call will fail, if the cap is out of range compared to pre-defined | ||
46 | * values within the BFA library | ||
47 | * | ||
48 | * @param[in] cfg - pointer to bfa_ioc_cfg_t. Driver layer should indicate | ||
49 | * its configuration in this structure. | ||
50 | * The default values for struct bfa_iocfc_cfg_s can be | ||
51 | * fetched using bfa_cfg_get_default() API. | ||
52 | * | ||
53 | * If cap's boundary check fails, the library will use | ||
54 | * the default bfa_cap_t values (and log a warning msg). | ||
55 | * | ||
56 | * @param[out] meminfo - pointer to bfa_meminfo_t. This content | ||
57 | * indicates the memory type (see bfa_mem_type_t) and | ||
58 | * amount of memory required. | ||
59 | * | ||
60 | * Driver should allocate the memory, populate the | ||
61 | * starting address for each block and provide the same | ||
62 | * structure as input parameter to bfa_attach() call. | ||
63 | * | ||
64 | * @return void | ||
65 | * | ||
66 | * Special Considerations: @note | ||
67 | */ | ||
68 | void | ||
69 | bfa_cfg_get_meminfo(struct bfa_iocfc_cfg_s *cfg, struct bfa_meminfo_s *meminfo) | ||
70 | { | ||
71 | int i; | ||
72 | u32 km_len = 0, dm_len = 0; | ||
73 | |||
74 | bfa_assert((cfg != NULL) && (meminfo != NULL)); | ||
75 | |||
76 | bfa_os_memset((void *)meminfo, 0, sizeof(struct bfa_meminfo_s)); | ||
77 | meminfo->meminfo[BFA_MEM_TYPE_KVA - 1].mem_type = | ||
78 | BFA_MEM_TYPE_KVA; | ||
79 | meminfo->meminfo[BFA_MEM_TYPE_DMA - 1].mem_type = | ||
80 | BFA_MEM_TYPE_DMA; | ||
81 | |||
82 | bfa_iocfc_meminfo(cfg, &km_len, &dm_len); | ||
83 | |||
84 | for (i = 0; hal_mods[i]; i++) | ||
85 | hal_mods[i]->meminfo(cfg, &km_len, &dm_len); | ||
86 | |||
87 | |||
88 | meminfo->meminfo[BFA_MEM_TYPE_KVA - 1].mem_len = km_len; | ||
89 | meminfo->meminfo[BFA_MEM_TYPE_DMA - 1].mem_len = dm_len; | ||
90 | } | ||
91 | |||
92 | /** | ||
93 | * Use this function to do attach the driver instance with the BFA | ||
94 | * library. This function will not trigger any HW initialization | ||
95 | * process (which will be done in bfa_init() call) | ||
96 | * | ||
97 | * This call will fail, if the cap is out of range compared to | ||
98 | * pre-defined values within the BFA library | ||
99 | * | ||
100 | * @param[out] bfa Pointer to bfa_t. | ||
101 | * @param[in] bfad Opaque handle back to the driver's IOC structure | ||
102 | * @param[in] cfg Pointer to bfa_ioc_cfg_t. Should be same structure | ||
103 | * that was used in bfa_cfg_get_meminfo(). | ||
104 | * @param[in] meminfo Pointer to bfa_meminfo_t. The driver should | ||
105 | * use the bfa_cfg_get_meminfo() call to | ||
106 | * find the memory blocks required, allocate the | ||
107 | * required memory and provide the starting addresses. | ||
108 | * @param[in] pcidev pointer to struct bfa_pcidev_s | ||
109 | * | ||
110 | * @return | ||
111 | * void | ||
112 | * | ||
113 | * Special Considerations: | ||
114 | * | ||
115 | * @note | ||
116 | * | ||
117 | */ | ||
118 | void | ||
119 | bfa_attach(struct bfa_s *bfa, void *bfad, struct bfa_iocfc_cfg_s *cfg, | ||
120 | struct bfa_meminfo_s *meminfo, struct bfa_pcidev_s *pcidev) | ||
121 | { | ||
122 | int i; | ||
123 | struct bfa_mem_elem_s *melem; | ||
124 | |||
125 | bfa->fcs = BFA_FALSE; | ||
126 | |||
127 | bfa_assert((cfg != NULL) && (meminfo != NULL)); | ||
128 | |||
129 | /** | ||
130 | * initialize all memory pointers for iterative allocation | ||
131 | */ | ||
132 | for (i = 0; i < BFA_MEM_TYPE_MAX; i++) { | ||
133 | melem = meminfo->meminfo + i; | ||
134 | melem->kva_curp = melem->kva; | ||
135 | melem->dma_curp = melem->dma; | ||
136 | } | ||
137 | |||
138 | bfa_iocfc_attach(bfa, bfad, cfg, meminfo, pcidev); | ||
139 | |||
140 | for (i = 0; hal_mods[i]; i++) | ||
141 | hal_mods[i]->attach(bfa, bfad, cfg, meminfo, pcidev); | ||
142 | |||
143 | } | ||
144 | |||
145 | /** | ||
146 | * Use this function to delete a BFA IOC. IOC should be stopped (by | ||
147 | * calling bfa_stop()) before this function call. | ||
148 | * | ||
149 | * @param[in] bfa - pointer to bfa_t. | ||
150 | * | ||
151 | * @return | ||
152 | * void | ||
153 | * | ||
154 | * Special Considerations: | ||
155 | * | ||
156 | * @note | ||
157 | */ | ||
158 | void | ||
159 | bfa_detach(struct bfa_s *bfa) | ||
160 | { | ||
161 | int i; | ||
162 | |||
163 | for (i = 0; hal_mods[i]; i++) | ||
164 | hal_mods[i]->detach(bfa); | ||
165 | |||
166 | bfa_iocfc_detach(bfa); | ||
167 | } | ||
168 | |||
169 | |||
170 | void | ||
171 | bfa_init_trc(struct bfa_s *bfa, struct bfa_trc_mod_s *trcmod) | ||
172 | { | ||
173 | bfa->trcmod = trcmod; | ||
174 | } | ||
175 | |||
176 | |||
177 | void | ||
178 | bfa_init_log(struct bfa_s *bfa, struct bfa_log_mod_s *logmod) | ||
179 | { | ||
180 | bfa->logm = logmod; | ||
181 | } | ||
182 | |||
183 | |||
184 | void | ||
185 | bfa_init_aen(struct bfa_s *bfa, struct bfa_aen_s *aen) | ||
186 | { | ||
187 | bfa->aen = aen; | ||
188 | } | ||
189 | |||
190 | void | ||
191 | bfa_init_plog(struct bfa_s *bfa, struct bfa_plog_s *plog) | ||
192 | { | ||
193 | bfa->plog = plog; | ||
194 | } | ||
195 | |||
196 | /** | ||
197 | * Initialize IOC. | ||
198 | * | ||
199 | * This function will return immediately, when the IOC initialization is | ||
200 | * completed, the bfa_cb_init() will be called. | ||
201 | * | ||
202 | * @param[in] bfa instance | ||
203 | * | ||
204 | * @return void | ||
205 | * | ||
206 | * Special Considerations: | ||
207 | * | ||
208 | * @note | ||
209 | * When this function returns, the driver should register the interrupt service | ||
210 | * routine(s) and enable the device interrupts. If this is not done, | ||
211 | * bfa_cb_init() will never get called | ||
212 | */ | ||
213 | void | ||
214 | bfa_init(struct bfa_s *bfa) | ||
215 | { | ||
216 | bfa_iocfc_init(bfa); | ||
217 | } | ||
218 | |||
219 | /** | ||
220 | * Use this function initiate the IOC configuration setup. This function | ||
221 | * will return immediately. | ||
222 | * | ||
223 | * @param[in] bfa instance | ||
224 | * | ||
225 | * @return None | ||
226 | */ | ||
227 | void | ||
228 | bfa_start(struct bfa_s *bfa) | ||
229 | { | ||
230 | bfa_iocfc_start(bfa); | ||
231 | } | ||
232 | |||
233 | /** | ||
234 | * Use this function quiese the IOC. This function will return immediately, | ||
235 | * when the IOC is actually stopped, the bfa_cb_stop() will be called. | ||
236 | * | ||
237 | * @param[in] bfa - pointer to bfa_t. | ||
238 | * | ||
239 | * @return None | ||
240 | * | ||
241 | * Special Considerations: | ||
242 | * bfa_cb_stop() could be called before or after bfa_stop() returns. | ||
243 | * | ||
244 | * @note | ||
245 | * In case of any failure, we could handle it automatically by doing a | ||
246 | * reset and then succeed the bfa_stop() call. | ||
247 | */ | ||
248 | void | ||
249 | bfa_stop(struct bfa_s *bfa) | ||
250 | { | ||
251 | bfa_iocfc_stop(bfa); | ||
252 | } | ||
253 | |||
254 | void | ||
255 | bfa_comp_deq(struct bfa_s *bfa, struct list_head *comp_q) | ||
256 | { | ||
257 | INIT_LIST_HEAD(comp_q); | ||
258 | list_splice_tail_init(&bfa->comp_q, comp_q); | ||
259 | } | ||
260 | |||
261 | void | ||
262 | bfa_comp_process(struct bfa_s *bfa, struct list_head *comp_q) | ||
263 | { | ||
264 | struct list_head *qe; | ||
265 | struct list_head *qen; | ||
266 | struct bfa_cb_qe_s *hcb_qe; | ||
267 | |||
268 | list_for_each_safe(qe, qen, comp_q) { | ||
269 | hcb_qe = (struct bfa_cb_qe_s *) qe; | ||
270 | hcb_qe->cbfn(hcb_qe->cbarg, BFA_TRUE); | ||
271 | } | ||
272 | } | ||
273 | |||
274 | void | ||
275 | bfa_comp_free(struct bfa_s *bfa, struct list_head *comp_q) | ||
276 | { | ||
277 | struct list_head *qe; | ||
278 | struct bfa_cb_qe_s *hcb_qe; | ||
279 | |||
280 | while (!list_empty(comp_q)) { | ||
281 | bfa_q_deq(comp_q, &qe); | ||
282 | hcb_qe = (struct bfa_cb_qe_s *) qe; | ||
283 | hcb_qe->cbfn(hcb_qe->cbarg, BFA_FALSE); | ||
284 | } | ||
285 | } | ||
286 | |||
287 | void | ||
288 | bfa_attach_fcs(struct bfa_s *bfa) | ||
289 | { | ||
290 | bfa->fcs = BFA_TRUE; | ||
291 | } | ||
292 | |||
293 | /** | ||
294 | * Periodic timer heart beat from driver | ||
295 | */ | ||
296 | void | ||
297 | bfa_timer_tick(struct bfa_s *bfa) | ||
298 | { | ||
299 | bfa_timer_beat(&bfa->timer_mod); | ||
300 | } | ||
301 | |||
302 | #ifndef BFA_BIOS_BUILD | ||
303 | /** | ||
304 | * Return the list of PCI vendor/device id lists supported by this | ||
305 | * BFA instance. | ||
306 | */ | ||
307 | void | ||
308 | bfa_get_pciids(struct bfa_pciid_s **pciids, int *npciids) | ||
309 | { | ||
310 | static struct bfa_pciid_s __pciids[] = { | ||
311 | {BFA_PCI_VENDOR_ID_BROCADE, BFA_PCI_DEVICE_ID_FC_8G2P}, | ||
312 | {BFA_PCI_VENDOR_ID_BROCADE, BFA_PCI_DEVICE_ID_FC_8G1P}, | ||
313 | {BFA_PCI_VENDOR_ID_BROCADE, BFA_PCI_DEVICE_ID_CT}, | ||
314 | }; | ||
315 | |||
316 | *npciids = sizeof(__pciids) / sizeof(__pciids[0]); | ||
317 | *pciids = __pciids; | ||
318 | } | ||
319 | |||
320 | /** | ||
321 | * Use this function query the default struct bfa_iocfc_cfg_s value (compiled | ||
322 | * into BFA layer). The OS driver can then turn back and overwrite entries that | ||
323 | * have been configured by the user. | ||
324 | * | ||
325 | * @param[in] cfg - pointer to bfa_ioc_cfg_t | ||
326 | * | ||
327 | * @return | ||
328 | * void | ||
329 | * | ||
330 | * Special Considerations: | ||
331 | * note | ||
332 | */ | ||
333 | void | ||
334 | bfa_cfg_get_default(struct bfa_iocfc_cfg_s *cfg) | ||
335 | { | ||
336 | cfg->fwcfg.num_fabrics = DEF_CFG_NUM_FABRICS; | ||
337 | cfg->fwcfg.num_lports = DEF_CFG_NUM_LPORTS; | ||
338 | cfg->fwcfg.num_rports = DEF_CFG_NUM_RPORTS; | ||
339 | cfg->fwcfg.num_ioim_reqs = DEF_CFG_NUM_IOIM_REQS; | ||
340 | cfg->fwcfg.num_tskim_reqs = DEF_CFG_NUM_TSKIM_REQS; | ||
341 | cfg->fwcfg.num_fcxp_reqs = DEF_CFG_NUM_FCXP_REQS; | ||
342 | cfg->fwcfg.num_uf_bufs = DEF_CFG_NUM_UF_BUFS; | ||
343 | cfg->fwcfg.num_cqs = DEF_CFG_NUM_CQS; | ||
344 | |||
345 | cfg->drvcfg.num_reqq_elems = DEF_CFG_NUM_REQQ_ELEMS; | ||
346 | cfg->drvcfg.num_rspq_elems = DEF_CFG_NUM_RSPQ_ELEMS; | ||
347 | cfg->drvcfg.num_sgpgs = DEF_CFG_NUM_SGPGS; | ||
348 | cfg->drvcfg.num_sboot_tgts = DEF_CFG_NUM_SBOOT_TGTS; | ||
349 | cfg->drvcfg.num_sboot_luns = DEF_CFG_NUM_SBOOT_LUNS; | ||
350 | cfg->drvcfg.path_tov = BFA_FCPIM_PATHTOV_DEF; | ||
351 | cfg->drvcfg.ioc_recover = BFA_FALSE; | ||
352 | cfg->drvcfg.delay_comp = BFA_FALSE; | ||
353 | |||
354 | } | ||
355 | |||
356 | void | ||
357 | bfa_cfg_get_min(struct bfa_iocfc_cfg_s *cfg) | ||
358 | { | ||
359 | bfa_cfg_get_default(cfg); | ||
360 | cfg->fwcfg.num_ioim_reqs = BFA_IOIM_MIN; | ||
361 | cfg->fwcfg.num_tskim_reqs = BFA_TSKIM_MIN; | ||
362 | cfg->fwcfg.num_fcxp_reqs = BFA_FCXP_MIN; | ||
363 | cfg->fwcfg.num_uf_bufs = BFA_UF_MIN; | ||
364 | cfg->fwcfg.num_rports = BFA_RPORT_MIN; | ||
365 | |||
366 | cfg->drvcfg.num_sgpgs = BFA_SGPG_MIN; | ||
367 | cfg->drvcfg.num_reqq_elems = BFA_REQQ_NELEMS_MIN; | ||
368 | cfg->drvcfg.num_rspq_elems = BFA_RSPQ_NELEMS_MIN; | ||
369 | cfg->drvcfg.min_cfg = BFA_TRUE; | ||
370 | } | ||
371 | |||
372 | void | ||
373 | bfa_get_attr(struct bfa_s *bfa, struct bfa_ioc_attr_s *ioc_attr) | ||
374 | { | ||
375 | bfa_ioc_get_attr(&bfa->ioc, ioc_attr); | ||
376 | } | ||
377 | |||
378 | /** | ||
379 | * Retrieve firmware trace information on IOC failure. | ||
380 | */ | ||
381 | bfa_status_t | ||
382 | bfa_debug_fwsave(struct bfa_s *bfa, void *trcdata, int *trclen) | ||
383 | { | ||
384 | return bfa_ioc_debug_fwsave(&bfa->ioc, trcdata, trclen); | ||
385 | } | ||
386 | |||
387 | /** | ||
388 | * Fetch firmware trace data. | ||
389 | * | ||
390 | * @param[in] bfa BFA instance | ||
391 | * @param[out] trcdata Firmware trace buffer | ||
392 | * @param[in,out] trclen Firmware trace buffer len | ||
393 | * | ||
394 | * @retval BFA_STATUS_OK Firmware trace is fetched. | ||
395 | * @retval BFA_STATUS_INPROGRESS Firmware trace fetch is in progress. | ||
396 | */ | ||
397 | bfa_status_t | ||
398 | bfa_debug_fwtrc(struct bfa_s *bfa, void *trcdata, int *trclen) | ||
399 | { | ||
400 | return bfa_ioc_debug_fwtrc(&bfa->ioc, trcdata, trclen); | ||
401 | } | ||
402 | #endif | ||