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