FreeBSD/Linux Kernel Cross Reference
sys/dev/twa/twa.c
1 /*-
2 * Copyright (c) 2003-04 3ware, Inc.
3 * Copyright (c) 2000 Michael Smith
4 * Copyright (c) 2000 BSDi
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
17 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
20 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26 * SUCH DAMAGE.
27 *
28 * $FreeBSD$
29 */
30
31 /*
32 * 3ware driver for 9000 series storage controllers.
33 *
34 * Author: Vinod Kashyap
35 */
36
37
38 #include <dev/twa/twa_includes.h>
39
40 #ifdef TWA_FLASH_FIRMWARE
41 static int twa_flash_firmware(struct twa_softc *sc);
42 static int twa_hard_reset(struct twa_softc *sc);
43 #endif /* TWA_FLASH_FIRMWARE */
44
45 static int twa_init_ctlr(struct twa_softc *sc);
46 static void *twa_get_param(struct twa_softc *sc, int table_id,
47 int parameter_id, size_t size,
48 void (* callback)(struct twa_request *tr));
49 static int twa_set_param(struct twa_softc *sc, int table_id, int param_id,
50 int param_size, void *data,
51 void (* callback)(struct twa_request *tr));
52 static int twa_init_connection(struct twa_softc *sc, u_int16_t message_credits,
53 u_int32_t set_features, u_int16_t current_fw_srl,
54 u_int16_t current_fw_arch_id, u_int16_t current_fw_branch,
55 u_int16_t current_fw_build, u_int16_t *fw_on_ctlr_srl,
56 u_int16_t *fw_on_ctlr_arch_id, u_int16_t *fw_on_ctlr_branch,
57 u_int16_t *fw_on_ctlr_build, u_int32_t *init_connect_result);
58
59 static int twa_wait_request(struct twa_request *req, u_int32_t timeout);
60 static int twa_immediate_request(struct twa_request *req, u_int32_t timeout);
61
62 static int twa_done(struct twa_softc *sc);
63 static int twa_drain_pending_queue(struct twa_softc *sc);
64 static void twa_drain_complete_queue(struct twa_softc *sc);
65 static int twa_wait_status(struct twa_softc *sc, u_int32_t status, u_int32_t timeout);
66 static int twa_drain_response_queue(struct twa_softc *sc);
67 static int twa_check_ctlr_state(struct twa_softc *sc, u_int32_t status_reg);
68 static int twa_soft_reset(struct twa_softc *sc);
69
70 static void twa_host_intr(struct twa_softc *sc);
71 static void twa_attention_intr(struct twa_softc *sc);
72 static void twa_command_intr(struct twa_softc *sc);
73
74 static int twa_fetch_aen(struct twa_softc *sc);
75 static void twa_aen_callback(struct twa_request *tr);
76 static unsigned short twa_enqueue_aen(struct twa_softc *sc,
77 struct twa_command_header *cmd_hdr);
78 static int twa_drain_aen_queue(struct twa_softc *sc);
79 static int twa_find_aen(struct twa_softc *sc, u_int16_t aen_code);
80
81 static void twa_panic(struct twa_softc *sc, int8_t *reason);
82
83 /*
84 * Function name: twa_setup
85 * Description: Initializes driver data structures for the controller.
86 *
87 * Input: sc -- ptr to per ctlr structure
88 * Output: None
89 * Return value: 0 -- success
90 * non-zero-- failure
91 */
92 int
93 twa_setup(struct twa_softc *sc)
94 {
95 struct twa_event_packet *aen_queue;
96 int error = 0;
97 int i;
98
99 twa_dbg_dprint_enter(3, sc);
100
101 /* Initialize request queues. */
102 twa_initq_free(sc);
103 twa_initq_busy(sc);
104 twa_initq_pending(sc);
105 twa_initq_complete(sc);
106
107 if (twa_alloc_req_pkts(sc, TWA_Q_LENGTH)) {
108 twa_printf(sc, "Failed to allocate request packets.\n");
109 return(ENOMEM);
110 }
111
112 /* Allocate memory for the AEN queue. */
113 if ((aen_queue = malloc(sizeof(struct twa_event_packet) * TWA_Q_LENGTH,
114 M_DEVBUF, M_WAITOK)) == NULL) {
115 /*
116 * This should not cause us to return error. We will only be
117 * unable to support AEN's. But then, we will have to check
118 * time and again to see if we can support AEN's, if we
119 * continue. So, we will just return error.
120 */
121 twa_printf(sc, "Could not allocate memory for AEN queue.\n");
122 return(ENOMEM); /* any unfreed memory will be freed by twa_free */
123 }
124 /* Initialize the aen queue. */
125 bzero(aen_queue, sizeof(struct twa_event_packet) * TWA_Q_LENGTH);
126 for (i = 0; i < TWA_Q_LENGTH; i++)
127 sc->twa_aen_queue[i] = &(aen_queue[i]);
128
129 /* Disable interrupts. */
130 twa_disable_interrupts(sc);
131
132 /* Initialize the controller. */
133 if ((error = twa_init_ctlr(sc))) {
134 /* Soft reset the controller, and try one more time. */
135 twa_printf(sc, "Controller initialization failed. Retrying...\n");
136 if ((error = twa_soft_reset(sc)))
137 twa_printf(sc, "Controller soft reset failed.\n");
138 else
139 error = twa_init_ctlr(sc);
140 }
141 return(error);
142 }
143
144 #ifdef TWA_FLASH_FIRMWARE
145 /*
146 * Function name: twa_flash_firmware
147 * Description: Flashes bundled firmware image onto controller.
148 *
149 * Input: sc -- ptr to per ctlr structure
150 * Output: None
151 * Return value: 0 -- success
152 * non-zero-- failure
153 */
154 static int
155 twa_flash_firmware(struct twa_softc *sc)
156 {
157 struct twa_request *tr;
158 struct twa_command_header *cmd_hdr;
159 struct twa_command_download_firmware *cmd;
160 u_int32_t fw_img_chunk_size;
161 u_int32_t this_chunk_size = 0;
162 u_int32_t remaining_img_size = 0;
163 u_int8_t *error_str;
164 int error;
165 int i;
166
167 if ((tr = twa_get_request(sc)) == NULL) {
168 /* No free request packets available. Can't proceed. */
169 error = EIO;
170 goto out;
171 }
172 tr->tr_cmd_pkt_type |= TWA_CMD_PKT_TYPE_INTERNAL;
173 /* Allocate sufficient memory to hold a chunk of the firmware image. */
174 fw_img_chunk_size = ((twa_fw_img_size/NUM_FW_IMAGE_CHUNKS) + 511) & ~511;
175 if ((tr->tr_data = malloc(fw_img_chunk_size, M_DEVBUF, M_WAITOK)) == NULL) {
176 twa_printf (sc, "Could not allocate memory for firmware image.\n");
177 error = ENOMEM;
178 goto out;
179 }
180 remaining_img_size = twa_fw_img_size;
181 cmd_hdr = &(tr->tr_command->cmd_hdr);
182 cmd = &(tr->tr_command->command.cmd_pkt_7k.download_fw);
183
184 for (i = 0; i < NUM_FW_IMAGE_CHUNKS; i++) {
185 /* Build a cmd pkt for downloading firmware. */
186 bzero(tr->tr_command, sizeof(struct twa_command_packet));
187
188 cmd_hdr->header_desc.size_header = 128;
189
190 cmd->opcode = TWA_OP_DOWNLOAD_FIRMWARE;
191 cmd->sgl_offset = 2;/* offset in dwords, to the beginning of sg list */
192 cmd->size = 2; /* this field will be updated at data map time */
193 cmd->request_id = tr->tr_request_id;
194 cmd->unit = 0;
195 cmd->status = 0;
196 cmd->flags = 0;
197 cmd->param = 8; /* prom image */
198
199 if (i != (NUM_FW_IMAGE_CHUNKS - 1))
200 this_chunk_size = fw_img_chunk_size;
201 else /* last chunk */
202 this_chunk_size = remaining_img_size;
203
204 remaining_img_size -= this_chunk_size;
205 bcopy(twa_fw_img + (i * fw_img_chunk_size),
206 tr->tr_data, this_chunk_size);
207
208 /*
209 * The next line will effect only the last chunk.
210 */
211 tr->tr_length = (this_chunk_size + 511) & ~511;
212
213 tr->tr_flags |= TWA_CMD_DATA_OUT;
214
215 error = twa_immediate_request(tr, TWA_REQUEST_TIMEOUT_PERIOD);
216 if (error) {
217 twa_printf(sc, "Firmware flash request could not be posted. error = 0x%x\n",
218 error);
219 if (error == ETIMEDOUT)
220 return(error); /* clean-up done by twa_immediate_request */
221 break;
222 }
223 error = cmd->status;
224 if (i != (NUM_FW_IMAGE_CHUNKS - 1)) {
225 if ((error = cmd_hdr->status_block.error) != TWA_ERROR_MORE_DATA) {
226 error_str =
227 &(cmd_hdr->err_desc[strlen(cmd_hdr->err_desc) + 1]);
228 if (error_str[0] == '\0')
229 error_str = twa_find_msg_string(twa_error_table, error);
230
231 twa_printf(sc, "cmd = 0x%x: ERROR: (0x%02X: 0x%04X): %s: %s\n",
232 cmd->opcode,
233 TWA_MESSAGE_SOURCE_CONTROLLER_ERROR,
234 error,
235 error_str,
236 cmd_hdr->err_desc);
237 twa_printf(sc, "Firmware flash request failed. Intermediate error = 0x%x, i = %x\n",
238 cmd->status, i);
239 /* Hard reset the controller, so that it doesn't wait for the remaining chunks. */
240 twa_hard_reset(sc);
241 break;
242 }
243 } else /* last chunk */
244 if (error) {
245 error_str =
246 &(cmd_hdr->err_desc[strlen(cmd_hdr->err_desc) + 1]);
247 if (error_str[0] == '\0')
248 error_str = twa_find_msg_string(twa_error_table,
249 cmd_hdr->status_block.error);
250
251 twa_printf(sc, "cmd = 0x%x: ERROR: (0x%02X: 0x%04X): %s: %s\n",
252 cmd->opcode,
253 TWA_MESSAGE_SOURCE_CONTROLLER_ERROR,
254 cmd_hdr->status_block.error,
255 error_str,
256 cmd_hdr->err_desc);
257 twa_printf(sc, "Firmware flash request failed. error = 0x%x\n", error);
258 /* Hard reset the controller, so that it doesn't wait for more chunks. */
259 twa_hard_reset(sc);
260 }
261 } /* for */
262
263 if (tr->tr_data)
264 free(tr->tr_data, M_DEVBUF);
265 out:
266 if (tr)
267 twa_release_request(tr);
268 return(error);
269 }
270
271
272 /*
273 * Function name: twa_hard_reset
274 * Description: Hard reset the controller.
275 *
276 * Input: sc -- ptr to per ctlr structure
277 * Output: None
278 * Return value: 0 -- success
279 * non-zero-- failure
280 */
281 static int
282 twa_hard_reset(struct twa_softc *sc)
283 {
284 struct twa_request *tr;
285 struct twa_command_header *cmd_hdr;
286 struct twa_command_reset_firmware *cmd;
287 int error;
288
289 if ((tr = twa_get_request(sc)) == NULL)
290 return(EIO);
291 tr->tr_cmd_pkt_type |= TWA_CMD_PKT_TYPE_INTERNAL;
292 /* Build a cmd pkt for sending down the hard reset command. */
293 cmd_hdr = &(tr->tr_command->cmd_hdr);
294 cmd_hdr->header_desc.size_header = 128;
295
296 cmd = &(tr->tr_command->command.cmd_pkt_7k.reset_fw);
297 cmd->opcode = TWA_OP_RESET_FIRMWARE;
298 cmd->size = 2; /* this field will be updated at data map time */
299 cmd->request_id = tr->tr_request_id;
300 cmd->unit = 0;
301 cmd->status = 0;
302 cmd->flags = 0;
303 cmd->param = 0; /* don't reload FPGA logic */
304
305 tr->tr_data = NULL;
306 tr->tr_length = 0;
307
308 error = twa_immediate_request(tr, TWA_REQUEST_TIMEOUT_PERIOD);
309 if (error) {
310 twa_printf(sc, "Hard reset request could not be posted. error = 0x%x\n",
311 error);
312 if (error == ETIMEDOUT)
313 return(error); /* clean-up done by twa_immediate_request */
314 goto out;
315 }
316 if ((error = cmd->status)) {
317 u_int8_t *error_str =
318 &(cmd_hdr->err_desc[strlen(cmd_hdr->err_desc) + 1]);
319
320 if (error_str[0] == '\0')
321 error_str = twa_find_msg_string(twa_error_table,
322 cmd_hdr->status_block.error);
323
324 twa_printf(sc, "cmd = 0x%x: ERROR: (0x%02X: 0x%04X): %s: %s\n",
325 cmd->opcode,
326 TWA_MESSAGE_SOURCE_CONTROLLER_ERROR,
327 cmd_hdr->status_block.error,
328 error_str,
329 cmd_hdr->err_desc);
330 twa_printf(sc, "Hard reset request failed. error = 0x%x\n", error);
331 }
332
333 out:
334 if (tr)
335 twa_release_request(tr);
336 return(error);
337 }
338
339 #endif /* TWA_FLASH_FIRMWARE */
340
341 /*
342 * Function name: twa_init_ctlr
343 * Description: Establishes a logical connection with the controller.
344 * If bundled with firmware, determines whether or not
345 * to flash firmware, based on arch_id, fw SRL (Spec.
346 * Revision Level), branch & build #'s. Also determines
347 * whether or not the driver is compatible with the
348 * firmware on the controller, before proceeding to work
349 * with it.
350 *
351 * Input: sc -- ptr to per ctlr structure
352 * Output: None
353 * Return value: 0 -- success
354 * non-zero-- failure
355 */
356 static int
357 twa_init_ctlr(struct twa_softc *sc)
358 {
359 u_int16_t fw_on_ctlr_srl = 0;
360 u_int16_t fw_on_ctlr_arch_id = 0;
361 u_int16_t fw_on_ctlr_branch = 0;
362 u_int16_t fw_on_ctlr_build = 0;
363 u_int32_t init_connect_result = 0;
364 int error = 0;
365 #ifdef TWA_FLASH_FIRMWARE
366 int8_t fw_flashed = FALSE;
367 int8_t fw_flash_failed = FALSE;
368 #endif /* TWA_FLASH_FIRMWARE */
369
370 twa_dbg_dprint_enter(3, sc);
371
372 /* Wait for the controller to become ready. */
373 if (twa_wait_status(sc, TWA_STATUS_MICROCONTROLLER_READY,
374 TWA_REQUEST_TIMEOUT_PERIOD)) {
375 twa_printf(sc, "Microcontroller not ready.\n");
376 return(ENXIO);
377 }
378 /* Drain the response queue. */
379 if (twa_drain_response_queue(sc)) {
380 twa_printf(sc, "Can't drain response queue.\n");
381 return(1);
382 }
383 /* Establish a logical connection with the controller. */
384 if ((error = twa_init_connection(sc, TWA_INIT_MESSAGE_CREDITS,
385 TWA_EXTENDED_INIT_CONNECT, TWA_CURRENT_FW_SRL,
386 TWA_9000_ARCH_ID, TWA_CURRENT_FW_BRANCH,
387 TWA_CURRENT_FW_BUILD, &fw_on_ctlr_srl,
388 &fw_on_ctlr_arch_id, &fw_on_ctlr_branch,
389 &fw_on_ctlr_build, &init_connect_result))) {
390 twa_printf(sc, "Can't initialize connection in current mode.\n");
391 return(error);
392 }
393
394 #ifdef TWA_FLASH_FIRMWARE
395
396 if ((init_connect_result & TWA_BUNDLED_FW_SAFE_TO_FLASH) &&
397 (init_connect_result & TWA_CTLR_FW_RECOMMENDS_FLASH)) {
398 /*
399 * The bundled firmware is safe to flash, and the firmware
400 * on the controller recommends a flash. So, flash!
401 */
402 twa_printf(sc, "Flashing bundled firmware...\n");
403 if ((error = twa_flash_firmware(sc))) {
404 fw_flash_failed = TRUE;
405 twa_printf(sc, "Unable to flash bundled firmware.\n");
406 twa_printf(sc, "Will see if possible to work with firmware on controller...\n");
407 } else {
408 twa_printf(sc, "Successfully flashed bundled firmware.\n");
409 fw_flashed = TRUE;
410 }
411 }
412
413 if (fw_flashed) {
414 /* The firmware was flashed. Have the new image loaded */
415 error = twa_hard_reset(sc);
416 if (error)
417 twa_printf(sc, "Could not reset controller after flash!\n");
418 else /* Go through initialization again. */
419 error = twa_init_ctlr(sc);
420 /*
421 * If hard reset of controller failed, we need to return.
422 * Otherwise, the above recursive call to twa_init_ctlr will
423 * have completed the rest of the initialization (starting
424 * from twa_drain_aen_queue below). Don't do it again.
425 * Just return.
426 */
427 return(error);
428 } else
429 #endif /* TWA_FLASH_FIRMWARE */
430 {
431 /*
432 * Either we are not bundled with a firmware image, or
433 * the bundled firmware is not safe to flash,
434 * or flash failed for some reason. See if we can at
435 * least work with the firmware on the controller in the
436 * current mode.
437 */
438 if (init_connect_result & TWA_CTLR_FW_COMPATIBLE) {
439 /* Yes, we can. Make note of the operating mode. */
440 sc->working_srl = TWA_CURRENT_FW_SRL;
441 sc->working_branch = TWA_CURRENT_FW_BRANCH;
442 sc->working_build = TWA_CURRENT_FW_BUILD;
443 } else {
444 /*
445 * No, we can't. See if we can at least work with
446 * it in the base mode. We should never come here
447 * if firmware has just been flashed.
448 */
449 twa_printf(sc, "Driver/Firmware mismatch. Negotiating for base level...\n");
450 if ((error = twa_init_connection(sc, TWA_INIT_MESSAGE_CREDITS,
451 TWA_EXTENDED_INIT_CONNECT, TWA_BASE_FW_SRL,
452 TWA_9000_ARCH_ID, TWA_BASE_FW_BRANCH,
453 TWA_BASE_FW_BUILD, &fw_on_ctlr_srl,
454 &fw_on_ctlr_arch_id, &fw_on_ctlr_branch,
455 &fw_on_ctlr_build, &init_connect_result))) {
456 twa_printf(sc, "Can't initialize connection in base mode.\n");
457 return(error);
458 }
459 if (!(init_connect_result & TWA_CTLR_FW_COMPATIBLE)) {
460 /*
461 * The firmware on the controller is not even
462 * compatible with our base mode. We cannot
463 * work with it. Bail...
464 */
465 twa_printf(sc, "Incompatible firmware on controller\n");
466 #ifdef TWA_FLASH_FIRMWARE
467 if (fw_flash_failed)
468 twa_printf(sc, "...and could not flash bundled firmware.\n");
469 else
470 twa_printf(sc, "...and bundled firmware not safe to flash.\n");
471 #endif /* TWA_FLASH_FIRMWARE */
472 return(1);
473 }
474 /* We can work with this firmware, but only in base mode. */
475 sc->working_srl = TWA_BASE_FW_SRL;
476 sc->working_branch = TWA_BASE_FW_BRANCH;
477 sc->working_build = TWA_BASE_FW_BUILD;
478 sc->twa_operating_mode = TWA_BASE_MODE;
479 }
480 }
481
482 /* Drain the AEN queue */
483 if (twa_drain_aen_queue(sc)) {
484 /*
485 * We will just print that we couldn't drain the AEN queue.
486 * There's no need to bail out.
487 */
488 twa_printf(sc, "Can't drain AEN queue.\n");
489 }
490
491 /* Set controller state to initialized. */
492 sc->twa_state &= ~TWA_STATE_SHUTDOWN;
493
494 twa_enable_interrupts(sc);
495 twa_dbg_dprint_exit(3, sc);
496 return(0);
497 }
498
499
500 /*
501 * Function name: twa_deinit_ctlr
502 * Description: Close logical connection with the controller.
503 *
504 * Input: sc -- ptr to per ctlr structure
505 * Output: None
506 * Return value: 0 -- success
507 * non-zero-- failure
508 */
509 int
510 twa_deinit_ctlr(struct twa_softc *sc)
511 {
512 /*
513 * Mark the controller as shutting down,
514 * and disable any further interrupts.
515 */
516 sc->twa_state |= TWA_STATE_SHUTDOWN;
517 twa_disable_interrupts(sc);
518
519 /* Let the controller know that we are going down. */
520 return(twa_init_connection(sc, TWA_SHUTDOWN_MESSAGE_CREDITS,
521 0, 0, 0, 0, 0,
522 NULL, NULL, NULL, NULL, NULL));
523 }
524
525
526 /*
527 * Function name: twa_interrupt
528 * Description: Interrupt handler. Determines the kind of interrupt,
529 * and calls the appropriate handler.
530 *
531 * Input: sc -- ptr to per ctlr structure
532 * Output: None
533 * Return value: None
534 */
535 void
536 twa_interrupt(struct twa_softc *sc)
537 {
538 u_int32_t status_reg;
539 int s;
540
541 s = splcam();
542 twa_dbg_dprint_enter(5, sc);
543
544 /* Collect current interrupt status. */
545 status_reg = TWA_READ_STATUS_REGISTER(sc);
546 if (twa_check_ctlr_state(sc, status_reg))
547 return;
548
549 /* Dispatch based on the kind of interrupt. */
550 if (status_reg & TWA_STATUS_HOST_INTERRUPT)
551 twa_host_intr(sc);
552 if (status_reg & TWA_STATUS_ATTENTION_INTERRUPT)
553 twa_attention_intr(sc);
554 if (status_reg & TWA_STATUS_COMMAND_INTERRUPT)
555 twa_command_intr(sc);
556 if (status_reg & TWA_STATUS_RESPONSE_INTERRUPT)
557 twa_done(sc);
558 splx(s);
559 }
560
561
562 /*
563 * Function name: twa_ioctl
564 * Description: ioctl handler.
565 *
566 * Input: sc -- ptr to per ctlr structure
567 * cmd -- ioctl cmd
568 * buf -- ptr to buffer in kernel memory, which is
569 * a copy of the input buffer in user-space
570 * Output: buf -- ptr to buffer in kernel memory, which will
571 * be copied of the output buffer in user-space
572 * Return value: 0 -- success
573 * non-zero-- failure
574 */
575 int
576 twa_ioctl(struct twa_softc *sc, int cmd, void *buf)
577 {
578 struct twa_ioctl_9k *user_buf = (struct twa_ioctl_9k *)buf;
579 struct twa_event_packet event_buf;
580 int32_t event_index;
581 int32_t start_index;
582 int s;
583 int error = 0;
584
585 switch (cmd) {
586 case TWA_IOCTL_FIRMWARE_PASS_THROUGH:
587 {
588 struct twa_command_packet *cmdpkt;
589 struct twa_request *tr;
590 u_int32_t data_buf_size_adjusted;
591
592
593 twa_dbg_dprint(2, sc, "Firmware PassThru");
594
595 /* Get a request packet */
596 while ((tr = twa_get_request(sc)) == NULL)
597 /*
598 * No free request packets available. Sleep until
599 * one becomes available.
600 */
601 tsleep(&(sc->twa_wait_timeout), PPAUSE, "twioctl", hz);
602
603 /*
604 * Make sure that the data buffer sent to firmware is a
605 * 512 byte multiple in size.
606 */
607 data_buf_size_adjusted = (user_buf->twa_drvr_pkt.buffer_length + 511) & ~511;
608 if ((tr->tr_length = data_buf_size_adjusted)) {
609 if ((tr->tr_data = malloc(data_buf_size_adjusted, M_DEVBUF, M_WAITOK)) == NULL) {
610 twa_printf(sc, "Could not alloc mem for fw_passthru data_buf.\n");
611 error = ENOMEM;
612 goto fw_passthru_done;
613 }
614 /* Copy the payload. */
615 if ((error = copyin((void *) (user_buf->pdata),
616 (void *) (tr->tr_data),
617 user_buf->twa_drvr_pkt.buffer_length)) != 0) {
618 twa_printf (sc, "Could not copyin fw_passthru data_buf.\n");
619 goto fw_passthru_done;
620 }
621 tr->tr_flags |= TWA_CMD_DATA_IN | TWA_CMD_DATA_OUT;
622 }
623 tr->tr_cmd_pkt_type |= TWA_CMD_PKT_TYPE_IOCTL;
624 cmdpkt = tr->tr_command;
625
626 /* Copy the command packet. */
627 bcopy(&(user_buf->twa_cmd_pkt), cmdpkt,
628 sizeof(struct twa_command_packet));
629 cmdpkt->command.cmd_pkt_7k.generic.request_id = tr->tr_request_id;
630
631 twa_dbg_dprint(3, sc, "cmd_pkt_7k = %x %x %x %x %x %x %x",
632 cmdpkt->command.cmd_pkt_7k.generic.opcode,
633 cmdpkt->command.cmd_pkt_7k.generic.sgl_offset,
634 cmdpkt->command.cmd_pkt_7k.generic.size,
635 cmdpkt->command.cmd_pkt_7k.generic.request_id,
636 cmdpkt->command.cmd_pkt_7k.generic.unit,
637 cmdpkt->command.cmd_pkt_7k.generic.status,
638 cmdpkt->command.cmd_pkt_7k.generic.flags);
639
640 /* Send down the request, and wait for it to complete. */
641 if ((error = twa_wait_request(tr, TWA_REQUEST_TIMEOUT_PERIOD))) {
642 twa_printf(sc, "fw_passthru request failed. error = 0x%x\n", error);
643 if (error == ETIMEDOUT)
644 break; /* clean-up done by twa_wait_request */
645 goto fw_passthru_done;
646 }
647
648 /* Copy the command packet back into user space. */
649 bcopy(cmdpkt, &(user_buf->twa_cmd_pkt),
650 sizeof(struct twa_command_packet));
651
652 /* If there was a payload, copy it back too. */
653 if (tr->tr_length)
654 error = copyout(tr->tr_data, user_buf->pdata,
655 user_buf->twa_drvr_pkt.buffer_length);
656
657 fw_passthru_done:
658 /* Free resources. */
659 if (tr->tr_data)
660 free(tr->tr_data, M_DEVBUF);
661 if (tr)
662 twa_release_request(tr);
663 break;
664 }
665
666
667 case TWA_IOCTL_SCAN_BUS:
668 /* Request CAM for a bus scan. */
669 twa_request_bus_scan(sc);
670 break;
671
672
673 case TWA_IOCTL_GET_FIRST_EVENT:
674 twa_dbg_dprint(3, sc, "Get First Event");
675
676 if (sc->twa_aen_queue_wrapped) {
677 if (sc->twa_aen_queue_overflow) {
678 /*
679 * The aen queue has wrapped, even before some
680 * events have been retrieved. Let the caller
681 * know that he missed out on some AEN's.
682 */
683 user_buf->twa_drvr_pkt.status = TWA_ERROR_AEN_OVERFLOW;
684 sc->twa_aen_queue_overflow = FALSE;
685 } else
686 user_buf->twa_drvr_pkt.status = 0;
687 event_index = sc->twa_aen_head;
688 } else {
689 if (sc->twa_aen_head == sc->twa_aen_tail) {
690 user_buf->twa_drvr_pkt.status = TWA_ERROR_AEN_NO_EVENTS;
691 break;
692 }
693 user_buf->twa_drvr_pkt.status = 0;
694 event_index = sc->twa_aen_tail; /* = 0 */
695 }
696 if ((error = copyout(sc->twa_aen_queue[event_index], user_buf->pdata,
697 sizeof(struct twa_event_packet))) != 0)
698 twa_printf(sc, "get_first: Could not copyout to event_buf. error = %x\n", error);
699 (sc->twa_aen_queue[event_index])->retrieved = TWA_AEN_RETRIEVED;
700 break;
701
702
703 case TWA_IOCTL_GET_LAST_EVENT:
704 twa_dbg_dprint(3, sc, "Get Last Event");
705
706 if (sc->twa_aen_queue_wrapped) {
707 if (sc->twa_aen_queue_overflow) {
708 /*
709 * The aen queue has wrapped, even before some
710 * events have been retrieved. Let the caller
711 * know that he missed out on some AEN's.
712 */
713 user_buf->twa_drvr_pkt.status = TWA_ERROR_AEN_OVERFLOW;
714 sc->twa_aen_queue_overflow = FALSE;
715 } else
716 user_buf->twa_drvr_pkt.status = 0;
717 } else {
718 if (sc->twa_aen_head == sc->twa_aen_tail) {
719 user_buf->twa_drvr_pkt.status = TWA_ERROR_AEN_NO_EVENTS;
720 break;
721 }
722 user_buf->twa_drvr_pkt.status = 0;
723 }
724 event_index = (sc->twa_aen_head - 1 + TWA_Q_LENGTH) % TWA_Q_LENGTH;
725 if ((error = copyout(sc->twa_aen_queue[event_index], user_buf->pdata,
726 sizeof(struct twa_event_packet))) != 0)
727 twa_printf(sc, "get_last: Could not copyout to event_buf. error = %x\n", error);
728 (sc->twa_aen_queue[event_index])->retrieved = TWA_AEN_RETRIEVED;
729 break;
730
731
732 case TWA_IOCTL_GET_NEXT_EVENT:
733 twa_dbg_dprint(3, sc, "Get Next Event");
734
735 user_buf->twa_drvr_pkt.status = 0;
736 if (sc->twa_aen_queue_wrapped) {
737 twa_dbg_dprint(3, sc, "Get Next Event: wrapped");
738 if (sc->twa_aen_queue_overflow) {
739 /*
740 * The aen queue has wrapped, even before some
741 * events have been retrieved. Let the caller
742 * know that he missed out on some AEN's.
743 */
744 twa_dbg_dprint(2, sc, "Get Next Event: overflow");
745 user_buf->twa_drvr_pkt.status = TWA_ERROR_AEN_OVERFLOW;
746 sc->twa_aen_queue_overflow = FALSE;
747 }
748 start_index = sc->twa_aen_head;
749 } else {
750 if (sc->twa_aen_head == sc->twa_aen_tail) {
751 twa_dbg_dprint(3, sc, "Get Next Event: empty queue");
752 user_buf->twa_drvr_pkt.status = TWA_ERROR_AEN_NO_EVENTS;
753 break;
754 }
755 start_index = sc->twa_aen_tail; /* = 0 */
756 }
757 if ((error = copyin(user_buf->pdata, &event_buf,
758 sizeof(struct twa_event_packet))) != 0)
759 twa_printf(sc, "get_next: Could not copyin event_buf.\n");
760
761 event_index = (start_index + event_buf.sequence_id -
762 (sc->twa_aen_queue[start_index])->sequence_id + 1)
763 % TWA_Q_LENGTH;
764
765 twa_dbg_dprint(3, sc, "Get Next Event: si = %x, ei = %x, ebsi = %x, sisi = %x, eisi = %x",
766 start_index, event_index, event_buf.sequence_id,
767 (sc->twa_aen_queue[start_index])->sequence_id,
768 (sc->twa_aen_queue[event_index])->sequence_id);
769
770 if (! ((sc->twa_aen_queue[event_index])->sequence_id >
771 event_buf.sequence_id)) {
772 if (user_buf->twa_drvr_pkt.status == TWA_ERROR_AEN_OVERFLOW)
773 sc->twa_aen_queue_overflow = TRUE; /* so we report the overflow next time */
774 user_buf->twa_drvr_pkt.status = TWA_ERROR_AEN_NO_EVENTS;
775 break;
776 }
777 if ((error = copyout(sc->twa_aen_queue[event_index], user_buf->pdata,
778 sizeof(struct twa_event_packet))) != 0)
779 twa_printf(sc, "get_next: Could not copyout to event_buf. error = %x\n", error);
780
781 (sc->twa_aen_queue[event_index])->retrieved = TWA_AEN_RETRIEVED;
782 break;
783
784
785 case TWA_IOCTL_GET_PREVIOUS_EVENT:
786 twa_dbg_dprint(3, sc, "Get Previous Event");
787
788 user_buf->twa_drvr_pkt.status = 0;
789 if (sc->twa_aen_queue_wrapped) {
790 if (sc->twa_aen_queue_overflow) {
791 /*
792 * The aen queue has wrapped, even before some
793 * events have been retrieved. Let the caller
794 * know that he missed out on some AEN's.
795 */
796 user_buf->twa_drvr_pkt.status = TWA_ERROR_AEN_OVERFLOW;
797 sc->twa_aen_queue_overflow = FALSE;
798 }
799 start_index = sc->twa_aen_head;
800 } else {
801 if (sc->twa_aen_head == sc->twa_aen_tail) {
802 user_buf->twa_drvr_pkt.status = TWA_ERROR_AEN_NO_EVENTS;
803 break;
804 }
805 start_index = sc->twa_aen_tail; /* = 0 */
806 }
807 if ((error = copyin(user_buf->pdata, &event_buf,
808 sizeof(struct twa_event_packet))) != 0)
809 twa_printf(sc, "get_previous: Could not copyin event_buf.\n");
810
811 event_index = (start_index + event_buf.sequence_id -
812 (sc->twa_aen_queue[start_index])->sequence_id - 1) % TWA_Q_LENGTH;
813 if (! ((sc->twa_aen_queue[event_index])->sequence_id < event_buf.sequence_id)) {
814 if (user_buf->twa_drvr_pkt.status == TWA_ERROR_AEN_OVERFLOW)
815 sc->twa_aen_queue_overflow = TRUE; /* so we report the overflow next time */
816 user_buf->twa_drvr_pkt.status = TWA_ERROR_AEN_NO_EVENTS;
817 break;
818 }
819 if ((error = copyout(sc->twa_aen_queue [event_index], user_buf->pdata,
820 sizeof(struct twa_event_packet))) != 0)
821 twa_printf(sc, "get_previous: Could not copyout to event_buf. error = %x\n", error);
822
823 (sc->twa_aen_queue[event_index])->retrieved = TWA_AEN_RETRIEVED;
824 break;
825
826
827 case TWA_IOCTL_GET_LOCK:
828 {
829 struct twa_lock_packet twa_lock;
830 u_int32_t cur_time;
831
832 cur_time = time_second - (tz.tz_minuteswest * 60) -
833 (wall_cmos_clock ? adjkerntz : 0);
834 copyin(user_buf->pdata, &twa_lock,
835 sizeof(struct twa_lock_packet));
836 s = splcam();
837 if ((sc->twa_ioctl_lock.lock == TWA_LOCK_FREE) ||
838 (twa_lock.force_flag) ||
839 (cur_time >= sc->twa_ioctl_lock.timeout)) {
840 twa_dbg_dprint(3, sc, "GET_LOCK: Getting lock!");
841 sc->twa_ioctl_lock.lock = TWA_LOCK_HELD;
842 sc->twa_ioctl_lock.timeout = cur_time + (twa_lock.timeout_msec / 1000);
843 twa_lock.time_remaining_msec = twa_lock.timeout_msec;
844 user_buf->twa_drvr_pkt.status = 0;
845 } else {
846 twa_dbg_dprint(2, sc, "GET_LOCK: Lock already held!");
847 twa_lock.time_remaining_msec =
848 (sc->twa_ioctl_lock.timeout - cur_time) * 1000;
849 user_buf->twa_drvr_pkt.status =
850 TWA_ERROR_IOCTL_LOCK_ALREADY_HELD;
851 }
852 splx(s);
853 copyout(&twa_lock, user_buf->pdata,
854 sizeof(struct twa_lock_packet));
855 break;
856 }
857
858
859 case TWA_IOCTL_RELEASE_LOCK:
860 s = splcam();
861 if (sc->twa_ioctl_lock.lock == TWA_LOCK_FREE) {
862 twa_dbg_dprint(2, sc, "twa_ioctl: RELEASE_LOCK: Lock not held!");
863 user_buf->twa_drvr_pkt.status = TWA_ERROR_IOCTL_LOCK_NOT_HELD;
864 } else {
865 twa_dbg_dprint(3, sc, "RELEASE_LOCK: Releasing lock!");
866 sc->twa_ioctl_lock.lock = TWA_LOCK_FREE;
867 user_buf->twa_drvr_pkt.status = 0;
868 }
869 splx(s);
870 break;
871
872
873 case TWA_IOCTL_GET_COMPATIBILITY_INFO:
874 {
875 struct twa_compatibility_packet comp_pkt;
876
877 bcopy(TWA_DRIVER_VERSION_STRING, comp_pkt.driver_version,
878 sizeof(TWA_DRIVER_VERSION_STRING));
879 comp_pkt.working_srl = sc->working_srl;
880 comp_pkt.working_branch = sc->working_branch;
881 comp_pkt.working_build = sc->working_build;
882 user_buf->twa_drvr_pkt.status = 0;
883
884 /* Copy compatibility information to user space. */
885 copyout(&comp_pkt, user_buf->pdata,
886 min(sizeof(struct twa_compatibility_packet),
887 user_buf->twa_drvr_pkt.buffer_length));
888 break;
889 }
890
891 default:
892 /* Unknown opcode. */
893 error = ENOTTY;
894 }
895
896 return(error);
897 }
898
899
900 /*
901 * Function name: twa_enable_interrupts
902 * Description: Enables interrupts on the controller
903 *
904 * Input: sc -- ptr to per ctlr structure
905 * Output: None
906 * Return value: None
907 */
908 void
909 twa_enable_interrupts(struct twa_softc *sc)
910 {
911 sc->twa_state |= TWA_STATE_INTR_ENABLED;
912 TWA_WRITE_CONTROL_REGISTER(sc,
913 TWA_CONTROL_CLEAR_ATTENTION_INTERRUPT |
914 TWA_CONTROL_UNMASK_RESPONSE_INTERRUPT |
915 TWA_CONTROL_ENABLE_INTERRUPTS);
916 }
917
918
919 /*
920 * Function name: twa_setup
921 * Description: Disables interrupts on the controller
922 *
923 * Input: sc -- ptr to per ctlr structure
924 * Output: None
925 * Return value: None
926 */
927 void
928 twa_disable_interrupts(struct twa_softc *sc)
929 {
930 TWA_WRITE_CONTROL_REGISTER(sc, TWA_CONTROL_DISABLE_INTERRUPTS);
931 sc->twa_state &= ~TWA_STATE_INTR_ENABLED;
932 }
933
934
935
936 /*
937 * Function name: twa_get_param
938 * Description: Get a firmware parameter.
939 *
940 * Input: sc -- ptr to per ctlr structure
941 * table_id -- parameter table #
942 * param_id -- index of the parameter in the table
943 * param_size -- size of the parameter in bytes
944 * callback -- ptr to function, if any, to be called
945 * back on completion; NULL if no callback.
946 * Output: None
947 * Return value: ptr to param structure -- success
948 * NULL -- failure
949 */
950 static void *
951 twa_get_param(struct twa_softc *sc, int table_id, int param_id,
952 size_t param_size, void (* callback)(struct twa_request *tr))
953 {
954 struct twa_request *tr;
955 struct twa_command_header *cmd_hdr;
956 union twa_command_7k *cmd;
957 struct twa_param_9k *param = NULL;
958 int error = ENOMEM;
959
960 twa_dbg_dprint_enter(4, sc);
961
962 /* Get a request packet. */
963 if ((tr = twa_get_request(sc)) == NULL)
964 goto out;
965 tr->tr_cmd_pkt_type |= TWA_CMD_PKT_TYPE_INTERNAL;
966
967 /* Allocate memory to read data into. */
968 if ((param = (struct twa_param_9k *)
969 malloc(TWA_SECTOR_SIZE, M_DEVBUF, M_NOWAIT)) == NULL)
970 goto out;
971 bzero(param, sizeof(struct twa_param_9k) - 1 + param_size);
972 tr->tr_data = param;
973 tr->tr_length = TWA_SECTOR_SIZE;
974 tr->tr_flags = TWA_CMD_DATA_IN | TWA_CMD_DATA_OUT;
975
976 /* Build the cmd pkt. */
977 cmd_hdr = &(tr->tr_command->cmd_hdr);
978 cmd_hdr->header_desc.size_header = 128;
979
980 cmd = &(tr->tr_command->command.cmd_pkt_7k);
981 cmd->param.opcode = TWA_OP_GET_PARAM;
982 cmd->param.sgl_offset = 2;
983 cmd->param.size = 2;
984 cmd->param.request_id = tr->tr_request_id;
985 cmd->param.unit = 0;
986 cmd->param.param_count = 1;
987
988 /* Specify which parameter we need. */
989 param->table_id = table_id | TWA_9K_PARAM_DESCRIPTOR;
990 param->parameter_id = param_id;
991 param->parameter_size_bytes = param_size;
992
993 /* Submit the command. */
994 if (callback == NULL) {
995 /* There's no call back; wait till the command completes. */
996 error = twa_immediate_request(tr, TWA_REQUEST_TIMEOUT_PERIOD);
997 if (error == ETIMEDOUT)
998 return(NULL); /* clean-up done by twa_immediate_request */
999 if (error)
1000 goto out;
1001 if ((error = cmd->param.status)) {
1002 u_int8_t *error_str =
1003 &(cmd_hdr->err_desc[strlen(cmd_hdr->err_desc) + 1]);
1004
1005 if (error_str[0] == '\0')
1006 error_str = twa_find_msg_string(twa_error_table,
1007 cmd_hdr->status_block.error);
1008
1009 twa_printf(sc, "cmd = 0x%x: ERROR: (0x%02X: 0x%04X): %s: %s\n",
1010 cmd->param.opcode,
1011 TWA_MESSAGE_SOURCE_CONTROLLER_ERROR,
1012 cmd_hdr->status_block.error,
1013 error_str,
1014 cmd_hdr->err_desc);
1015 goto out; /* twa_drain_complete_queue will have done the unmapping */
1016 }
1017 twa_release_request(tr);
1018 return(param);
1019 } else {
1020 /* There's a call back. Simply submit the command. */
1021 tr->tr_callback = callback;
1022 if ((error = twa_map_request(tr))) {
1023 twa_printf(tr->tr_sc, "%s: twa_map_request returned 0x%x\n",
1024 __func__, error);
1025 goto out;
1026 }
1027 return(callback);
1028 }
1029
1030 out:
1031 twa_printf(sc, "get_param failed. error = 0x%x\n", error);
1032 if (param)
1033 free(param, M_DEVBUF);
1034 if (tr)
1035 twa_release_request(tr);
1036 return(NULL);
1037 }
1038
1039
1040 /*
1041 * Function name: twa_set_param
1042 * Description: Set a firmware parameter.
1043 *
1044 * Input: sc -- ptr to per ctlr structure
1045 * table_id -- parameter table #
1046 * param_id -- index of the parameter in the table
1047 * param_size -- size of the parameter in bytes
1048 * callback -- ptr to function, if any, to be called
1049 * back on completion; NULL if no callback.
1050 * Output: None
1051 * Return value: 0 -- success
1052 * non-zero-- failure
1053 */
1054 static int
1055 twa_set_param(struct twa_softc *sc, int table_id,
1056 int param_id, int param_size, void *data,
1057 void (* callback)(struct twa_request *tr))
1058 {
1059 struct twa_request *tr;
1060 struct twa_command_header *cmd_hdr;
1061 union twa_command_7k *cmd;
1062 struct twa_param_9k *param = NULL;
1063 int error = ENOMEM;
1064
1065 twa_dbg_dprint_enter(4, sc);
1066
1067 /* Get a request packet. */
1068 if ((tr = twa_get_request(sc)) == NULL)
1069 goto out;
1070 tr->tr_cmd_pkt_type |= TWA_CMD_PKT_TYPE_INTERNAL;
1071
1072 /* Allocate memory to send data using. */
1073 if ((param = (struct twa_param_9k *)
1074 malloc(TWA_SECTOR_SIZE, M_DEVBUF, M_NOWAIT)) == NULL)
1075 goto out;
1076 bzero(param, sizeof(struct twa_param_9k) - 1 + param_size);
1077 tr->tr_data = param;
1078 tr->tr_length = TWA_SECTOR_SIZE;
1079 tr->tr_flags = TWA_CMD_DATA_IN | TWA_CMD_DATA_OUT;
1080
1081 /* Build the cmd pkt. */
1082 cmd_hdr = &(tr->tr_command->cmd_hdr);
1083 cmd_hdr->header_desc.size_header = 128;
1084
1085 cmd = &(tr->tr_command->command.cmd_pkt_7k);
1086 cmd->param.opcode = TWA_OP_SET_PARAM;
1087 cmd->param.sgl_offset = 2;
1088 cmd->param.size = 2;
1089 cmd->param.request_id = tr->tr_request_id;
1090 cmd->param.unit = 0;
1091 cmd->param.param_count = 1;
1092
1093 /* Specify which parameter we want to set. */
1094 param->table_id = table_id | TWA_9K_PARAM_DESCRIPTOR;
1095 param->parameter_id = param_id;
1096 param->parameter_size_bytes = param_size;
1097 bcopy(data, param->data, param_size);
1098
1099 /* Submit the command. */
1100 if (callback == NULL) {
1101 /* There's no call back; wait till the command completes. */
1102 error = twa_immediate_request(tr, TWA_REQUEST_TIMEOUT_PERIOD);
1103 if (error == ETIMEDOUT)
1104 return(error); /* clean-up done by twa_immediate_request */
1105 if (error)
1106 goto out;
1107 if ((error = cmd->param.status)) {
1108 u_int8_t *error_str =
1109 &(cmd_hdr->err_desc[strlen(cmd_hdr->err_desc) + 1]);
1110
1111 if (error_str[0] == '\0')
1112 error_str = twa_find_msg_string(twa_error_table,
1113 cmd_hdr->status_block.error);
1114 twa_printf(sc, "cmd = 0x%x: ERROR: (0x%02X: 0x%04X): %s: %s\n",
1115 cmd->param.opcode,
1116 TWA_MESSAGE_SOURCE_CONTROLLER_ERROR,
1117 cmd_hdr->status_block.error,
1118 error_str,
1119 cmd_hdr->err_desc);
1120 goto out; /* twa_drain_complete_queue will have done the unmapping */
1121 }
1122 free(param, M_DEVBUF);
1123 twa_release_request(tr);
1124 return(error);
1125 } else {
1126 /* There's a call back. Simply submit the command. */
1127 tr->tr_callback = callback;
1128 if ((error = twa_map_request(tr))) {
1129 twa_printf(tr->tr_sc, "%s: twa_map_request returned 0x%x\n",
1130 __func__, error);
1131 goto out;
1132 }
1133 return(0);
1134 }
1135
1136 out:
1137 twa_printf(sc, "set_param failed. error = 0x%x\n", error);
1138 if (param)
1139 free(param, M_DEVBUF);
1140 if (tr)
1141 twa_release_request(tr);
1142 return(error);
1143 }
1144
1145
1146 /*
1147 * Function name: twa_init_connection
1148 * Description: Send init_connection cmd to firmware
1149 *
1150 * Input: sc -- ptr to per ctlr structure
1151 * message_credits -- max # of requests that we might send
1152 * down simultaneously. This will be
1153 * typically set to 256 at init-time or
1154 * after a reset, and to 1 at shutdown-time
1155 * set_features -- indicates if we intend to use 64-bit
1156 * sg, also indicates if we want to do a
1157 * basic or an extended init_connection;
1158 *
1159 * Note: The following input/output parameters are valid, only in case of an
1160 * extended init_connection:
1161 *
1162 * current_fw_srl -- srl of fw we are bundled
1163 * with, if any; 0 otherwise
1164 * current_fw_arch_id -- arch_id of fw we are bundled
1165 * with, if any; 0 otherwise
1166 * current_fw_branch -- branch # of fw we are bundled
1167 * with, if any; 0 otherwise
1168 * current_fw_build -- build # of fw we are bundled
1169 * with, if any; 0 otherwise
1170 * Output: fw_on_ctlr_srl -- srl of fw on ctlr
1171 * fw_on_ctlr_arch_id -- arch_id of fw on ctlr
1172 * fw_on_ctlr_branch -- branch # of fw on ctlr
1173 * fw_on_ctlr_build -- build # of fw on ctlr
1174 * init_connect_result -- result bitmap of fw response
1175 * Return value: 0 -- success
1176 * non-zero-- failure
1177 */
1178 static int
1179 twa_init_connection(struct twa_softc *sc, u_int16_t message_credits,
1180 u_int32_t set_features, u_int16_t current_fw_srl,
1181 u_int16_t current_fw_arch_id, u_int16_t current_fw_branch,
1182 u_int16_t current_fw_build, u_int16_t *fw_on_ctlr_srl,
1183 u_int16_t *fw_on_ctlr_arch_id, u_int16_t *fw_on_ctlr_branch,
1184 u_int16_t *fw_on_ctlr_build, u_int32_t *init_connect_result)
1185 {
1186 struct twa_request *tr;
1187 struct twa_command_header *cmd_hdr;
1188 struct twa_command_init_connect *init_connect;
1189 int error = 1;
1190
1191 twa_dbg_dprint_enter(3, sc);
1192
1193 /* Get a request packet. */
1194 if ((tr = twa_get_request(sc)) == NULL)
1195 goto out;
1196 tr->tr_cmd_pkt_type |= TWA_CMD_PKT_TYPE_INTERNAL;
1197 /* Build the cmd pkt. */
1198 cmd_hdr = &(tr->tr_command->cmd_hdr);
1199 cmd_hdr->header_desc.size_header = 128;
1200
1201 init_connect = &(tr->tr_command->command.cmd_pkt_7k.init_connect);
1202 init_connect->opcode = TWA_OP_INIT_CONNECTION;
1203 init_connect->request_id = tr->tr_request_id;
1204 init_connect->message_credits = message_credits;
1205 init_connect->features = set_features;
1206 if (TWA_64BIT_ADDRESSES)
1207 init_connect->features |= TWA_64BIT_SG_ADDRESSES;
1208 if (set_features & TWA_EXTENDED_INIT_CONNECT) {
1209 /* Fill in the extra fields needed for an extended init_connect. */
1210 init_connect->size = 6;
1211 init_connect->fw_srl = current_fw_srl;
1212 init_connect->fw_arch_id = current_fw_arch_id;
1213 init_connect->fw_branch = current_fw_branch;
1214 init_connect->fw_build = current_fw_build;
1215 } else
1216 init_connect->size = 3;
1217
1218 /* Submit the command, and wait for it to complete. */
1219 error = twa_immediate_request(tr, TWA_REQUEST_TIMEOUT_PERIOD);
1220 if (error == ETIMEDOUT)
1221 return(error); /* clean-up done by twa_immediate_request */
1222 if (error)
1223 goto out;
1224 if ((error = init_connect->status)) {
1225 u_int8_t *error_str =
1226 &(cmd_hdr->err_desc[strlen(cmd_hdr->err_desc) + 1]);
1227
1228 if (error_str[0] == '\0')
1229 error_str = twa_find_msg_string(twa_error_table,
1230 cmd_hdr->status_block.error);
1231 twa_printf(sc, "cmd = 0x%x: ERROR: (0x%02X: 0x%04X): %s: %s\n",
1232 init_connect->opcode,
1233 TWA_MESSAGE_SOURCE_CONTROLLER_ERROR,
1234 cmd_hdr->status_block.error,
1235 error_str,
1236 cmd_hdr->err_desc);
1237 goto out; /* twa_drain_complete_queue will have done the unmapping */
1238 }
1239 if (set_features & TWA_EXTENDED_INIT_CONNECT) {
1240 *fw_on_ctlr_srl = init_connect->fw_srl;
1241 *fw_on_ctlr_arch_id = init_connect->fw_arch_id;
1242 *fw_on_ctlr_branch = init_connect->fw_branch;
1243 *fw_on_ctlr_build = init_connect->fw_build;
1244 *init_connect_result = init_connect->result;
1245 }
1246 twa_release_request(tr);
1247 return(error);
1248
1249 out:
1250 twa_printf(sc, "init_connection failed. error = 0x%x\n", error);
1251 if (tr)
1252 twa_release_request(tr);
1253 return(error);
1254 }
1255
1256
1257
1258 /*
1259 * Function name: twa_wait_request
1260 * Description: Sends down a firmware cmd, and waits for the completion,
1261 * but NOT in a tight loop.
1262 *
1263 * Input: tr -- ptr to request pkt
1264 * timeout -- max # of seconds to wait before giving up
1265 * Output: None
1266 * Return value: 0 -- success
1267 * non-zero-- failure
1268 */
1269 static int
1270 twa_wait_request(struct twa_request *tr, u_int32_t timeout)
1271 {
1272 time_t end_time;
1273 int s;
1274 int error;
1275
1276 twa_dbg_dprint_enter(4, tr->tr_sc);
1277
1278 tr->tr_flags |= TWA_CMD_SLEEP_ON_REQUEST;
1279 tr->tr_status = TWA_CMD_BUSY;
1280 if ((error = twa_map_request(tr))) {
1281 twa_printf(tr->tr_sc, "%s: twa_map_request returned 0x%x\n",
1282 __func__, error);
1283 return(error);
1284 }
1285
1286 s = splcam();
1287 end_time = time_second + timeout;
1288 while (tr->tr_status != TWA_CMD_COMPLETE) {
1289 if ((error = tr->tr_error))
1290 goto err;
1291 if ((error = tsleep(tr, PRIBIO, "twawait", timeout * hz)) == 0) {
1292 if ((error = tr->tr_error)) /* possible reset */
1293 goto err;
1294 error = (tr->tr_status != TWA_CMD_COMPLETE);
1295 break;
1296 }
1297 tr->tr_flags &= ~TWA_CMD_SLEEP_ON_REQUEST;
1298 if (error == EWOULDBLOCK) {
1299 /* Time out! */
1300 twa_printf(tr->tr_sc, "%s: Request %p timed out.\n",
1301 __func__, tr);
1302 /*
1303 * We will reset the controller only if the request has
1304 * already been submitted, so as to not lose the
1305 * request packet. If a busy request timed out, the
1306 * reset will take care of freeing resources. If a
1307 * pending request timed out, we will free resources
1308 * for that request, right here. So, the caller is
1309 * expected to NOT cleanup when ETIMEDOUT is returned.
1310 */
1311 if (tr->tr_status != TWA_CMD_PENDING)
1312 twa_reset(tr->tr_sc);
1313 else {
1314 /* Request was never submitted. Clean up. */
1315 twa_remove_pending(tr);
1316 twa_unmap_request(tr);
1317 }
1318 if (tr->tr_data)
1319 free(tr->tr_data, M_DEVBUF);
1320 twa_release_request(tr);
1321 splx(s);
1322 return(ETIMEDOUT);
1323 }
1324 /*
1325 * Either the request got completed, or we were woken up by a
1326 * signal. Calculate the new timeout, in case it was the latter.
1327 */
1328 timeout = (end_time - time_second);
1329 }
1330 twa_unmap_request(tr);
1331
1332 err:
1333 splx(s);
1334 return(error);
1335 }
1336
1337
1338
1339 /*
1340 * Function name: twa_immediate_request
1341 * Description: Sends down a firmware cmd, and waits for the completion
1342 * in a tight loop.
1343 *
1344 * Input: tr -- ptr to request pkt
1345 * timeout -- max # of seconds to wait before giving up
1346 * Output: None
1347 * Return value: 0 -- success
1348 * non-zero-- failure
1349 */
1350 static int
1351 twa_immediate_request(struct twa_request *tr, u_int32_t timeout)
1352 {
1353 time_t end_time;
1354 int error = 0;
1355
1356 twa_dbg_dprint_enter(4, tr->tr_sc);
1357
1358 if ((error = twa_map_request(tr))) {
1359 twa_printf(tr->tr_sc, "%s: twa_map_request returned 0x%x\n",
1360 __func__, error);
1361 return(error);
1362 }
1363
1364 end_time = time_second + timeout;
1365 do {
1366 if ((error = tr->tr_error))
1367 return(error);
1368 twa_done(tr->tr_sc);
1369 if ((tr->tr_status != TWA_CMD_BUSY) &&
1370 (tr->tr_status != TWA_CMD_PENDING)) {
1371 twa_unmap_request(tr);
1372 return(tr->tr_status != TWA_CMD_COMPLETE);
1373 }
1374 } while (time_second <= end_time);
1375
1376 /* Time out! */
1377 twa_printf(tr->tr_sc, "%s: Request %p timed out.\n", __func__, tr);
1378 /*
1379 * We will reset the controller only if the request has
1380 * already been submitted, so as to not lose the
1381 * request packet. If a busy request timed out, the
1382 * reset will take care of freeing resources. If a
1383 * pending request timed out, we will free resources
1384 * for that request, right here. So, the caller is
1385 * expected to NOT cleanup when ETIMEDOUT is returned.
1386 */
1387 if (tr->tr_status != TWA_CMD_PENDING)
1388 twa_reset(tr->tr_sc);
1389 else {
1390 /* Request was never submitted. Clean up. */
1391 twa_remove_pending(tr);
1392 twa_unmap_request(tr);
1393 if (tr->tr_data)
1394 free(tr->tr_data, M_DEVBUF);
1395 twa_release_request(tr);
1396 }
1397 return(ETIMEDOUT);
1398 }
1399
1400
1401
1402 /*
1403 * Function name: twa_complete_io
1404 * Description: Callback on scsi requests to fw.
1405 *
1406 * Input: tr -- ptr to request pkt
1407 * Output: None
1408 * Return value: None
1409 */
1410 void
1411 twa_complete_io(struct twa_request *tr)
1412 {
1413 struct twa_softc *sc = tr->tr_sc;
1414
1415 twa_dbg_dprint_enter(8, sc);
1416
1417 if (tr->tr_status != TWA_CMD_COMPLETE)
1418 twa_panic(sc, "twa_complete_io on incomplete command");
1419 if (tr->tr_private) /* This is a scsi cmd. Complete it. */
1420 twa_scsi_complete(tr);
1421 twa_release_request(tr);
1422 }
1423
1424
1425 /*
1426 * Function name: twa_reset
1427 * Description: Soft resets and then initializes the controller;
1428 * drains any incomplete requests.
1429 *
1430 * Input: sc -- ptr to per ctlr structure
1431 * Output: None
1432 * Return value: 0 -- success
1433 * non-zero-- failure
1434 */
1435 int
1436 twa_reset(struct twa_softc *sc)
1437 {
1438 int s;
1439 int error = 0;
1440
1441 twa_dbg_dprint_enter(2, sc);
1442
1443 /*
1444 * Disable interrupts from the controller, and mask any
1445 * accidental entry into our interrupt handler.
1446 */
1447 twa_disable_interrupts(sc);
1448 s = splcam();
1449
1450 /*
1451 * Complete all requests in the complete queue; error back all requests
1452 * in the busy queue. Any internal requests will be simply freed.
1453 * Re-submit any requests in the pending queue.
1454 */
1455 twa_drain_complete_queue(sc);
1456 twa_drain_busy_queue(sc);
1457
1458 /* Soft reset the controller. */
1459 if ((error = twa_soft_reset(sc))) {
1460 twa_printf (sc, "Controller reset failed.\n");
1461 goto out;
1462 }
1463
1464 /* Re-establish logical connection with the controller. */
1465 if ((error = twa_init_connection(sc, TWA_INIT_MESSAGE_CREDITS,
1466 0, 0, 0, 0, 0,
1467 NULL, NULL, NULL, NULL, NULL))) {
1468 twa_printf(sc, "Can't initialize connection after reset.\n");
1469 goto out;
1470 }
1471
1472 twa_printf(sc, "Controller reset done!\n");
1473
1474 out:
1475 splx(s);
1476 /*
1477 * Enable interrupts, and also clear attention and response interrupts.
1478 */
1479 twa_enable_interrupts(sc);
1480 return(error);
1481 }
1482
1483
1484
1485 /*
1486 * Function name: twa_soft_reset
1487 * Description: Does the actual soft reset.
1488 *
1489 * Input: sc -- ptr to per ctlr structure
1490 * Output: None
1491 * Return value: 0 -- success
1492 * non-zero-- failure
1493 */
1494 static int
1495 twa_soft_reset(struct twa_softc *sc)
1496 {
1497 u_int32_t status_reg;
1498
1499 twa_dbg_dprint_enter(1, sc);
1500
1501 twa_printf(sc, "Resetting controller...\n");
1502 TWA_SOFT_RESET(sc);
1503
1504 if (twa_wait_status(sc, TWA_STATUS_MICROCONTROLLER_READY |
1505 TWA_STATUS_ATTENTION_INTERRUPT, 30)) {
1506 twa_printf(sc, "Micro-ctlr not ready/No attn intr after reset.\n");
1507 return(1);
1508 }
1509 TWA_WRITE_CONTROL_REGISTER(sc, TWA_CONTROL_CLEAR_ATTENTION_INTERRUPT);
1510 if (twa_drain_response_queue(sc)) {
1511 twa_printf(sc, "Can't drain response queue.\n");
1512 return(1);
1513 }
1514 if (twa_drain_aen_queue(sc)) {
1515 twa_printf(sc, "Can't drain AEN queue.\n");
1516 return(1);
1517 }
1518 if (twa_find_aen(sc, TWA_AEN_SOFT_RESET)) {
1519 twa_printf(sc, "Reset not reported by controller.\n");
1520 return(1);
1521 }
1522 status_reg = TWA_READ_STATUS_REGISTER(sc);
1523 if (TWA_STATUS_ERRORS(status_reg) ||
1524 twa_check_ctlr_state(sc, status_reg)) {
1525 twa_printf(sc, "Controller errors detected.\n");
1526 return(1);
1527 }
1528 return(0);
1529 }
1530
1531
1532
1533 /*
1534 * Function name: twa_submit_io
1535 * Description: Wrapper to twa_start.
1536 *
1537 * Input: tr -- ptr to request pkt
1538 * Output: None
1539 * Return value: 0 -- success
1540 * non-zero-- failure
1541 */
1542 int
1543 twa_submit_io(struct twa_request *tr)
1544 {
1545 int error;
1546
1547 if ((error = twa_start(tr))) {
1548 if (tr->tr_cmd_pkt_type & TWA_CMD_PKT_TYPE_EXTERNAL) {
1549 if (error == EBUSY)
1550 /*
1551 * Cmd queue is full. Freeze the simq to
1552 * maintain ccb ordering. The next ccb that
1553 * gets completed will unfreeze the simq.
1554 */
1555 twa_disallow_new_requests(tr->tr_sc);
1556 else
1557 /* It's a controller error. */
1558 twa_printf(tr->tr_sc, "SCSI cmd = 0x%x: ERROR: (0x%02X: 0x%04X)\n",
1559 tr->tr_command->command.cmd_pkt_9k.cdb[0],
1560 TWA_MESSAGE_SOURCE_CONTROLLER_ERROR,
1561 error);
1562
1563 tr->tr_error = error;
1564 twa_scsi_complete(tr);
1565 } else {
1566 if (error == EBUSY)
1567 error = 0; /* the request will be in the pending queue */
1568 else {
1569 twa_printf(tr->tr_sc, "cmd = 0x%x: ERROR: (0x%02X: 0x%04X)\n",
1570 (tr->tr_cmd_pkt_type == TWA_CMD_PKT_TYPE_9K) ?
1571 (tr->tr_command->command.cmd_pkt_9k.command.opcode) :
1572 (tr->tr_command->command.cmd_pkt_7k.generic.opcode),
1573 TWA_MESSAGE_SOURCE_CONTROLLER_ERROR,
1574 tr->tr_error);
1575 tr->tr_error = error;
1576 }
1577 }
1578 }
1579 return(error);
1580 }
1581
1582
1583
1584 /*
1585 * Function name: twa_start
1586 * Description: Posts a cmd to firmware.
1587 *
1588 * Input: tr -- ptr to request pkt
1589 * Output: None
1590 * Return value: 0 -- success
1591 * non-zero-- failure
1592 */
1593 int
1594 twa_start(struct twa_request *tr)
1595 {
1596 struct twa_softc *sc = tr->tr_sc;
1597 u_int32_t status_reg;
1598 int s;
1599 int error;
1600
1601 twa_dbg_dprint_enter(10, sc);
1602
1603 s = splcam();
1604 /* Check to see if we can post a command. */
1605 status_reg = TWA_READ_STATUS_REGISTER(sc);
1606 if ((error = twa_check_ctlr_state(sc, status_reg)))
1607 goto out;
1608
1609 if (status_reg & TWA_STATUS_COMMAND_QUEUE_FULL) {
1610 if ((tr->tr_cmd_pkt_type & TWA_CMD_PKT_TYPE_INTERNAL) ||
1611 (tr->tr_cmd_pkt_type & TWA_CMD_PKT_TYPE_IOCTL)) {
1612 if (tr->tr_status != TWA_CMD_PENDING) {
1613 twa_dbg_dprint(2, sc, "pending internal/ioctl request");
1614 tr->tr_status = TWA_CMD_PENDING;
1615 twa_enqueue_pending(tr);
1616 }
1617 TWA_WRITE_CONTROL_REGISTER(sc,
1618 TWA_CONTROL_UNMASK_COMMAND_INTERRUPT);
1619 }
1620 error = EBUSY;
1621 } else {
1622 /* Mark the request as currently being processed. */
1623 tr->tr_status = TWA_CMD_BUSY;
1624 /* Move the request into the busy queue. */
1625 twa_enqueue_busy(tr);
1626 /* Cmd queue is not full. Post the command. */
1627 TWA_WRITE_COMMAND_QUEUE(sc,
1628 tr->tr_cmd_phys + sizeof(struct twa_command_header));
1629 }
1630
1631 out:
1632 splx(s);
1633 return(error);
1634 }
1635
1636
1637
1638 /*
1639 * Function name: twa_done
1640 * Description: Looks for cmd completions from fw; queues cmds completed
1641 * by fw into complete queue.
1642 *
1643 * Input: sc -- ptr to per ctlr structure
1644 * Output: None
1645 * Return value: 0 -- no ctlr error
1646 * non-zero-- ctlr error
1647 */
1648 static int
1649 twa_done(struct twa_softc *sc)
1650 {
1651 union twa_response_queue rq;
1652 struct twa_request *tr;
1653 int s;
1654 int error = 0;
1655 u_int32_t status_reg;
1656
1657 twa_dbg_dprint_enter(10, sc);
1658
1659 s = splcam();
1660 for (;;) {
1661 status_reg = TWA_READ_STATUS_REGISTER(sc);
1662 if ((error = twa_check_ctlr_state(sc, status_reg)))
1663 break;
1664 if (status_reg & TWA_STATUS_RESPONSE_QUEUE_EMPTY)
1665 break;
1666 /* Response queue is not empty. */
1667 rq = TWA_READ_RESPONSE_QUEUE(sc);
1668 tr = sc->twa_lookup[rq.u.response_id]; /* lookup the request */
1669 if (tr->tr_status != TWA_CMD_BUSY)
1670 twa_printf(sc, "ERROR: Unposted command completed!! req = %p; status = %d\n",
1671 tr, tr->tr_status);
1672 tr->tr_status = TWA_CMD_COMPLETE;
1673 /* Enqueue request in the complete queue. */
1674 twa_remove_busy(tr);
1675 twa_enqueue_complete(tr);
1676 }
1677 splx(s);
1678
1679 /* Complete this, and other requests in the complete queue. */
1680 twa_drain_complete_queue(sc);
1681 return(error);
1682 }
1683
1684
1685
1686 /*
1687 * Function name: twa_drain_pending_queue
1688 * Description: Kick starts any requests in the pending queue.
1689 *
1690 * Input: sc -- ptr to per ctlr structure
1691 * Output: None
1692 * Return value: 0 -- all pending requests drained
1693 * non-zero-- otherwise
1694 */
1695 static int
1696 twa_drain_pending_queue(struct twa_softc *sc)
1697 {
1698 struct twa_request *tr;
1699 int error = 0;
1700
1701 twa_dbg_dprint_enter(10, sc);
1702
1703 /*
1704 * Pull requests off the pending queue, and submit them.
1705 */
1706 while ((tr = twa_dequeue_pending(sc)) != NULL) {
1707 if ((error = twa_start(tr))) {
1708 if (error == EBUSY) {
1709 twa_dbg_dprint(2, sc, "Requeueing pending request");
1710 tr->tr_status = TWA_CMD_PENDING;
1711 twa_requeue_pending(tr);/* queue at the head */
1712 break;
1713 } else {
1714 twa_printf(sc, "%s: twa_start returned 0x%x\n",
1715 __func__, error);
1716 tr->tr_error = error;
1717 if (tr->tr_flags & TWA_CMD_SLEEP_ON_REQUEST)
1718 wakeup_one(tr);/* let the caller know it failed */
1719 error = 0;
1720 }
1721 }
1722 }
1723 return(error);
1724 }
1725
1726
1727
1728 /*
1729 * Function name: twa_drain_complete_queue
1730 * Description: Does unmapping for each request completed by fw,
1731 * and lets the request originators know of the completion.
1732 *
1733 * Input: sc -- ptr to per ctlr structure
1734 * Output: None
1735 * Return value: None
1736 */
1737 static void
1738 twa_drain_complete_queue(struct twa_softc *sc)
1739 {
1740 struct twa_request *tr;
1741
1742 twa_dbg_dprint_enter(10, sc);
1743
1744 /*
1745 * Pull commands off the completed list, dispatch them appropriately.
1746 */
1747 while ((tr = twa_dequeue_complete(sc)) != NULL) {
1748 /* Unmap the command packet, and any associated data buffer. */
1749 twa_unmap_request(tr);
1750
1751 /* Call the callback, if there's one. */
1752 if (tr->tr_callback)
1753 tr->tr_callback(tr);
1754 else
1755 if (tr->tr_flags & TWA_CMD_SLEEP_ON_REQUEST) {
1756 /* Wake up the sleeping command originator. */
1757 twa_dbg_dprint(7, sc, "Waking up originator of request %p", tr);
1758 wakeup_one(tr);
1759 }
1760 }
1761 }
1762
1763
1764
1765 /*
1766 * Function name: twa_wait_status
1767 * Description: Wait for a given status to show up in the fw status register.
1768 *
1769 * Input: sc -- ptr to per ctlr structure
1770 * status -- status to look for
1771 * timeout -- max # of seconds to wait before giving up
1772 * Output: None
1773 * Return value: 0 -- success
1774 * non-zero-- failure
1775 */
1776 static int
1777 twa_wait_status(struct twa_softc *sc, u_int32_t status, u_int32_t timeout)
1778 {
1779 time_t end_time;
1780 u_int32_t status_reg;
1781
1782 twa_dbg_dprint_enter(4, sc);
1783
1784 end_time = time_second + timeout;
1785 do {
1786 status_reg = TWA_READ_STATUS_REGISTER(sc);
1787 if ((status_reg & status) == status)/* got the required bit(s)? */
1788 return(0);
1789 DELAY(1000);
1790 } while (time_second <= end_time);
1791
1792 return(1);
1793 }
1794
1795
1796
1797 /*
1798 * Function name: twa_drain_response_queue
1799 * Description: Drain the response queue.
1800 *
1801 * Input: sc -- ptr to per ctlr structure
1802 * Output: None
1803 * Return value: 0 -- success
1804 * non-zero-- failure
1805 */
1806 static int
1807 twa_drain_response_queue(struct twa_softc *sc)
1808 {
1809 union twa_response_queue rq;
1810 u_int32_t status_reg;
1811
1812 twa_dbg_dprint_enter(4, sc);
1813
1814 for (;;) {
1815 status_reg = TWA_READ_STATUS_REGISTER(sc);
1816 if (twa_check_ctlr_state(sc, status_reg))
1817 return(1);
1818 if (status_reg & TWA_STATUS_RESPONSE_QUEUE_EMPTY)
1819 return(0); /* no more response queue entries */
1820 rq = TWA_READ_RESPONSE_QUEUE(sc);
1821 }
1822 }
1823
1824
1825
1826 /*
1827 * Function name: twa_host_intr
1828 * Description: This function gets called if we triggered an interrupt.
1829 * We don't use it as of now.
1830 *
1831 * Input: sc -- ptr to per ctlr structure
1832 * Output: None
1833 * Return value: None
1834 */
1835 static void
1836 twa_host_intr(struct twa_softc *sc)
1837 {
1838 twa_dbg_dprint_enter(6, sc);
1839
1840 TWA_WRITE_CONTROL_REGISTER(sc, TWA_CONTROL_CLEAR_HOST_INTERRUPT);
1841 }
1842
1843
1844
1845 /*
1846 * Function name: twa_attention_intr
1847 * Description: This function gets called if the fw posted an AEN
1848 * (Asynchronous Event Notification). It fetches
1849 * all the AEN's that the fw might have posted.
1850 *
1851 * Input: sc -- ptr to per ctlr structure
1852 * Output: None
1853 * Return value: None
1854 */
1855 static void
1856 twa_attention_intr(struct twa_softc *sc)
1857 {
1858 int error;
1859
1860 twa_dbg_dprint_enter(6, sc);
1861
1862 TWA_WRITE_CONTROL_REGISTER(sc, TWA_CONTROL_CLEAR_ATTENTION_INTERRUPT);
1863 if ((error = twa_fetch_aen(sc)))
1864 twa_printf(sc, "Fetch AEN failed. error = 0x%x\n", error);
1865 }
1866
1867
1868
1869 /*
1870 * Function name: twa_command_intr
1871 * Description: This function gets called if we hit a queue full
1872 * condition earlier, and the fw is now ready for
1873 * new cmds. Submits any pending requests.
1874 *
1875 * Input: sc -- ptr to per ctlr structure
1876 * Output: None
1877 * Return value: None
1878 */
1879 static void
1880 twa_command_intr(struct twa_softc *sc)
1881 {
1882 twa_dbg_dprint_enter(6, sc);
1883
1884 TWA_WRITE_CONTROL_REGISTER(sc, TWA_CONTROL_MASK_COMMAND_INTERRUPT);
1885 /*
1886 * Start any requests that might be in the pending queue.
1887 * If all requests could not be started because of a queue_full
1888 * condition, twa_start will have unmasked the command interrupt.
1889 */
1890 twa_drain_pending_queue(sc);
1891 }
1892
1893
1894
1895 /*
1896 * Function name: twa_fetch_aen
1897 * Description: Send down a Request Sense cmd to fw to fetch an AEN.
1898 *
1899 * Input: sc -- ptr to per ctlr structure
1900 * Output: None
1901 * Return value: 0 -- success
1902 * non-zero-- failure
1903 */
1904 static int
1905 twa_fetch_aen(struct twa_softc *sc)
1906 {
1907 struct twa_request *tr;
1908 int error = 0;
1909
1910 twa_dbg_dprint_enter(4, sc);
1911
1912 if ((tr = twa_get_request(sc)) == NULL)
1913 return(EIO);
1914 tr->tr_cmd_pkt_type |= TWA_CMD_PKT_TYPE_INTERNAL;
1915 tr->tr_callback = twa_aen_callback;
1916 if ((error = twa_send_scsi_cmd(tr, 0x03 /* REQUEST_SENSE */))) {
1917 if (tr->tr_data)
1918 free(tr->tr_data, M_DEVBUF);
1919 twa_release_request(tr);
1920 }
1921 return(error);
1922 }
1923
1924
1925
1926 /*
1927 * Function name: twa_aen_callback
1928 * Description: Callback for requests to fetch AEN's.
1929 *
1930 * Input: tr -- ptr to completed request pkt
1931 * Output: None
1932 * Return value: None
1933 */
1934 static void
1935 twa_aen_callback(struct twa_request *tr)
1936 {
1937 struct twa_softc *sc = tr->tr_sc;
1938 struct twa_command_header *cmd_hdr;
1939 struct twa_command_9k *cmd = &(tr->tr_command->command.cmd_pkt_9k);
1940 u_int8_t *error_str;
1941 int fetch_more_aens = 0;
1942 int error;
1943 int i;
1944
1945 twa_dbg_dprint_enter(4, sc);
1946
1947 twa_dbg_dprint(4, sc, "req_id = 0x%x, status = 0x%x",
1948 cmd->request_id,
1949 cmd->status);
1950
1951 if (tr->tr_error)
1952 goto out;
1953
1954 if (! cmd->status) {
1955 cmd_hdr = (struct twa_command_header *)(tr->tr_data);
1956 if ((tr->tr_cmd_pkt_type & TWA_CMD_PKT_TYPE_9K) &&
1957 (cmd->cdb[0] == 0x3 /* REQUEST_SENSE */))
1958 if (twa_enqueue_aen(sc, cmd_hdr) != TWA_AEN_QUEUE_EMPTY)
1959 fetch_more_aens = 1;
1960 } else {
1961 cmd_hdr = &(tr->tr_command->cmd_hdr);
1962 error_str = &(cmd_hdr->err_desc[strlen(cmd_hdr->err_desc) + 1]);
1963
1964 if (error_str[0] == '\0')
1965 error_str = twa_find_msg_string(twa_error_table,
1966 cmd_hdr->status_block.error);
1967 twa_printf(sc, "%s: cmd = 0x%x: ERROR: (0x%02X: 0x%04X): %s: %s\n",
1968 __func__, cmd->command.opcode,
1969 TWA_MESSAGE_SOURCE_CONTROLLER_ERROR,
1970 cmd_hdr->status_block.error,
1971 error_str,
1972 cmd_hdr->err_desc);
1973 twa_dbg_print(2, "sense info: ");
1974 for (i = 0; i < 18; i++)
1975 twa_dbg_print(2, "%x\t", tr->tr_command->cmd_hdr.sense_data[i]);
1976 twa_dbg_print(2, ""); /* print new line */
1977 for (i = 0; i < 128; i++)
1978 twa_dbg_print(7, "%x\t", ((int8_t *)(tr->tr_data))[i]);
1979 }
1980
1981 out:
1982 if (tr->tr_data)
1983 free(tr->tr_data, M_DEVBUF);
1984 twa_release_request(tr);
1985 if (fetch_more_aens)
1986 if ((error = twa_fetch_aen(sc)))
1987 twa_printf(sc, "%s: Fetch AEN failed. error = 0x%x\n",
1988 __func__, error);
1989 }
1990
1991
1992
1993 /*
1994 * Function name: twa_drain_aen_queue
1995 * Description: Fetches all un-retrieved AEN's posted by fw.
1996 *
1997 * Input: sc -- ptr to per ctlr structure
1998 * Output: None
1999 * Return value: 0 -- success
2000 * non-zero-- failure
2001 */
2002 static int
2003 twa_drain_aen_queue(struct twa_softc *sc)
2004 {
2005 struct twa_request *tr;
2006 struct twa_command_header *cmd_hdr;
2007 time_t end_time;
2008 int error = 0;
2009
2010 for (;;) {
2011 if ((tr = twa_get_request(sc)) == NULL) {
2012 error = EIO;
2013 break;
2014 }
2015 tr->tr_cmd_pkt_type |= TWA_CMD_PKT_TYPE_INTERNAL;
2016 tr->tr_callback = NULL;
2017 if ((error = twa_send_scsi_cmd(tr, 0x03 /* REQUEST_SENSE */))) {
2018 twa_dbg_dprint(1, sc, "Cannot send command to fetch aen");
2019 break;
2020 }
2021
2022 end_time = time_second + TWA_REQUEST_TIMEOUT_PERIOD;
2023 do {
2024 twa_done(tr->tr_sc);
2025 if (tr->tr_status != TWA_CMD_BUSY)
2026 break;
2027 } while (time_second <= end_time);
2028
2029 if (tr->tr_status != TWA_CMD_COMPLETE) {
2030 error = ETIMEDOUT;
2031 break;
2032 }
2033
2034 if ((error = tr->tr_command->command.cmd_pkt_9k.status))
2035 break;
2036
2037 cmd_hdr = (struct twa_command_header *)(tr->tr_data);
2038 if (twa_enqueue_aen(sc, cmd_hdr) == TWA_AEN_QUEUE_EMPTY)
2039 break;
2040
2041 free(tr->tr_data, M_DEVBUF);
2042 twa_release_request(tr);
2043 }
2044
2045 if (tr) {
2046 if (tr->tr_data)
2047 free(tr->tr_data, M_DEVBUF);
2048 twa_release_request(tr);
2049 }
2050 return(error);
2051 }
2052
2053
2054
2055 /*
2056 * Function name: twa_enqueue_aen
2057 * Description: Queues AEN's to be supplied to user-space tools on request.
2058 *
2059 * Input: sc -- ptr to per ctlr structure
2060 * cmd_hdr -- ptr to hdr of fw cmd pkt, from where the AEN
2061 * details can be retrieved.
2062 * Output: None
2063 * Return value: AEN code
2064 */
2065 static unsigned short
2066 twa_enqueue_aen(struct twa_softc *sc, struct twa_command_header *cmd_hdr)
2067 {
2068 struct twa_event_packet *event;
2069 unsigned short aen_code;
2070 unsigned long local_time;
2071 unsigned long sync_time;
2072 u_int8_t *aen_str;
2073 int s;
2074
2075 twa_dbg_dprint_enter(4, sc);
2076 s = splcam();
2077 aen_code = cmd_hdr->status_block.error;
2078
2079 switch (aen_code) {
2080 case TWA_AEN_SYNC_TIME_WITH_HOST:
2081 twa_dbg_dprint(4, sc, "Received AEN_SYNC_TIME");
2082 /* Calculate time (in seconds) since last Sunday 12.00 AM. */
2083 local_time = time_second - (tz.tz_minuteswest * 60) -
2084 (wall_cmos_clock ? adjkerntz : 0);
2085 sync_time = (local_time - (3 * 86400)) % 604800;
2086 if (twa_set_param(sc, TWA_PARAM_TIME_TABLE,
2087 TWA_PARAM_TIME_SchedulerTime, 4,
2088 &sync_time, twa_aen_callback))
2089 twa_printf(sc, "Unable to sync time with ctlr!\n");
2090 break;
2091
2092 case TWA_AEN_QUEUE_EMPTY:
2093 twa_dbg_dprint(4, sc, "AEN queue empty");
2094 break;
2095
2096 default:
2097 /* Queue the event. */
2098 event = sc->twa_aen_queue[sc->twa_aen_head];
2099 if (event->retrieved == TWA_AEN_NOT_RETRIEVED)
2100 sc->twa_aen_queue_overflow = TRUE;
2101 event->severity = cmd_hdr->status_block.substatus_block.severity;
2102 local_time = time_second - (tz.tz_minuteswest * 60) -
2103 (wall_cmos_clock ? adjkerntz : 0);
2104 event->time_stamp_sec = local_time;
2105 event->aen_code = aen_code;
2106 event->retrieved = TWA_AEN_NOT_RETRIEVED;
2107 event->sequence_id = ++(sc->twa_current_sequence_id);
2108
2109 aen_str = &(cmd_hdr->err_desc[strlen(cmd_hdr->err_desc) + 1]);
2110 if (aen_str[0] == '\0')
2111 aen_str = twa_find_msg_string(twa_aen_table, aen_code);
2112
2113
2114 event->parameter_len = strlen(cmd_hdr->err_desc) +
2115 strlen(aen_str) + 2;
2116 bcopy(cmd_hdr->err_desc, event->parameter_data,
2117 event->parameter_len);
2118
2119 twa_dbg_dprint(4, sc, "event = %x %x %x %x %x %x %x\n %s %s",
2120 event->sequence_id,
2121 event->time_stamp_sec,
2122 event->aen_code,
2123 event->severity,
2124 event->retrieved,
2125 event->repeat_count,
2126 event->parameter_len,
2127 &(event->parameter_data[strlen(cmd_hdr->err_desc) + 1]),
2128 event->parameter_data);
2129
2130 twa_dbg_dprint(4, sc, "cmd_hdr = %x %lx %x %x %x %x %zx\n %s %s",
2131 sc->twa_current_sequence_id,
2132 local_time,
2133 cmd_hdr->status_block.error,
2134 cmd_hdr->status_block.substatus_block.severity,
2135 TWA_AEN_NOT_RETRIEVED,
2136 0,
2137 strlen(cmd_hdr->err_desc),
2138 &(cmd_hdr->err_desc[strlen(cmd_hdr->err_desc) + 1]),
2139 cmd_hdr->err_desc);
2140
2141 /* Print the event. */
2142 if (event->severity < TWA_AEN_SEVERITY_DEBUG)
2143 twa_printf(sc, "%s: (0x%02X: 0x%04X): %s: %s\n",
2144 twa_aen_severity_table[event->severity],
2145 TWA_MESSAGE_SOURCE_CONTROLLER_EVENT,
2146 aen_code,
2147 aen_str,
2148 event->parameter_data);
2149
2150 if ((sc->twa_aen_head + 1) == TWA_Q_LENGTH)
2151 sc->twa_aen_queue_wrapped = TRUE;
2152 sc->twa_aen_head = (sc->twa_aen_head + 1) % TWA_Q_LENGTH;
2153 break;
2154 } /* switch */
2155 splx(s);
2156 return(aen_code);
2157 }
2158
2159
2160
2161 /*
2162 * Function name: twa_find_aen
2163 * Description: Reports whether a given AEN ever occurred.
2164 *
2165 * Input: sc -- ptr to per ctlr structure
2166 * aen_code-- AEN to look for
2167 * Output: None
2168 * Return value: 0 -- success
2169 * non-zero-- failure
2170 */
2171 static int
2172 twa_find_aen(struct twa_softc *sc, u_int16_t aen_code)
2173 {
2174 u_int32_t last_index;
2175 int s;
2176 int i;
2177
2178 s = splcam();
2179
2180 if (sc->twa_aen_queue_wrapped)
2181 last_index = sc->twa_aen_head;
2182 else
2183 last_index = 0;
2184
2185 i = sc->twa_aen_head;
2186 do {
2187 i = (i + TWA_Q_LENGTH - 1) % TWA_Q_LENGTH;
2188 if ((sc->twa_aen_queue[i])->aen_code == aen_code) {
2189 splx(s);
2190 return(0);
2191 }
2192 } while (i != last_index);
2193
2194 splx(s);
2195 return(1);
2196 }
2197
2198
2199
2200 /*
2201 * Function name: twa_find_msg_string
2202 * Description: Looks up a given table, and returns the message string
2203 * corresponding to a given code (error code or AEN code).
2204 *
2205 * Input: sc -- ptr to per ctlr structure
2206 * code -- code, the message string corresponding to
2207 * which is to be returned.
2208 * Output: None
2209 * Return value: ptr to corresponding msg string -- success
2210 * NULL -- failure
2211 */
2212 char *
2213 twa_find_msg_string(struct twa_message *table, u_int16_t code)
2214 {
2215 int i;
2216
2217 for (i = 0; table[i].message != NULL; i++)
2218 if (table[i].code == code)
2219 return(table[i].message);
2220
2221 return(table[i].message);
2222 }
2223
2224
2225
2226 /*
2227 * Function name: twa_get_request
2228 * Description: Gets a request pkt from the free queue.
2229 *
2230 * Input: sc -- ptr to per ctlr structure
2231 * Output: None
2232 * Return value: ptr to request pkt -- success
2233 * NULL -- failure
2234 */
2235 struct twa_request *
2236 twa_get_request(struct twa_softc *sc)
2237 {
2238 struct twa_request *tr;
2239
2240 twa_dbg_dprint_enter(4, sc);
2241
2242 /* Get a free request packet. */
2243 tr = twa_dequeue_free(sc);
2244
2245 /* Initialize some fields to their defaults. */
2246 if (tr) {
2247 tr->tr_data = NULL;
2248 tr->tr_real_data = NULL;
2249 tr->tr_length = 0;
2250 tr->tr_real_length = 0;
2251 tr->tr_status = TWA_CMD_SETUP;/* command is in setup phase */
2252 tr->tr_flags = 0;
2253 tr->tr_error = 0;
2254 tr->tr_private = NULL;
2255 tr->tr_callback = NULL;
2256 tr->tr_cmd_pkt_type = 0;
2257
2258 /*
2259 * Look at the status field in the command packet to see how
2260 * it completed the last time it was used, and zero out only
2261 * the portions that might have changed. Note that we don't
2262 * care to zero out the sglist.
2263 */
2264 if (tr->tr_command->command.cmd_pkt_9k.status)
2265 bzero(tr->tr_command,
2266 sizeof(struct twa_command_header) + 28 /* max bytes before sglist */);
2267 else
2268 bzero(&(tr->tr_command->command), 28 /* max bytes before sglist */);
2269 }
2270 return(tr);
2271 }
2272
2273
2274
2275 /*
2276 * Function name: twa_release_request
2277 * Description: Puts a request pkt into the free queue.
2278 *
2279 * Input: tr -- ptr to request pkt to be freed
2280 * Output: None
2281 * Return value: None
2282 */
2283 void
2284 twa_release_request(struct twa_request *tr)
2285 {
2286 twa_dbg_dprint_enter(4, tr->tr_sc);
2287
2288 twa_enqueue_free(tr);
2289 }
2290
2291
2292
2293 /*
2294 * Function name: twa_describe_controller
2295 * Description: Describes the controller, in terms of its fw version,
2296 * BIOS version etc.
2297 *
2298 * Input: sc -- ptr to per ctlr structure
2299 * Output: None
2300 * Return value: None
2301 */
2302 void
2303 twa_describe_controller(struct twa_softc *sc)
2304 {
2305 struct twa_param_9k *p[6];
2306 u_int8_t num_ports = 0;
2307
2308 twa_dbg_dprint_enter(2, sc);
2309
2310 /* Get the port count. */
2311 p[0] = twa_get_param(sc, TWA_PARAM_CONTROLLER_TABLE,
2312 TWA_PARAM_CONTROLLER_PORT_COUNT, 1, NULL);
2313 if (p[0]) {
2314 num_ports = *(u_int8_t *)(p[0]->data);
2315 free(p[0], M_DEVBUF);
2316 }
2317
2318 /* Get the firmware and BIOS versions. */
2319 p[0] = twa_get_param(sc, TWA_PARAM_VERSION_TABLE,
2320 TWA_PARAM_VERSION_FW, 16, NULL);
2321 p[1] = twa_get_param(sc, TWA_PARAM_VERSION_TABLE,
2322 TWA_PARAM_VERSION_BIOS, 16, NULL);
2323
2324 twa_printf(sc, "%d ports, Firmware %.16s, BIOS %.16s\n",
2325 num_ports, p[0]?(p[0]->data):NULL, p[1]?(p[1]->data):NULL);
2326 if (bootverbose) {
2327 /* Get more versions. */
2328 p[2] = twa_get_param(sc, TWA_PARAM_VERSION_TABLE,
2329 TWA_PARAM_VERSION_MONITOR, 16, NULL);
2330 p[3] = twa_get_param(sc, TWA_PARAM_VERSION_TABLE,
2331 TWA_PARAM_VERSION_PCBA, 8, NULL);
2332 p[4] = twa_get_param(sc, TWA_PARAM_VERSION_TABLE,
2333 TWA_PARAM_VERSION_ATA, 8, NULL);
2334 p[5] = twa_get_param(sc, TWA_PARAM_VERSION_TABLE,
2335 TWA_PARAM_VERSION_PCI, 8, NULL);
2336
2337 twa_printf(sc, "Monitor %.16s, PCB %.8s, Achip %.8s, Pchip %.8s\n",
2338 p[2]?(p[2]->data):NULL, p[3]?(p[3]->data):NULL,
2339 p[4]?(p[4]->data):NULL, p[5]?(p[5]->data):NULL);
2340
2341 if (p[2])
2342 free(p[2], M_DEVBUF);
2343 if (p[3])
2344 free(p[3], M_DEVBUF);
2345 if (p[4])
2346 free(p[4], M_DEVBUF);
2347 if (p[5])
2348 free(p[5], M_DEVBUF);
2349 }
2350 if (p[0])
2351 free(p[0], M_DEVBUF);
2352 if (p[1])
2353 free(p[1], M_DEVBUF);
2354 }
2355
2356
2357
2358 /*
2359 * Function name: twa_check_ctlr_state
2360 * Description: Makes sure that the fw status register reports a
2361 * proper status.
2362 *
2363 * Input: sc -- ptr to per ctlr structure
2364 * status_reg -- value in the status register
2365 * Output: None
2366 * Return value: 0 -- no errors
2367 * non-zero-- errors
2368 */
2369 static int
2370 twa_check_ctlr_state(struct twa_softc *sc, u_int32_t status_reg)
2371 {
2372 int result = 0;
2373 static time_t last_warning[2] = {0, 0};
2374
2375 /* Check if the 'micro-controller ready' bit is not set. */
2376 if ((status_reg & TWA_STATUS_EXPECTED_BITS) !=
2377 TWA_STATUS_EXPECTED_BITS) {
2378 if (time_second > (last_warning[0] + 5)) {
2379 twa_printf(sc, "Missing expected status bit(s) %b\n",
2380 ~status_reg & TWA_STATUS_EXPECTED_BITS,
2381 TWA_STATUS_BITS_DESCRIPTION);
2382 last_warning[0] = time_second;
2383 }
2384 result = 1;
2385 }
2386
2387 /* Check if any error bits are set. */
2388 if ((status_reg & TWA_STATUS_UNEXPECTED_BITS) != 0) {
2389 if (time_second > (last_warning[1] + 5)) {
2390 twa_printf(sc, "Unexpected status bit(s) %b\n",
2391 status_reg & TWA_STATUS_UNEXPECTED_BITS,
2392 TWA_STATUS_BITS_DESCRIPTION);
2393 last_warning[1] = time_second;
2394 }
2395 if (status_reg & TWA_STATUS_PCI_PARITY_ERROR_INTERRUPT) {
2396 twa_printf(sc, "PCI parity error: clearing... Re-seat/move/replace card.\n");
2397 TWA_WRITE_CONTROL_REGISTER(sc, TWA_CONTROL_CLEAR_PARITY_ERROR);
2398 twa_write_pci_config(sc, TWA_PCI_CONFIG_CLEAR_PARITY_ERROR, 2);
2399 }
2400 if (status_reg & TWA_STATUS_PCI_ABORT_INTERRUPT) {
2401 twa_printf(sc, "PCI abort: clearing...\n");
2402 TWA_WRITE_CONTROL_REGISTER(sc, TWA_CONTROL_CLEAR_PCI_ABORT);
2403 twa_write_pci_config(sc, TWA_PCI_CONFIG_CLEAR_PCI_ABORT, 2);
2404 }
2405 if (status_reg & TWA_STATUS_QUEUE_ERROR_INTERRUPT) {
2406 twa_printf(sc, "Controller queue error: clearing...\n");
2407 TWA_WRITE_CONTROL_REGISTER(sc, TWA_CONTROL_CLEAR_PCI_ABORT);
2408 }
2409 if (status_reg & TWA_STATUS_SBUF_WRITE_ERROR) {
2410 twa_printf(sc, "SBUF write error: clearing...\n");
2411 TWA_WRITE_CONTROL_REGISTER(sc, TWA_CONTROL_CLEAR_SBUF_WRITE_ERROR);
2412 }
2413 if (status_reg & TWA_STATUS_MICROCONTROLLER_ERROR) {
2414 twa_printf(sc, "Micro-controller error!\n");
2415 result = 1;
2416 }
2417 }
2418 return(result);
2419 }
2420
2421
2422
2423 /*
2424 * Function name: twa_print_controller
2425 * Description: Prints the current status of the controller.
2426 *
2427 * Input: sc -- ptr to per ctlr structure
2428 * Output: None
2429 * Return value: None
2430 */
2431 void
2432 twa_print_controller(struct twa_softc *sc)
2433 {
2434 u_int32_t status_reg;
2435
2436 /* Print current controller details. */
2437 status_reg = TWA_READ_STATUS_REGISTER(sc);
2438 twa_printf(sc, "status %b\n", status_reg, TWA_STATUS_BITS_DESCRIPTION);
2439 #ifdef TWA_DEBUG
2440 twa_printf(sc, "q type current max\n");
2441 twa_printf(sc, "free %04d %04d\n",
2442 sc->twa_qstats[TWAQ_FREE].q_length, sc->twa_qstats[TWAQ_FREE].q_max);
2443 twa_printf(sc, "busy %04d %04d\n",
2444 sc->twa_qstats[TWAQ_BUSY].q_length, sc->twa_qstats[TWAQ_BUSY].q_max);
2445 twa_printf(sc, "pending %04d %04d\n",
2446 sc->twa_qstats[TWAQ_PENDING].q_length, sc->twa_qstats[TWAQ_PENDING].q_max);
2447 twa_printf(sc, "complete %04d %04d\n",
2448 sc->twa_qstats[TWAQ_COMPLETE].q_length, sc->twa_qstats[TWAQ_COMPLETE].q_max);
2449 #endif /* TWA_DEBUG */
2450 twa_printf(sc, "AEN queue head %d tail %d\n",
2451 sc->twa_aen_head, sc->twa_aen_tail);
2452 }
2453
2454
2455
2456 /*
2457 * Function name: twa_panic
2458 * Description: Called when something is seriously wrong with the ctlr.
2459 * Hits the debugger if the debugger is turned on, else
2460 * resets the ctlr.
2461 *
2462 * Input: sc -- ptr to per ctlr structure
2463 * reason -- string describing what went wrong
2464 * Output: None
2465 * Return value: None
2466 */
2467 static void
2468 twa_panic(struct twa_softc *sc, int8_t *reason)
2469 {
2470 twa_print_controller(sc);
2471 #ifdef TWA_DEBUG
2472 panic(reason);
2473 #else
2474 twa_printf(sc, "twa_panic: RESETTING CONTROLLER...\n");
2475 twa_reset(sc);
2476 #endif
2477 }
2478
Cache object: c8291761391147774100bedfabcc6d37
|