1 /*-
2 * SPDX-License-Identifier: BSD-2-Clause
3 *
4 * Copyright (c) 2004-07 Applied Micro Circuits Corporation.
5 * Copyright (c) 2004-05 Vinod Kashyap
6 * All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
21 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27 * SUCH DAMAGE.
28 */
29
30 /*
31 * AMCC'S 3ware driver for 9000 series storage controllers.
32 *
33 * Author: Vinod Kashyap
34 * Modifications by: Adam Radford
35 * Modifications by: Manjunath Ranganathaiah
36 */
37
38 /*
39 * Common Layer initialization functions.
40 */
41
42 #include "tw_osl_share.h"
43 #include "tw_cl_share.h"
44 #include "tw_cl_fwif.h"
45 #include "tw_cl_ioctl.h"
46 #include "tw_cl.h"
47 #include "tw_cl_externs.h"
48 #include "tw_osl_ioctl.h"
49
50 /*
51 * Function name: tw_cl_ctlr_supported
52 * Description: Determines if a controller is supported.
53 *
54 * Input: vendor_id -- vendor id of the controller
55 * device_id -- device id of the controller
56 * Output: None
57 * Return value: TW_CL_TRUE-- controller supported
58 * TW_CL_FALSE-- controller not supported
59 */
60 TW_INT32
tw_cl_ctlr_supported(TW_INT32 vendor_id,TW_INT32 device_id)61 tw_cl_ctlr_supported(TW_INT32 vendor_id, TW_INT32 device_id)
62 {
63 if ((vendor_id == TW_CL_VENDOR_ID) &&
64 ((device_id == TW_CL_DEVICE_ID_9K) ||
65 (device_id == TW_CL_DEVICE_ID_9K_X) ||
66 (device_id == TW_CL_DEVICE_ID_9K_E) ||
67 (device_id == TW_CL_DEVICE_ID_9K_SA)))
68 return(TW_CL_TRUE);
69 return(TW_CL_FALSE);
70 }
71
72 /*
73 * Function name: tw_cl_get_pci_bar_info
74 * Description: Returns PCI BAR info.
75 *
76 * Input: device_id -- device id of the controller
77 * bar_type -- type of PCI BAR in question
78 * Output: bar_num -- PCI BAR number corresponding to bar_type
79 * bar0_offset -- byte offset from BAR 0 (0x10 in
80 * PCI config space)
81 * bar_size -- size, in bytes, of the BAR in question
82 * Return value: 0 -- success
83 * non-zero -- failure
84 */
85 TW_INT32
tw_cl_get_pci_bar_info(TW_INT32 device_id,TW_INT32 bar_type,TW_INT32 * bar_num,TW_INT32 * bar0_offset,TW_INT32 * bar_size)86 tw_cl_get_pci_bar_info(TW_INT32 device_id, TW_INT32 bar_type,
87 TW_INT32 *bar_num, TW_INT32 *bar0_offset, TW_INT32 *bar_size)
88 {
89 TW_INT32 error = TW_OSL_ESUCCESS;
90
91 switch(device_id) {
92 case TW_CL_DEVICE_ID_9K:
93 switch(bar_type) {
94 case TW_CL_BAR_TYPE_IO:
95 *bar_num = 0;
96 *bar0_offset = 0;
97 *bar_size = 4;
98 break;
99
100 case TW_CL_BAR_TYPE_MEM:
101 *bar_num = 1;
102 *bar0_offset = 0x4;
103 *bar_size = 8;
104 break;
105
106 case TW_CL_BAR_TYPE_SBUF:
107 *bar_num = 2;
108 *bar0_offset = 0xC;
109 *bar_size = 8;
110 break;
111 }
112 break;
113
114 case TW_CL_DEVICE_ID_9K_X:
115 case TW_CL_DEVICE_ID_9K_E:
116 case TW_CL_DEVICE_ID_9K_SA:
117 switch(bar_type) {
118 case TW_CL_BAR_TYPE_IO:
119 *bar_num = 2;
120 *bar0_offset = 0x10;
121 *bar_size = 4;
122 break;
123
124 case TW_CL_BAR_TYPE_MEM:
125 *bar_num = 1;
126 *bar0_offset = 0x8;
127 *bar_size = 8;
128 break;
129
130 case TW_CL_BAR_TYPE_SBUF:
131 *bar_num = 0;
132 *bar0_offset = 0;
133 *bar_size = 8;
134 break;
135 }
136 break;
137
138 default:
139 error = TW_OSL_ENOTTY;
140 break;
141 }
142
143 return(error);
144 }
145
146 /*
147 * Function name: tw_cl_get_mem_requirements
148 * Description: Provides info about Common Layer requirements for a
149 * controller, given the controller type (in 'flags').
150 * Input: ctlr_handle -- controller handle
151 * flags -- more info passed by the OS Layer
152 * device_id -- device id of the controller
153 * max_simult_reqs -- maximum # of simultaneous
154 * requests that the OS Layer expects
155 * the Common Layer to support
156 * max_aens -- maximun # of AEN's needed to be supported
157 * Output: alignment -- alignment needed for all DMA'able
158 * buffers
159 * sg_size_factor -- every SG element should have a size
160 * that's a multiple of this number
161 * non_dma_mem_size -- # of bytes of memory needed for
162 * non-DMA purposes
163 * dma_mem_size -- # of bytes of DMA'able memory needed
164 * per_req_dma_mem_size -- # of bytes of DMA'able memory
165 * needed per request, if applicable
166 * per_req_non_dma_mem_size -- # of bytes of memory needed
167 * per request for non-DMA purposes,
168 * if applicable
169 * Output: None
170 * Return value: 0 -- success
171 * non-zero-- failure
172 */
173 TW_INT32
tw_cl_get_mem_requirements(struct tw_cl_ctlr_handle * ctlr_handle,TW_UINT32 flags,TW_INT32 device_id,TW_INT32 max_simult_reqs,TW_INT32 max_aens,TW_UINT32 * alignment,TW_UINT32 * sg_size_factor,TW_UINT32 * non_dma_mem_size,TW_UINT32 * dma_mem_size)174 tw_cl_get_mem_requirements(struct tw_cl_ctlr_handle *ctlr_handle,
175 TW_UINT32 flags, TW_INT32 device_id, TW_INT32 max_simult_reqs,
176 TW_INT32 max_aens, TW_UINT32 *alignment, TW_UINT32 *sg_size_factor,
177 TW_UINT32 *non_dma_mem_size, TW_UINT32 *dma_mem_size
178 )
179 {
180 if (device_id == 0)
181 device_id = TW_CL_DEVICE_ID_9K;
182
183 if (max_simult_reqs > TW_CL_MAX_SIMULTANEOUS_REQUESTS) {
184 tw_cl_create_event(ctlr_handle, TW_CL_FALSE,
185 TW_CL_MESSAGE_SOURCE_COMMON_LAYER_ERROR,
186 0x1000, 0x1, TW_CL_SEVERITY_ERROR_STRING,
187 "Too many simultaneous requests to support!",
188 "requested = %d, supported = %d, error = %d\n",
189 max_simult_reqs, TW_CL_MAX_SIMULTANEOUS_REQUESTS,
190 TW_OSL_EBIG);
191 return(TW_OSL_EBIG);
192 }
193
194 *alignment = TWA_ALIGNMENT(device_id);
195 *sg_size_factor = TWA_SG_ELEMENT_SIZE_FACTOR(device_id);
196
197 /*
198 * Total non-DMA memory needed is the sum total of memory needed for
199 * the controller context, request packets (including the 1 needed for
200 * CL internal requests), and event packets.
201 */
202
203 *non_dma_mem_size = sizeof(struct tw_cli_ctlr_context) +
204 (sizeof(struct tw_cli_req_context) * max_simult_reqs) +
205 (sizeof(struct tw_cl_event_packet) * max_aens);
206
207 /*
208 * Total DMA'able memory needed is the sum total of memory needed for
209 * all command packets (including the 1 needed for CL internal
210 * requests), and memory needed to hold the payload for internal
211 * requests.
212 */
213
214 *dma_mem_size = (sizeof(struct tw_cl_command_packet) *
215 (max_simult_reqs)) + (TW_CLI_SECTOR_SIZE);
216
217 return(0);
218 }
219
220 /*
221 * Function name: tw_cl_init_ctlr
222 * Description: Initializes driver data structures for the controller.
223 *
224 * Input: ctlr_handle -- controller handle
225 * flags -- more info passed by the OS Layer
226 * device_id -- device id of the controller
227 * max_simult_reqs -- maximum # of simultaneous requests
228 * that the OS Layer expects the Common
229 * Layer to support
230 * max_aens -- maximun # of AEN's needed to be supported
231 * non_dma_mem -- ptr to allocated non-DMA memory
232 * dma_mem -- ptr to allocated DMA'able memory
233 * dma_mem_phys -- physical address of dma_mem
234 * Output: None
235 * Return value: 0 -- success
236 * non-zero-- failure
237 */
238 TW_INT32
tw_cl_init_ctlr(struct tw_cl_ctlr_handle * ctlr_handle,TW_UINT32 flags,TW_INT32 device_id,TW_INT32 max_simult_reqs,TW_INT32 max_aens,TW_VOID * non_dma_mem,TW_VOID * dma_mem,TW_UINT64 dma_mem_phys)239 tw_cl_init_ctlr(struct tw_cl_ctlr_handle *ctlr_handle, TW_UINT32 flags,
240 TW_INT32 device_id, TW_INT32 max_simult_reqs, TW_INT32 max_aens,
241 TW_VOID *non_dma_mem, TW_VOID *dma_mem, TW_UINT64 dma_mem_phys
242 )
243 {
244 struct tw_cli_ctlr_context *ctlr;
245 struct tw_cli_req_context *req;
246 TW_UINT8 *free_non_dma_mem;
247 TW_INT32 error = TW_OSL_ESUCCESS;
248 TW_INT32 i;
249
250 tw_cli_dbg_printf(3, ctlr_handle, tw_osl_cur_func(), "entered");
251
252 if (flags & TW_CL_START_CTLR_ONLY) {
253 ctlr = (struct tw_cli_ctlr_context *)
254 (ctlr_handle->cl_ctlr_ctxt);
255 goto start_ctlr;
256 }
257
258 if (max_simult_reqs > TW_CL_MAX_SIMULTANEOUS_REQUESTS) {
259 tw_cl_create_event(ctlr_handle, TW_CL_FALSE,
260 TW_CL_MESSAGE_SOURCE_COMMON_LAYER_ERROR,
261 0x1000, 0x1, TW_CL_SEVERITY_ERROR_STRING,
262 "Too many simultaneous requests to support!",
263 "requested = %d, supported = %d, error = %d\n",
264 max_simult_reqs, TW_CL_MAX_SIMULTANEOUS_REQUESTS,
265 TW_OSL_EBIG);
266 return(TW_OSL_EBIG);
267 }
268
269 if ((non_dma_mem == TW_CL_NULL) || (dma_mem == TW_CL_NULL)
270 ) {
271 tw_cl_create_event(ctlr_handle, TW_CL_FALSE,
272 TW_CL_MESSAGE_SOURCE_COMMON_LAYER_ERROR,
273 0x1001, 0x1, TW_CL_SEVERITY_ERROR_STRING,
274 "Insufficient memory for Common Layer's internal usage",
275 "error = %d\n", TW_OSL_ENOMEM);
276 return(TW_OSL_ENOMEM);
277 }
278
279 tw_osl_memzero(non_dma_mem, sizeof(struct tw_cli_ctlr_context) +
280 (sizeof(struct tw_cli_req_context) * max_simult_reqs) +
281 (sizeof(struct tw_cl_event_packet) * max_aens));
282
283 tw_osl_memzero(dma_mem,
284 (sizeof(struct tw_cl_command_packet) *
285 max_simult_reqs) +
286 TW_CLI_SECTOR_SIZE);
287
288 free_non_dma_mem = (TW_UINT8 *)non_dma_mem;
289
290 ctlr = (struct tw_cli_ctlr_context *)free_non_dma_mem;
291 free_non_dma_mem += sizeof(struct tw_cli_ctlr_context);
292
293 ctlr_handle->cl_ctlr_ctxt = ctlr;
294 ctlr->ctlr_handle = ctlr_handle;
295
296 ctlr->device_id = (TW_UINT32)device_id;
297 ctlr->arch_id = TWA_ARCH_ID(device_id);
298 ctlr->flags = flags;
299 ctlr->sg_size_factor = TWA_SG_ELEMENT_SIZE_FACTOR(device_id);
300 ctlr->max_simult_reqs = max_simult_reqs;
301 ctlr->max_aens_supported = max_aens;
302
303 /* Initialize queues of CL internal request context packets. */
304 tw_cli_req_q_init(ctlr, TW_CLI_FREE_Q);
305 tw_cli_req_q_init(ctlr, TW_CLI_BUSY_Q);
306 tw_cli_req_q_init(ctlr, TW_CLI_PENDING_Q);
307 tw_cli_req_q_init(ctlr, TW_CLI_COMPLETE_Q);
308 tw_cli_req_q_init(ctlr, TW_CLI_RESET_Q);
309
310 /* Initialize all locks used by CL. */
311 ctlr->gen_lock = &(ctlr->gen_lock_handle);
312 tw_osl_init_lock(ctlr_handle, "tw_cl_gen_lock", ctlr->gen_lock);
313 ctlr->io_lock = &(ctlr->io_lock_handle);
314 tw_osl_init_lock(ctlr_handle, "tw_cl_io_lock", ctlr->io_lock);
315
316 /* Initialize CL internal request context packets. */
317 ctlr->req_ctxt_buf = (struct tw_cli_req_context *)free_non_dma_mem;
318 free_non_dma_mem += (sizeof(struct tw_cli_req_context) *
319 max_simult_reqs);
320
321 ctlr->cmd_pkt_buf = (struct tw_cl_command_packet *)dma_mem;
322 ctlr->cmd_pkt_phys = dma_mem_phys;
323
324 ctlr->internal_req_data = (TW_UINT8 *)
325 (ctlr->cmd_pkt_buf +
326 max_simult_reqs);
327 ctlr->internal_req_data_phys = ctlr->cmd_pkt_phys +
328 (sizeof(struct tw_cl_command_packet) *
329 max_simult_reqs);
330
331 for (i = 0; i < max_simult_reqs; i++) {
332 req = &(ctlr->req_ctxt_buf[i]);
333
334 req->cmd_pkt = &(ctlr->cmd_pkt_buf[i]);
335 req->cmd_pkt_phys = ctlr->cmd_pkt_phys +
336 (i * sizeof(struct tw_cl_command_packet));
337
338 req->request_id = i;
339 req->ctlr = ctlr;
340
341 /* Insert request into the free queue. */
342 tw_cli_req_q_insert_tail(req, TW_CLI_FREE_Q);
343 }
344
345 /* Initialize the AEN queue. */
346 ctlr->aen_queue = (struct tw_cl_event_packet *)free_non_dma_mem;
347
348 start_ctlr:
349 /*
350 * Disable interrupts. Interrupts will be enabled in tw_cli_start_ctlr
351 * (only) if initialization succeeded.
352 */
353 tw_cli_disable_interrupts(ctlr);
354
355 /* Initialize the controller. */
356 if ((error = tw_cli_start_ctlr(ctlr))) {
357 /* Soft reset the controller, and try one more time. */
358 tw_cl_create_event(ctlr_handle, TW_CL_FALSE,
359 TW_CL_MESSAGE_SOURCE_COMMON_LAYER_ERROR,
360 0x1002, 0x1, TW_CL_SEVERITY_ERROR_STRING,
361 "Controller initialization failed. Retrying...",
362 "error = %d\n", error);
363 if ((error = tw_cli_soft_reset(ctlr))) {
364 tw_cl_create_event(ctlr_handle, TW_CL_FALSE,
365 TW_CL_MESSAGE_SOURCE_COMMON_LAYER_ERROR,
366 0x1003, 0x1, TW_CL_SEVERITY_ERROR_STRING,
367 "Controller soft reset failed",
368 "error = %d\n", error);
369 return(error);
370 } else if ((error = tw_cli_start_ctlr(ctlr))) {
371 tw_cl_create_event(ctlr_handle, TW_CL_FALSE,
372 TW_CL_MESSAGE_SOURCE_COMMON_LAYER_ERROR,
373 0x1004, 0x1, TW_CL_SEVERITY_ERROR_STRING,
374 "Controller initialization retry failed",
375 "error = %d\n", error);
376 return(error);
377 }
378 }
379 /* Notify some info about the controller to the OSL. */
380 tw_cli_notify_ctlr_info(ctlr);
381
382 /* Mark the controller active. */
383 ctlr->active = TW_CL_TRUE;
384 return(error);
385 }
386
387 /*
388 * Function name: tw_cli_start_ctlr
389 * Description: Establishes a logical connection with the controller.
390 * Determines whether or not the driver is compatible
391 * with the firmware on the controller, before proceeding
392 * to work with it.
393 *
394 * Input: ctlr -- ptr to per ctlr structure
395 * Output: None
396 * Return value: 0 -- success
397 * non-zero-- failure
398 */
399 TW_INT32
tw_cli_start_ctlr(struct tw_cli_ctlr_context * ctlr)400 tw_cli_start_ctlr(struct tw_cli_ctlr_context *ctlr)
401 {
402 TW_UINT16 fw_on_ctlr_srl = 0;
403 TW_UINT16 fw_on_ctlr_arch_id = 0;
404 TW_UINT16 fw_on_ctlr_branch = 0;
405 TW_UINT16 fw_on_ctlr_build = 0;
406 TW_UINT32 init_connect_result = 0;
407 TW_INT32 error = TW_OSL_ESUCCESS;
408
409 tw_cli_dbg_printf(3, ctlr->ctlr_handle, tw_osl_cur_func(), "entered");
410
411 /* Wait for the controller to become ready. */
412 if ((error = tw_cli_poll_status(ctlr,
413 TWA_STATUS_MICROCONTROLLER_READY,
414 TW_CLI_REQUEST_TIMEOUT_PERIOD))) {
415 tw_cl_create_event(ctlr->ctlr_handle, TW_CL_FALSE,
416 TW_CL_MESSAGE_SOURCE_COMMON_LAYER_ERROR,
417 0x1009, 0x1, TW_CL_SEVERITY_ERROR_STRING,
418 "Microcontroller not ready",
419 "error = %d", error);
420 return(error);
421 }
422 /* Drain the response queue. */
423 if ((error = tw_cli_drain_response_queue(ctlr))) {
424 tw_cl_create_event(ctlr->ctlr_handle, TW_CL_FALSE,
425 TW_CL_MESSAGE_SOURCE_COMMON_LAYER_ERROR,
426 0x100A, 0x1, TW_CL_SEVERITY_ERROR_STRING,
427 "Can't drain response queue",
428 "error = %d", error);
429 return(error);
430 }
431 /* Establish a logical connection with the controller. */
432 if ((error = tw_cli_init_connection(ctlr,
433 (TW_UINT16)(ctlr->max_simult_reqs),
434 TWA_EXTENDED_INIT_CONNECT, TWA_CURRENT_FW_SRL,
435 (TW_UINT16)(ctlr->arch_id),
436 TWA_CURRENT_FW_BRANCH(ctlr->arch_id),
437 TWA_CURRENT_FW_BUILD(ctlr->arch_id),
438 &fw_on_ctlr_srl, &fw_on_ctlr_arch_id,
439 &fw_on_ctlr_branch, &fw_on_ctlr_build,
440 &init_connect_result))) {
441 tw_cl_create_event(ctlr->ctlr_handle, TW_CL_FALSE,
442 TW_CL_MESSAGE_SOURCE_COMMON_LAYER_ERROR,
443 0x100B, 0x2, TW_CL_SEVERITY_WARNING_STRING,
444 "Can't initialize connection in current mode",
445 "error = %d", error);
446 return(error);
447 }
448 {
449 /* See if we can at least work with the firmware on the
450 * controller in the current mode.
451 */
452 if (init_connect_result & TWA_CTLR_FW_COMPATIBLE) {
453 /* Yes, we can. Make note of the operating mode. */
454 if (init_connect_result & TWA_CTLR_FW_SAME_OR_NEWER) {
455 ctlr->working_srl = TWA_CURRENT_FW_SRL;
456 ctlr->working_branch =
457 TWA_CURRENT_FW_BRANCH(ctlr->arch_id);
458 ctlr->working_build =
459 TWA_CURRENT_FW_BUILD(ctlr->arch_id);
460 } else {
461 ctlr->working_srl = fw_on_ctlr_srl;
462 ctlr->working_branch = fw_on_ctlr_branch;
463 ctlr->working_build = fw_on_ctlr_build;
464 }
465 } else {
466 /*
467 * No, we can't. See if we can at least work with
468 * it in the base mode.
469 */
470 tw_cl_create_event(ctlr->ctlr_handle, TW_CL_FALSE,
471 TW_CL_MESSAGE_SOURCE_COMMON_LAYER_ERROR,
472 0x1010, 0x2, TW_CL_SEVERITY_WARNING_STRING,
473 "Driver/Firmware mismatch. "
474 "Negotiating for base level...",
475 " ");
476 if ((error = tw_cli_init_connection(ctlr,
477 (TW_UINT16)(ctlr->max_simult_reqs),
478 TWA_EXTENDED_INIT_CONNECT,
479 TWA_BASE_FW_SRL,
480 (TW_UINT16)(ctlr->arch_id),
481 TWA_BASE_FW_BRANCH, TWA_BASE_FW_BUILD,
482 &fw_on_ctlr_srl, &fw_on_ctlr_arch_id,
483 &fw_on_ctlr_branch, &fw_on_ctlr_build,
484 &init_connect_result))) {
485 tw_cl_create_event(ctlr->ctlr_handle,
486 TW_CL_FALSE,
487 TW_CL_MESSAGE_SOURCE_COMMON_LAYER_ERROR,
488 0x1011, 0x1,
489 TW_CL_SEVERITY_ERROR_STRING,
490 "Can't initialize connection in "
491 "base mode",
492 " ");
493 return(error);
494 }
495 if (!(init_connect_result & TWA_CTLR_FW_COMPATIBLE)) {
496 /*
497 * The firmware on the controller is not even
498 * compatible with our base mode. We cannot
499 * work with it. Bail...
500 */
501 return(1);
502 }
503 /*
504 * We can work with this firmware, but only in
505 * base mode.
506 */
507 ctlr->working_srl = TWA_BASE_FW_SRL;
508 ctlr->working_branch = TWA_BASE_FW_BRANCH;
509 ctlr->working_build = TWA_BASE_FW_BUILD;
510 ctlr->operating_mode = TWA_BASE_MODE;
511 }
512 ctlr->fw_on_ctlr_srl = fw_on_ctlr_srl;
513 ctlr->fw_on_ctlr_branch = fw_on_ctlr_branch;
514 ctlr->fw_on_ctlr_build = fw_on_ctlr_build;
515 }
516
517 /* Drain the AEN queue */
518 if ((error = tw_cli_drain_aen_queue(ctlr)))
519 /*
520 * We will just print that we couldn't drain the AEN queue.
521 * There's no need to bail out.
522 */
523 tw_cl_create_event(ctlr->ctlr_handle, TW_CL_FALSE,
524 TW_CL_MESSAGE_SOURCE_COMMON_LAYER_ERROR,
525 0x1014, 0x2, TW_CL_SEVERITY_WARNING_STRING,
526 "Can't drain AEN queue",
527 "error = %d", error);
528
529 /* Enable interrupts. */
530 tw_cli_enable_interrupts(ctlr);
531
532 return(TW_OSL_ESUCCESS);
533 }
534
535 /*
536 * Function name: tw_cl_shutdown_ctlr
537 * Description: Closes logical connection with the controller.
538 *
539 * Input: ctlr -- ptr to per ctlr structure
540 * flags -- more info passed by the OS Layer
541 * Output: None
542 * Return value: 0 -- success
543 * non-zero-- failure
544 */
545 TW_INT32
tw_cl_shutdown_ctlr(struct tw_cl_ctlr_handle * ctlr_handle,TW_UINT32 flags)546 tw_cl_shutdown_ctlr(struct tw_cl_ctlr_handle *ctlr_handle, TW_UINT32 flags)
547 {
548 struct tw_cli_ctlr_context *ctlr =
549 (struct tw_cli_ctlr_context *)(ctlr_handle->cl_ctlr_ctxt);
550 TW_INT32 error;
551
552 tw_cli_dbg_printf(3, ctlr_handle, tw_osl_cur_func(), "entered");
553 /*
554 * Mark the controller as inactive, disable any further interrupts,
555 * and notify the controller that we are going down.
556 */
557 ctlr->active = TW_CL_FALSE;
558
559 tw_cli_disable_interrupts(ctlr);
560
561 /* Let the controller know that we are going down. */
562 if ((error = tw_cli_init_connection(ctlr, TWA_SHUTDOWN_MESSAGE_CREDITS,
563 0, 0, 0, 0, 0, TW_CL_NULL, TW_CL_NULL, TW_CL_NULL,
564 TW_CL_NULL, TW_CL_NULL)))
565 tw_cl_create_event(ctlr_handle, TW_CL_FALSE,
566 TW_CL_MESSAGE_SOURCE_COMMON_LAYER_ERROR,
567 0x1015, 0x1, TW_CL_SEVERITY_ERROR_STRING,
568 "Can't close connection with controller",
569 "error = %d", error);
570
571 if (flags & TW_CL_STOP_CTLR_ONLY)
572 goto ret;
573
574 /* Destroy all locks used by CL. */
575 tw_osl_destroy_lock(ctlr_handle, ctlr->gen_lock);
576 tw_osl_destroy_lock(ctlr_handle, ctlr->io_lock);
577
578 ret:
579 return(error);
580 }
581
582 /*
583 * Function name: tw_cli_init_connection
584 * Description: Sends init_connection cmd to firmware
585 *
586 * Input: ctlr -- ptr to per ctlr structure
587 * message_credits -- max # of requests that we might send
588 * down simultaneously. This will be
589 * typically set to 256 at init-time or
590 * after a reset, and to 1 at shutdown-time
591 * set_features -- indicates if we intend to use 64-bit
592 * sg, also indicates if we want to do a
593 * basic or an extended init_connection;
594 *
595 * Note: The following input/output parameters are valid, only in case of an
596 * extended init_connection:
597 *
598 * current_fw_srl -- srl of fw we are bundled
599 * with, if any; 0 otherwise
600 * current_fw_arch_id -- arch_id of fw we are bundled
601 * with, if any; 0 otherwise
602 * current_fw_branch -- branch # of fw we are bundled
603 * with, if any; 0 otherwise
604 * current_fw_build -- build # of fw we are bundled
605 * with, if any; 0 otherwise
606 * Output: fw_on_ctlr_srl -- srl of fw on ctlr
607 * fw_on_ctlr_arch_id -- arch_id of fw on ctlr
608 * fw_on_ctlr_branch -- branch # of fw on ctlr
609 * fw_on_ctlr_build -- build # of fw on ctlr
610 * init_connect_result -- result bitmap of fw response
611 * Return value: 0 -- success
612 * non-zero-- failure
613 */
614 TW_INT32
tw_cli_init_connection(struct tw_cli_ctlr_context * ctlr,TW_UINT16 message_credits,TW_UINT32 set_features,TW_UINT16 current_fw_srl,TW_UINT16 current_fw_arch_id,TW_UINT16 current_fw_branch,TW_UINT16 current_fw_build,TW_UINT16 * fw_on_ctlr_srl,TW_UINT16 * fw_on_ctlr_arch_id,TW_UINT16 * fw_on_ctlr_branch,TW_UINT16 * fw_on_ctlr_build,TW_UINT32 * init_connect_result)615 tw_cli_init_connection(struct tw_cli_ctlr_context *ctlr,
616 TW_UINT16 message_credits, TW_UINT32 set_features,
617 TW_UINT16 current_fw_srl, TW_UINT16 current_fw_arch_id,
618 TW_UINT16 current_fw_branch, TW_UINT16 current_fw_build,
619 TW_UINT16 *fw_on_ctlr_srl, TW_UINT16 *fw_on_ctlr_arch_id,
620 TW_UINT16 *fw_on_ctlr_branch, TW_UINT16 *fw_on_ctlr_build,
621 TW_UINT32 *init_connect_result)
622 {
623 struct tw_cli_req_context *req;
624 struct tw_cl_command_init_connect *init_connect;
625 TW_INT32 error = TW_OSL_EBUSY;
626
627 tw_cli_dbg_printf(3, ctlr->ctlr_handle, tw_osl_cur_func(), "entered");
628
629 /* Get a request packet. */
630 if ((req = tw_cli_get_request(ctlr
631 )) == TW_CL_NULL)
632 goto out;
633
634 req->flags |= TW_CLI_REQ_FLAGS_INTERNAL;
635
636 /* Build the cmd pkt. */
637 init_connect = &(req->cmd_pkt->command.cmd_pkt_7k.init_connect);
638
639 req->cmd_pkt->cmd_hdr.header_desc.size_header = 128;
640
641 init_connect->res1__opcode =
642 BUILD_RES__OPCODE(0, TWA_FW_CMD_INIT_CONNECTION);
643 init_connect->request_id =
644 (TW_UINT8)(TW_CL_SWAP16(req->request_id));
645 init_connect->message_credits = TW_CL_SWAP16(message_credits);
646 init_connect->features = TW_CL_SWAP32(set_features);
647 if (ctlr->flags & TW_CL_64BIT_ADDRESSES)
648 init_connect->features |= TW_CL_SWAP32(TWA_64BIT_SG_ADDRESSES);
649 if (set_features & TWA_EXTENDED_INIT_CONNECT) {
650 /*
651 * Fill in the extra fields needed for an extended
652 * init_connect.
653 */
654 init_connect->size = 6;
655 init_connect->fw_srl = TW_CL_SWAP16(current_fw_srl);
656 init_connect->fw_arch_id = TW_CL_SWAP16(current_fw_arch_id);
657 init_connect->fw_branch = TW_CL_SWAP16(current_fw_branch);
658 init_connect->fw_build = TW_CL_SWAP16(current_fw_build);
659 } else
660 init_connect->size = 3;
661
662 /* Submit the command, and wait for it to complete. */
663 error = tw_cli_submit_and_poll_request(req,
664 TW_CLI_REQUEST_TIMEOUT_PERIOD);
665 if (error)
666 goto out;
667 if ((error = init_connect->status)) {
668 #if 0
669 tw_cli_create_ctlr_event(ctlr,
670 TW_CL_MESSAGE_SOURCE_CONTROLLER_ERROR,
671 &(req->cmd_pkt->cmd_hdr));
672 #endif // 0
673 goto out;
674 }
675 if (set_features & TWA_EXTENDED_INIT_CONNECT) {
676 *fw_on_ctlr_srl = TW_CL_SWAP16(init_connect->fw_srl);
677 *fw_on_ctlr_arch_id = TW_CL_SWAP16(init_connect->fw_arch_id);
678 *fw_on_ctlr_branch = TW_CL_SWAP16(init_connect->fw_branch);
679 *fw_on_ctlr_build = TW_CL_SWAP16(init_connect->fw_build);
680 *init_connect_result = TW_CL_SWAP32(init_connect->result);
681 }
682 tw_cli_req_q_insert_tail(req, TW_CLI_FREE_Q);
683 return(error);
684
685 out:
686 tw_cl_create_event(ctlr->ctlr_handle, TW_CL_FALSE,
687 TW_CL_MESSAGE_SOURCE_COMMON_LAYER_ERROR,
688 0x1016, 0x1, TW_CL_SEVERITY_ERROR_STRING,
689 "init_connection failed",
690 "error = %d", error);
691 if (req)
692 tw_cli_req_q_insert_tail(req, TW_CLI_FREE_Q);
693 return(error);
694 }
695