1 /*
   2  * CDDL HEADER START
   3  *
   4  * The contents of this file are subject to the terms of the
   5  * Common Development and Distribution License (the "License").
   6  * You may not use this file except in compliance with the License.
   7  *
   8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
   9  * or http://www.opensolaris.org/os/licensing.
  10  * See the License for the specific language governing permissions
  11  * and limitations under the License.
  12  *
  13  * When distributing Covered Code, include this CDDL HEADER in each
  14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15  * If applicable, add the following below this CDDL HEADER, with the
  16  * fields enclosed by brackets "[]" replaced with your own identifying
  17  * information: Portions Copyright [yyyy] [name of copyright owner]
  18  *
  19  * CDDL HEADER END
  20  */
  21 
  22 /* Copyright 2010 QLogic Corporation */
  23 
  24 /*
  25  * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
  26  */
  27 /*
  28  * Copyright 2011 Nexenta Systems, Inc.  All rights reserved.
  29  * Copyright (c) 2016 by Delphix. All rights reserved.
  30  */
  31 
  32 #pragma ident   "Copyright 2010 QLogic Corporation; ql_api.c"
  33 
  34 /*
  35  * ISP2xxx Solaris Fibre Channel Adapter (FCA) driver source file.
  36  *
  37  * ***********************************************************************
  38  * *                                                                    **
  39  * *                            NOTICE                                  **
  40  * *            COPYRIGHT (C) 1996-2010 QLOGIC CORPORATION              **
  41  * *                    ALL RIGHTS RESERVED                             **
  42  * *                                                                    **
  43  * ***********************************************************************
  44  *
  45  */
  46 
  47 #include <ql_apps.h>
  48 #include <ql_api.h>
  49 #include <ql_debug.h>
  50 #include <ql_init.h>
  51 #include <ql_iocb.h>
  52 #include <ql_ioctl.h>
  53 #include <ql_isr.h>
  54 #include <ql_mbx.h>
  55 #include <ql_nx.h>
  56 #include <ql_xioctl.h>
  57 
  58 /*
  59  * Solaris external defines.
  60  */
  61 extern pri_t minclsyspri;
  62 extern pri_t maxclsyspri;
  63 
  64 /*
  65  * dev_ops functions prototypes
  66  */
  67 static int ql_getinfo(dev_info_t *, ddi_info_cmd_t, void *, void **);
  68 static int ql_attach(dev_info_t *, ddi_attach_cmd_t);
  69 static int ql_detach(dev_info_t *, ddi_detach_cmd_t);
  70 static int ql_power(dev_info_t *, int, int);
  71 static int ql_quiesce(dev_info_t *);
  72 
  73 /*
  74  * FCA functions prototypes exported by means of the transport table
  75  */
  76 static opaque_t ql_bind_port(dev_info_t *, fc_fca_port_info_t *,
  77     fc_fca_bind_info_t *);
  78 static void ql_unbind_port(opaque_t);
  79 static int ql_init_pkt(opaque_t, fc_packet_t *, int);
  80 static int ql_un_init_pkt(opaque_t, fc_packet_t *);
  81 static int ql_els_send(opaque_t, fc_packet_t *);
  82 static int ql_get_cap(opaque_t, char *, void *);
  83 static int ql_set_cap(opaque_t, char *, void *);
  84 static int ql_getmap(opaque_t, fc_lilpmap_t *);
  85 static int ql_transport(opaque_t, fc_packet_t *);
  86 static int ql_ub_alloc(opaque_t, uint64_t *, uint32_t, uint32_t *, uint32_t);
  87 static int ql_ub_free(opaque_t, uint32_t, uint64_t *);
  88 static int ql_ub_release(opaque_t, uint32_t, uint64_t *);
  89 static int ql_abort(opaque_t, fc_packet_t *, int);
  90 static int ql_reset(opaque_t, uint32_t);
  91 static int ql_port_manage(opaque_t, fc_fca_pm_t *);
  92 static opaque_t ql_get_device(opaque_t, fc_portid_t);
  93 
  94 /*
  95  * FCA Driver Support Function Prototypes.
  96  */
  97 static uint16_t ql_wait_outstanding(ql_adapter_state_t *);
  98 static void ql_task_mgmt(ql_adapter_state_t *, ql_tgt_t *, fc_packet_t *,
  99     ql_srb_t *);
 100 static void ql_task_daemon(void *);
 101 static void ql_task_thread(ql_adapter_state_t *);
 102 static void ql_unsol_callback(ql_srb_t *);
 103 static void ql_free_unsolicited_buffer(ql_adapter_state_t *,
 104     fc_unsol_buf_t *);
 105 static void ql_timer(void *);
 106 static void ql_watchdog(ql_adapter_state_t *, uint32_t *, uint32_t *);
 107 static void ql_cmd_timeout(ql_adapter_state_t *, ql_tgt_t *q, ql_srb_t *,
 108     uint32_t *, uint32_t *);
 109 static void ql_halt(ql_adapter_state_t *, int);
 110 static int ql_els_plogi(ql_adapter_state_t *, fc_packet_t *);
 111 static int ql_els_flogi(ql_adapter_state_t *, fc_packet_t *);
 112 static int ql_els_logo(ql_adapter_state_t *, fc_packet_t *);
 113 static int ql_els_prli(ql_adapter_state_t *, fc_packet_t *);
 114 static int ql_els_prlo(ql_adapter_state_t *, fc_packet_t *);
 115 static int ql_els_adisc(ql_adapter_state_t *, fc_packet_t *);
 116 static int ql_els_linit(ql_adapter_state_t *, fc_packet_t *);
 117 static int ql_els_lpc(ql_adapter_state_t *, fc_packet_t *);
 118 static int ql_els_lsts(ql_adapter_state_t *, fc_packet_t *);
 119 static int ql_els_scr(ql_adapter_state_t *, fc_packet_t *);
 120 static int ql_els_rscn(ql_adapter_state_t *, fc_packet_t *);
 121 static int ql_els_farp_req(ql_adapter_state_t *, fc_packet_t *);
 122 static int ql_els_farp_reply(ql_adapter_state_t *, fc_packet_t *);
 123 static int ql_els_rls(ql_adapter_state_t *, fc_packet_t *);
 124 static int ql_els_rnid(ql_adapter_state_t *, fc_packet_t *);
 125 static int ql_login_port(ql_adapter_state_t *, port_id_t);
 126 static int ql_login_fabric_port(ql_adapter_state_t *, ql_tgt_t *, uint16_t);
 127 static int ql_logout_port(ql_adapter_state_t *, port_id_t);
 128 static ql_lun_t *ql_lun_queue(ql_adapter_state_t *, ql_tgt_t *, uint16_t);
 129 static int ql_fcp_scsi_cmd(ql_adapter_state_t *, fc_packet_t *, ql_srb_t *);
 130 static int ql_fcp_ip_cmd(ql_adapter_state_t *, fc_packet_t *, ql_srb_t *);
 131 static int ql_fc_services(ql_adapter_state_t *, fc_packet_t *);
 132 static int ql_poll_cmd(ql_adapter_state_t *, ql_srb_t *, time_t);
 133 static int ql_start_cmd(ql_adapter_state_t *, ql_tgt_t *, fc_packet_t *,
 134     ql_srb_t *);
 135 static int ql_kstat_update(kstat_t *, int);
 136 static ql_adapter_state_t *ql_fca_handle_to_state(opaque_t);
 137 static ql_adapter_state_t *ql_cmd_setup(opaque_t, fc_packet_t *, int *);
 138 static int ql_program_flash_address(ql_adapter_state_t *, uint32_t, uint8_t);
 139 static void ql_rst_aen(ql_adapter_state_t *);
 140 static void ql_restart_queues(ql_adapter_state_t *);
 141 static void ql_abort_queues(ql_adapter_state_t *);
 142 static void ql_abort_device_queues(ql_adapter_state_t *ha, ql_tgt_t *tq);
 143 static void ql_idle_check(ql_adapter_state_t *);
 144 static int ql_loop_resync(ql_adapter_state_t *);
 145 static size_t ql_24xx_ascii_fw_dump(ql_adapter_state_t *, caddr_t);
 146 static size_t ql_2581_ascii_fw_dump(ql_adapter_state_t *, caddr_t);
 147 static int ql_save_config_regs(dev_info_t *);
 148 static int ql_restore_config_regs(dev_info_t *);
 149 static int ql_process_rscn(ql_adapter_state_t *, fc_affected_id_t *);
 150 static int ql_handle_rscn_update(ql_adapter_state_t *);
 151 static int ql_send_plogi(ql_adapter_state_t *, ql_tgt_t *, ql_head_t *);
 152 static int ql_process_rscn_for_device(ql_adapter_state_t *, ql_tgt_t *);
 153 static int ql_dump_firmware(ql_adapter_state_t *);
 154 static int ql_process_logo_for_device(ql_adapter_state_t *, ql_tgt_t *);
 155 static int ql_2200_binary_fw_dump(ql_adapter_state_t *, ql_fw_dump_t *);
 156 static int ql_2300_binary_fw_dump(ql_adapter_state_t *, ql_fw_dump_t *);
 157 static int ql_24xx_binary_fw_dump(ql_adapter_state_t *, ql_24xx_fw_dump_t *);
 158 static int ql_25xx_binary_fw_dump(ql_adapter_state_t *, ql_25xx_fw_dump_t *);
 159 static int ql_81xx_binary_fw_dump(ql_adapter_state_t *, ql_81xx_fw_dump_t *);
 160 static int ql_read_risc_ram(ql_adapter_state_t *, uint32_t, uint32_t,
 161     void *);
 162 static void *ql_read_regs(ql_adapter_state_t *, void *, void *, uint32_t,
 163     uint8_t);
 164 static int ql_busy_plogi(ql_adapter_state_t *, fc_packet_t *, ql_tgt_t *);
 165 static int ql_suspend_adapter(ql_adapter_state_t *);
 166 static int ql_bstr_to_dec(char *, uint32_t *, uint32_t);
 167 static void ql_update_rscn(ql_adapter_state_t *, fc_affected_id_t *);
 168 int ql_alloc_dma_resouce(ql_adapter_state_t *, dma_mem_t *, int);
 169 static int ql_bind_dma_buffer(ql_adapter_state_t *, dma_mem_t *, int);
 170 static void ql_unbind_dma_buffer(ql_adapter_state_t *, dma_mem_t *);
 171 static void ql_timeout_insert(ql_adapter_state_t *, ql_tgt_t *, ql_srb_t *);
 172 static int ql_setup_interrupts(ql_adapter_state_t *);
 173 static int ql_setup_msi(ql_adapter_state_t *);
 174 static int ql_setup_msix(ql_adapter_state_t *);
 175 static int ql_setup_fixed(ql_adapter_state_t *);
 176 static void ql_release_intr(ql_adapter_state_t *);
 177 static void ql_disable_intr(ql_adapter_state_t *);
 178 static int ql_legacy_intr(ql_adapter_state_t *);
 179 static int ql_init_mutex(ql_adapter_state_t *);
 180 static void ql_destroy_mutex(ql_adapter_state_t *);
 181 static void ql_iidma(ql_adapter_state_t *);
 182 
 183 static int ql_n_port_plogi(ql_adapter_state_t *);
 184 static void ql_fca_isp_els_request(ql_adapter_state_t *, fc_packet_t *,
 185     els_descriptor_t *);
 186 static void ql_isp_els_request_ctor(els_descriptor_t *,
 187     els_passthru_entry_t *);
 188 static int ql_p2p_plogi(ql_adapter_state_t *, fc_packet_t *);
 189 static int ql_wait_for_td_stop(ql_adapter_state_t *);
 190 static void ql_process_idc_event(ql_adapter_state_t *);
 191 
 192 /*
 193  * Global data
 194  */
 195 static uint8_t  ql_enable_pm = 1;
 196 static int      ql_flash_sbus_fpga = 0;
 197 uint32_t        ql_os_release_level;
 198 uint32_t        ql_disable_aif = 0;
 199 uint32_t        ql_disable_msi = 0;
 200 uint32_t        ql_disable_msix = 0;
 201 uint32_t        ql_enable_ets = 0;
 202 uint16_t        ql_osc_wait_count = 1000;
 203 
 204 /* Timer routine variables. */
 205 static timeout_id_t     ql_timer_timeout_id = NULL;
 206 static clock_t          ql_timer_ticks;
 207 
 208 /* Soft state head pointer. */
 209 void *ql_state = NULL;
 210 
 211 /* Head adapter link. */
 212 ql_head_t ql_hba = {
 213         NULL,
 214         NULL
 215 };
 216 
 217 /* Global hba index */
 218 uint32_t ql_gfru_hba_index = 1;
 219 
 220 /*
 221  * Some IP defines and globals
 222  */
 223 uint32_t        ql_ip_buffer_count = 128;
 224 uint32_t        ql_ip_low_water = 10;
 225 uint8_t         ql_ip_fast_post_count = 5;
 226 static int      ql_ip_mtu = 65280;              /* equivalent to FCIPMTU */
 227 
 228 /* Device AL_PA to Device Head Queue index array. */
 229 uint8_t ql_alpa_to_index[] = {
 230         0x7e, 0x7d, 0x7c, 0x00, 0x7b, 0x01, 0x02, 0x03, 0x7a, 0x04,
 231         0x05, 0x06, 0x07, 0x08, 0x09, 0x79, 0x78, 0x0a, 0x0b, 0x0c,
 232         0x0d, 0x0e, 0x0f, 0x77, 0x76, 0x10, 0x11, 0x75, 0x12, 0x74,
 233         0x73, 0x72, 0x13, 0x14, 0x15, 0x71, 0x16, 0x70, 0x6f, 0x6e,
 234         0x17, 0x6d, 0x6c, 0x6b, 0x6a, 0x69, 0x68, 0x18, 0x19, 0x67,
 235         0x66, 0x65, 0x64, 0x63, 0x62, 0x20, 0x21, 0x61, 0x60, 0x23,
 236         0x5f, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x5e, 0x2a, 0x5d,
 237         0x5c, 0x5b, 0x2b, 0x5a, 0x59, 0x58, 0x57, 0x56, 0x55, 0x2c,
 238         0x2d, 0x54, 0x53, 0x52, 0x51, 0x50, 0x4f, 0x2e, 0x2f, 0x4e,
 239         0x4d, 0x30, 0x4c, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x4b,
 240         0x37, 0x4a, 0x49, 0x48, 0x38, 0x47, 0x46, 0x45, 0x44, 0x43,
 241         0x42, 0x39, 0x3a, 0x41, 0x40, 0x3f, 0x3e, 0x3d, 0x3c, 0x3b,
 242         0x3c, 0x3b, 0x3a, 0x3d, 0x39, 0x3e, 0x3f, 0x40, 0x38, 0x37,
 243         0x36, 0x41, 0x35, 0x42, 0x43, 0x44, 0x34, 0x45, 0x46, 0x47,
 244         0x48, 0x49, 0x4a, 0x33, 0x32, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f,
 245         0x50, 0x31, 0x30, 0x51, 0x52, 0x2f, 0x53, 0x2e, 0x2d, 0x2c,
 246         0x54, 0x55, 0x56, 0x2b, 0x57, 0x2a, 0x29, 0x28, 0x58, 0x27,
 247         0x26, 0x25, 0x24, 0x23, 0x22, 0x59, 0x5a, 0x21, 0x20, 0x1f,
 248         0x1e, 0x1d, 0x1c, 0x5b, 0x5c, 0x1b, 0x1a, 0x5d, 0x19, 0x5e,
 249         0x5f, 0x60, 0x61, 0x62, 0x63, 0x18, 0x64, 0x17, 0x16, 0x15,
 250         0x65, 0x14, 0x13, 0x12, 0x11, 0x10, 0x0f, 0x66, 0x67, 0x0e,
 251         0x0d, 0x0c, 0x0b, 0x0a, 0x09, 0x68, 0x69, 0x08, 0x07, 0x6a,
 252         0x06, 0x6b, 0x6c, 0x6d, 0x05, 0x04, 0x03, 0x6e, 0x02, 0x6f,
 253         0x70, 0x71, 0x01, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x00,
 254         0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7f, 0x80, 0x00, 0x01,
 255         0x02, 0x03, 0x80, 0x7f, 0x7e, 0x04
 256 };
 257 
 258 /* Device loop_id to ALPA array. */
 259 static uint8_t ql_index_to_alpa[] = {
 260         0xef, 0xe8, 0xe4, 0xe2, 0xe1, 0xe0, 0xdc, 0xda, 0xd9, 0xd6,
 261         0xd5, 0xd4, 0xd3, 0xd2, 0xd1, 0xce, 0xcd, 0xcc, 0xcb, 0xca,
 262         0xc9, 0xc7, 0xc6, 0xc5, 0xc3, 0xbc, 0xba, 0xb9, 0xb6, 0xb5,
 263         0xb4, 0xb3, 0xb2, 0xb1, 0xae, 0xad, 0xac, 0xab, 0xaa, 0xa9,
 264         0xa7, 0xa6, 0xa5, 0xa3, 0x9f, 0x9e, 0x9d, 0x9b, 0x98, 0x97,
 265         0x90, 0x8f, 0x88, 0x84, 0x82, 0x81, 0x80, 0x7c, 0x7a, 0x79,
 266         0x76, 0x75, 0x74, 0x73, 0x72, 0x71, 0x6e, 0x6d, 0x6c, 0x6b,
 267         0x6a, 0x69, 0x67, 0x66, 0x65, 0x63, 0x5c, 0x5a, 0x59, 0x56,
 268         0x55, 0x54, 0x53, 0x52, 0x51, 0x4e, 0x4d, 0x4c, 0x4b, 0x4a,
 269         0x49, 0x47, 0x46, 0x45, 0x43, 0x3c, 0x3a, 0x39, 0x36, 0x35,
 270         0x34, 0x33, 0x32, 0x31, 0x2e, 0x2d, 0x2c, 0x2b, 0x2a, 0x29,
 271         0x27, 0x26, 0x25, 0x23, 0x1f, 0x1e, 0x1d, 0x1b, 0x18, 0x17,
 272         0x10, 0x0f, 0x08, 0x04, 0x02, 0x01
 273 };
 274 
 275 /* 2200 register offsets */
 276 static reg_off_t reg_off_2200 = {
 277         0x00,   /* flash_address */
 278         0x02,   /* flash_data */
 279         0x06,   /* ctrl_status */
 280         0x08,   /* ictrl */
 281         0x0a,   /* istatus */
 282         0x0c,   /* semaphore */
 283         0x0e,   /* nvram */
 284         0x18,   /* req_in */
 285         0x18,   /* req_out */
 286         0x1a,   /* resp_in */
 287         0x1a,   /* resp_out */
 288         0xff,   /* risc2host - n/a */
 289         24,     /* Number of mailboxes */
 290 
 291         /* Mailbox in register offsets 0 - 23 */
 292         0x10, 0x12, 0x14, 0x16, 0x18, 0x1a, 0x1c, 0x1e,
 293         0xe0, 0xe2, 0xe4, 0xe6, 0xe8, 0xea, 0xec, 0xee,
 294         0xf0, 0xf2, 0xf4, 0xf6, 0xf8, 0xfa, 0xfc, 0xfe,
 295         /* 2200 does not have mailbox 24-31 - n/a */
 296         0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
 297 
 298         /* Mailbox out register offsets 0 - 23 */
 299         0x10, 0x12, 0x14, 0x16, 0x18, 0x1a, 0x1c, 0x1e,
 300         0xe0, 0xe2, 0xe4, 0xe6, 0xe8, 0xea, 0xec, 0xee,
 301         0xf0, 0xf2, 0xf4, 0xf6, 0xf8, 0xfa, 0xfc, 0xfe,
 302         /* 2200 does not have mailbox 24-31 - n/a */
 303         0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
 304 
 305         0x96,   /* fpm_diag_config */
 306         0xa4,   /* pcr */
 307         0xb0,   /* mctr */
 308         0xb8,   /* fb_cmd */
 309         0xc0,   /* hccr */
 310         0xcc,   /* gpiod */
 311         0xce,   /* gpioe */
 312         0xff,   /* host_to_host_sema - n/a */
 313         0xff,   /* pri_req_in - n/a */
 314         0xff,   /* pri_req_out - n/a */
 315         0xff,   /* atio_req_in - n/a */
 316         0xff,   /* atio_req_out - n/a */
 317         0xff,   /* io_base_addr - n/a */
 318         0xff,   /* nx_host_int - n/a */
 319         0xff    /* nx_risc_int - n/a */
 320 };
 321 
 322 /* 2300 register offsets */
 323 static reg_off_t reg_off_2300 = {
 324         0x00,   /* flash_address */
 325         0x02,   /* flash_data */
 326         0x06,   /* ctrl_status */
 327         0x08,   /* ictrl */
 328         0x0a,   /* istatus */
 329         0x0c,   /* semaphore */
 330         0x0e,   /* nvram */
 331         0x10,   /* req_in */
 332         0x12,   /* req_out */
 333         0x14,   /* resp_in */
 334         0x16,   /* resp_out */
 335         0x18,   /* risc2host */
 336         32,     /* Number of mailboxes */
 337 
 338         /* Mailbox in register offsets 0 - 31 */
 339         0x40, 0x42, 0x44, 0x46, 0x48, 0x4a, 0x4c, 0x4e,
 340         0x50, 0x52, 0x54, 0x56, 0x58, 0x5a, 0x5c, 0x5e,
 341         0x60, 0x62, 0x64, 0x66, 0x68, 0x6a, 0x6c, 0x6e,
 342         0x70, 0x72, 0x74, 0x76, 0x78, 0x7a, 0x7c, 0x7e,
 343 
 344         /* Mailbox out register offsets 0 - 31 */
 345         0x40, 0x42, 0x44, 0x46, 0x48, 0x4a, 0x4c, 0x4e,
 346         0x50, 0x52, 0x54, 0x56, 0x58, 0x5a, 0x5c, 0x5e,
 347         0x60, 0x62, 0x64, 0x66, 0x68, 0x6a, 0x6c, 0x6e,
 348         0x70, 0x72, 0x74, 0x76, 0x78, 0x7a, 0x7c, 0x7e,
 349 
 350         0x96,   /* fpm_diag_config */
 351         0xa4,   /* pcr */
 352         0xb0,   /* mctr */
 353         0x80,   /* fb_cmd */
 354         0xc0,   /* hccr */
 355         0xcc,   /* gpiod */
 356         0xce,   /* gpioe */
 357         0x1c,   /* host_to_host_sema */
 358         0xff,   /* pri_req_in - n/a */
 359         0xff,   /* pri_req_out - n/a */
 360         0xff,   /* atio_req_in - n/a */
 361         0xff,   /* atio_req_out - n/a */
 362         0xff,   /* io_base_addr - n/a */
 363         0xff,   /* nx_host_int - n/a */
 364         0xff    /* nx_risc_int - n/a */
 365 };
 366 
 367 /* 2400/2500 register offsets */
 368 reg_off_t reg_off_2400_2500 = {
 369         0x00,   /* flash_address */
 370         0x04,   /* flash_data */
 371         0x08,   /* ctrl_status */
 372         0x0c,   /* ictrl */
 373         0x10,   /* istatus */
 374         0xff,   /* semaphore - n/a */
 375         0xff,   /* nvram - n/a */
 376         0x1c,   /* req_in */
 377         0x20,   /* req_out */
 378         0x24,   /* resp_in */
 379         0x28,   /* resp_out */
 380         0x44,   /* risc2host */
 381         32,     /* Number of mailboxes */
 382 
 383         /* Mailbox in register offsets 0 - 31 */
 384         0x80, 0x82, 0x84, 0x86, 0x88, 0x8a, 0x8c, 0x8e,
 385         0x90, 0x92, 0x94, 0x96, 0x98, 0x9a, 0x9c, 0x9e,
 386         0xa0, 0xa2, 0xa4, 0xa6, 0xa8, 0xaa, 0xac, 0xae,
 387         0xb0, 0xb2, 0xb4, 0xb6, 0xb8, 0xba, 0xbc, 0xbe,
 388 
 389         /* Mailbox out register offsets 0 - 31 */
 390         0x80, 0x82, 0x84, 0x86, 0x88, 0x8a, 0x8c, 0x8e,
 391         0x90, 0x92, 0x94, 0x96, 0x98, 0x9a, 0x9c, 0x9e,
 392         0xa0, 0xa2, 0xa4, 0xa6, 0xa8, 0xaa, 0xac, 0xae,
 393         0xb0, 0xb2, 0xb4, 0xb6, 0xb8, 0xba, 0xbc, 0xbe,
 394 
 395         0xff,   /* fpm_diag_config  - n/a */
 396         0xff,   /* pcr - n/a */
 397         0xff,   /* mctr - n/a */
 398         0xff,   /* fb_cmd - n/a */
 399         0x48,   /* hccr */
 400         0x4c,   /* gpiod */
 401         0x50,   /* gpioe */
 402         0xff,   /* host_to_host_sema - n/a */
 403         0x2c,   /* pri_req_in */
 404         0x30,   /* pri_req_out */
 405         0x3c,   /* atio_req_in */
 406         0x40,   /* atio_req_out */
 407         0x54,   /* io_base_addr */
 408         0xff,   /* nx_host_int - n/a */
 409         0xff    /* nx_risc_int - n/a */
 410 };
 411 
 412 /* P3 register offsets */
 413 static reg_off_t reg_off_8021 = {
 414         0x00,   /* flash_address */
 415         0x04,   /* flash_data */
 416         0x08,   /* ctrl_status */
 417         0x0c,   /* ictrl */
 418         0x10,   /* istatus */
 419         0xff,   /* semaphore - n/a */
 420         0xff,   /* nvram - n/a */
 421         0xff,   /* req_in - n/a */
 422         0x0,    /* req_out */
 423         0x100,  /* resp_in */
 424         0x200,  /* resp_out */
 425         0x500,  /* risc2host */
 426         32,     /* Number of mailboxes */
 427 
 428         /* Mailbox in register offsets 0 - 31 */
 429         0x300, 0x302, 0x304, 0x306, 0x308, 0x30a, 0x30c, 0x30e,
 430         0x310, 0x312, 0x314, 0x316, 0x318, 0x31a, 0x31c, 0x31e,
 431         0x320, 0x322, 0x324, 0x326, 0x328, 0x32a, 0x32c, 0x32e,
 432         0x330, 0x332, 0x334, 0x336, 0x338, 0x33a, 0x33c, 0x33e,
 433 
 434         /* Mailbox out register offsets 0 - 31 */
 435         0x400, 0x402, 0x404, 0x406, 0x408, 0x40a, 0x40c, 0x40e,
 436         0x410, 0x412, 0x414, 0x416, 0x418, 0x41a, 0x41c, 0x41e,
 437         0x420, 0x422, 0x424, 0x426, 0x428, 0x42a, 0x42c, 0x42e,
 438         0x430, 0x432, 0x434, 0x436, 0x438, 0x43a, 0x43c, 0x43e,
 439 
 440         0xff,   /* fpm_diag_config  - n/a */
 441         0xff,   /* pcr - n/a */
 442         0xff,   /* mctr - n/a */
 443         0xff,   /* fb_cmd - n/a */
 444         0x48,   /* hccr */
 445         0x4c,   /* gpiod */
 446         0x50,   /* gpioe */
 447         0xff,   /* host_to_host_sema - n/a */
 448         0x2c,   /* pri_req_in */
 449         0x30,   /* pri_req_out */
 450         0x3c,   /* atio_req_in */
 451         0x40,   /* atio_req_out */
 452         0x54,   /* io_base_addr */
 453         0x380,  /* nx_host_int */
 454         0x504   /* nx_risc_int */
 455 };
 456 
 457 /* mutex for protecting variables shared by all instances of the driver */
 458 kmutex_t ql_global_mutex;
 459 kmutex_t ql_global_hw_mutex;
 460 kmutex_t ql_global_el_mutex;
 461 
 462 /* DMA access attribute structure. */
 463 static ddi_device_acc_attr_t ql_dev_acc_attr = {
 464         DDI_DEVICE_ATTR_V0,
 465         DDI_STRUCTURE_LE_ACC,
 466         DDI_STRICTORDER_ACC
 467 };
 468 
 469 /* I/O DMA attributes structures. */
 470 static ddi_dma_attr_t ql_64bit_io_dma_attr = {
 471         DMA_ATTR_V0,                    /* dma_attr_version */
 472         QL_DMA_LOW_ADDRESS,             /* low DMA address range */
 473         QL_DMA_HIGH_64BIT_ADDRESS,      /* high DMA address range */
 474         QL_DMA_XFER_COUNTER,            /* DMA counter register */
 475         QL_DMA_ADDRESS_ALIGNMENT,       /* DMA address alignment */
 476         QL_DMA_BURSTSIZES,              /* DMA burstsizes */
 477         QL_DMA_MIN_XFER_SIZE,           /* min effective DMA size */
 478         QL_DMA_MAX_XFER_SIZE,           /* max DMA xfer size */
 479         QL_DMA_SEGMENT_BOUNDARY,        /* segment boundary */
 480         QL_DMA_SG_LIST_LENGTH,          /* s/g list length */
 481         QL_DMA_GRANULARITY,             /* granularity of device */
 482         QL_DMA_XFER_FLAGS               /* DMA transfer flags */
 483 };
 484 
 485 static ddi_dma_attr_t ql_32bit_io_dma_attr = {
 486         DMA_ATTR_V0,                    /* dma_attr_version */
 487         QL_DMA_LOW_ADDRESS,             /* low DMA address range */
 488         QL_DMA_HIGH_32BIT_ADDRESS,      /* high DMA address range */
 489         QL_DMA_XFER_COUNTER,            /* DMA counter register */
 490         QL_DMA_ADDRESS_ALIGNMENT,       /* DMA address alignment */
 491         QL_DMA_BURSTSIZES,              /* DMA burstsizes */
 492         QL_DMA_MIN_XFER_SIZE,           /* min effective DMA size */
 493         QL_DMA_MAX_XFER_SIZE,           /* max DMA xfer size */
 494         QL_DMA_SEGMENT_BOUNDARY,        /* segment boundary */
 495         QL_DMA_SG_LIST_LENGTH,          /* s/g list length */
 496         QL_DMA_GRANULARITY,             /* granularity of device */
 497         QL_DMA_XFER_FLAGS               /* DMA transfer flags */
 498 };
 499 
 500 /* Load the default dma attributes */
 501 static  ddi_dma_attr_t  ql_32fcsm_cmd_dma_attr;
 502 static  ddi_dma_attr_t  ql_64fcsm_cmd_dma_attr;
 503 static  ddi_dma_attr_t  ql_32fcsm_rsp_dma_attr;
 504 static  ddi_dma_attr_t  ql_64fcsm_rsp_dma_attr;
 505 static  ddi_dma_attr_t  ql_32fcip_cmd_dma_attr;
 506 static  ddi_dma_attr_t  ql_64fcip_cmd_dma_attr;
 507 static  ddi_dma_attr_t  ql_32fcip_rsp_dma_attr;
 508 static  ddi_dma_attr_t  ql_64fcip_rsp_dma_attr;
 509 static  ddi_dma_attr_t  ql_32fcp_cmd_dma_attr;
 510 static  ddi_dma_attr_t  ql_64fcp_cmd_dma_attr;
 511 static  ddi_dma_attr_t  ql_32fcp_rsp_dma_attr;
 512 static  ddi_dma_attr_t  ql_64fcp_rsp_dma_attr;
 513 static  ddi_dma_attr_t  ql_32fcp_data_dma_attr;
 514 static  ddi_dma_attr_t  ql_64fcp_data_dma_attr;
 515 
 516 /* Static declarations of cb_ops entry point functions... */
 517 static struct cb_ops ql_cb_ops = {
 518         ql_open,                        /* b/c open */
 519         ql_close,                       /* b/c close */
 520         nodev,                          /* b strategy */
 521         nodev,                          /* b print */
 522         nodev,                          /* b dump */
 523         nodev,                          /* c read */
 524         nodev,                          /* c write */
 525         ql_ioctl,                       /* c ioctl */
 526         nodev,                          /* c devmap */
 527         nodev,                          /* c mmap */
 528         nodev,                          /* c segmap */
 529         nochpoll,                       /* c poll */
 530         nodev,                          /* cb_prop_op */
 531         NULL,                           /* streamtab  */
 532         D_MP | D_NEW | D_HOTPLUG,       /* Driver compatibility flag */
 533         CB_REV,                         /* cb_ops revision */
 534         nodev,                          /* c aread */
 535         nodev                           /* c awrite */
 536 };
 537 
 538 /* Static declarations of dev_ops entry point functions... */
 539 static struct dev_ops ql_devops = {
 540         DEVO_REV,                       /* devo_rev */
 541         0,                              /* refcnt */
 542         ql_getinfo,                     /* getinfo */
 543         nulldev,                        /* identify */
 544         nulldev,                        /* probe */
 545         ql_attach,                      /* attach */
 546         ql_detach,                      /* detach */
 547         nodev,                          /* reset */
 548         &ql_cb_ops,                 /* char/block ops */
 549         NULL,                           /* bus operations */
 550         ql_power,                       /* power management */
 551         ql_quiesce                      /* quiesce device */
 552 };
 553 
 554 /* ELS command code to text converter */
 555 cmd_table_t els_cmd_tbl[] = ELS_CMD_TABLE();
 556 /* Mailbox command code to text converter */
 557 cmd_table_t mbox_cmd_tbl[] = MBOX_CMD_TABLE();
 558 
 559 char qlc_driver_version[] = QL_VERSION;
 560 
 561 /*
 562  * Loadable Driver Interface Structures.
 563  * Declare and initialize the module configuration section...
 564  */
 565 static struct modldrv modldrv = {
 566         &mod_driverops,                             /* type of module: driver */
 567         "SunFC Qlogic FCA v" QL_VERSION,        /* name of module */
 568         &ql_devops                          /* driver dev_ops */
 569 };
 570 
 571 static struct modlinkage modlinkage = {
 572         MODREV_1,
 573         &modldrv,
 574         NULL
 575 };
 576 
 577 /* ************************************************************************ */
 578 /*                              Loadable Module Routines.                   */
 579 /* ************************************************************************ */
 580 
 581 /*
 582  * _init
 583  *      Initializes a loadable module. It is called before any other
 584  *      routine in a loadable module.
 585  *
 586  * Returns:
 587  *      0 = success
 588  *
 589  * Context:
 590  *      Kernel context.
 591  */
 592 int
 593 _init(void)
 594 {
 595         uint16_t        w16;
 596         int             rval = 0;
 597 
 598         /* Get OS major release level. */
 599         for (w16 = 0; w16 < sizeof (utsname.release); w16++) {
 600                 if (utsname.release[w16] == '.') {
 601                         w16++;
 602                         break;
 603                 }
 604         }
 605         if (w16 < sizeof (utsname.release)) {
 606                 (void) ql_bstr_to_dec(&utsname.release[w16],
 607                     &ql_os_release_level, 0);
 608         } else {
 609                 ql_os_release_level = 0;
 610         }
 611         if (ql_os_release_level < 6) {
 612                 cmn_err(CE_WARN, "%s Unsupported OS release level = %d",
 613                     QL_NAME, ql_os_release_level);
 614                 rval = EINVAL;
 615         }
 616         if (ql_os_release_level == 6) {
 617                 ql_32bit_io_dma_attr.dma_attr_count_max = 0x00ffffff;
 618                 ql_64bit_io_dma_attr.dma_attr_count_max = 0x00ffffff;
 619         }
 620 
 621         if (rval == 0) {
 622                 rval = ddi_soft_state_init(&ql_state,
 623                     sizeof (ql_adapter_state_t), 0);
 624         }
 625         if (rval == 0) {
 626                 /* allow the FC Transport to tweak the dev_ops */
 627                 fc_fca_init(&ql_devops);
 628 
 629                 mutex_init(&ql_global_mutex, NULL, MUTEX_DRIVER, NULL);
 630                 mutex_init(&ql_global_hw_mutex, NULL, MUTEX_DRIVER, NULL);
 631                 mutex_init(&ql_global_el_mutex, NULL, MUTEX_DRIVER, NULL);
 632                 rval = mod_install(&modlinkage);
 633                 if (rval != 0) {
 634                         mutex_destroy(&ql_global_hw_mutex);
 635                         mutex_destroy(&ql_global_mutex);
 636                         mutex_destroy(&ql_global_el_mutex);
 637                         ddi_soft_state_fini(&ql_state);
 638                 } else {
 639                         /*EMPTY*/
 640                         ql_32fcsm_cmd_dma_attr = ql_32bit_io_dma_attr;
 641                         ql_64fcsm_cmd_dma_attr = ql_64bit_io_dma_attr;
 642                         ql_32fcsm_rsp_dma_attr = ql_32bit_io_dma_attr;
 643                         ql_64fcsm_rsp_dma_attr = ql_64bit_io_dma_attr;
 644                         ql_32fcip_cmd_dma_attr = ql_32bit_io_dma_attr;
 645                         ql_64fcip_cmd_dma_attr = ql_64bit_io_dma_attr;
 646                         ql_32fcip_rsp_dma_attr = ql_32bit_io_dma_attr;
 647                         ql_64fcip_rsp_dma_attr = ql_64bit_io_dma_attr;
 648                         ql_32fcp_cmd_dma_attr = ql_32bit_io_dma_attr;
 649                         ql_64fcp_cmd_dma_attr = ql_64bit_io_dma_attr;
 650                         ql_32fcp_rsp_dma_attr = ql_32bit_io_dma_attr;
 651                         ql_64fcp_rsp_dma_attr = ql_64bit_io_dma_attr;
 652                         ql_32fcp_data_dma_attr = ql_32bit_io_dma_attr;
 653                         ql_64fcp_data_dma_attr = ql_64bit_io_dma_attr;
 654                         ql_32fcsm_cmd_dma_attr.dma_attr_sgllen =
 655                             ql_64fcsm_cmd_dma_attr.dma_attr_sgllen =
 656                             QL_FCSM_CMD_SGLLEN;
 657                         ql_32fcsm_rsp_dma_attr.dma_attr_sgllen =
 658                             ql_64fcsm_rsp_dma_attr.dma_attr_sgllen =
 659                             QL_FCSM_RSP_SGLLEN;
 660                         ql_32fcip_cmd_dma_attr.dma_attr_sgllen =
 661                             ql_64fcip_cmd_dma_attr.dma_attr_sgllen =
 662                             QL_FCIP_CMD_SGLLEN;
 663                         ql_32fcip_rsp_dma_attr.dma_attr_sgllen =
 664                             ql_64fcip_rsp_dma_attr.dma_attr_sgllen =
 665                             QL_FCIP_RSP_SGLLEN;
 666                         ql_32fcp_cmd_dma_attr.dma_attr_sgllen =
 667                             ql_64fcp_cmd_dma_attr.dma_attr_sgllen =
 668                             QL_FCP_CMD_SGLLEN;
 669                         ql_32fcp_rsp_dma_attr.dma_attr_sgllen =
 670                             ql_64fcp_rsp_dma_attr.dma_attr_sgllen =
 671                             QL_FCP_RSP_SGLLEN;
 672                 }
 673         }
 674 
 675         if (rval != 0) {
 676                 cmn_err(CE_CONT, "?Unable to install/attach driver '%s'",
 677                     QL_NAME);
 678         }
 679 
 680         return (rval);
 681 }
 682 
 683 /*
 684  * _fini
 685  *      Prepares a module for unloading. It is called when the system
 686  *      wants to unload a module. If the module determines that it can
 687  *      be unloaded, then _fini() returns the value returned by
 688  *      mod_remove(). Upon successful return from _fini() no other
 689  *      routine in the module will be called before _init() is called.
 690  *
 691  * Returns:
 692  *      0 = success
 693  *
 694  * Context:
 695  *      Kernel context.
 696  */
 697 int
 698 _fini(void)
 699 {
 700         int     rval;
 701 
 702         rval = mod_remove(&modlinkage);
 703         if (rval == 0) {
 704                 mutex_destroy(&ql_global_hw_mutex);
 705                 mutex_destroy(&ql_global_mutex);
 706                 mutex_destroy(&ql_global_el_mutex);
 707                 ddi_soft_state_fini(&ql_state);
 708         }
 709 
 710         return (rval);
 711 }
 712 
 713 /*
 714  * _info
 715  *      Returns information about loadable module.
 716  *
 717  * Input:
 718  *      modinfo = pointer to module information structure.
 719  *
 720  * Returns:
 721  *      Value returned by mod_info().
 722  *
 723  * Context:
 724  *      Kernel context.
 725  */
 726 int
 727 _info(struct modinfo *modinfop)
 728 {
 729         return (mod_info(&modlinkage, modinfop));
 730 }
 731 
 732 /* ************************************************************************ */
 733 /*                      dev_ops functions                                   */
 734 /* ************************************************************************ */
 735 
 736 /*
 737  * ql_getinfo
 738  *      Returns the pointer associated with arg when cmd is
 739  *      set to DDI_INFO_DEVT2DEVINFO, or it should return the
 740  *      instance number associated with arg when cmd is set
 741  *      to DDI_INFO_DEV2INSTANCE.
 742  *
 743  * Input:
 744  *      dip = Do not use.
 745  *      cmd = command argument.
 746  *      arg = command specific argument.
 747  *      resultp = pointer to where request information is stored.
 748  *
 749  * Returns:
 750  *      DDI_SUCCESS or DDI_FAILURE.
 751  *
 752  * Context:
 753  *      Kernel context.
 754  */
 755 /* ARGSUSED */
 756 static int
 757 ql_getinfo(dev_info_t *dip, ddi_info_cmd_t cmd, void *arg, void **resultp)
 758 {
 759         ql_adapter_state_t      *ha;
 760         int                     minor;
 761         int                     rval = DDI_FAILURE;
 762 
 763         minor = (int)(getminor((dev_t)arg));
 764         ha = ddi_get_soft_state(ql_state, minor);
 765         if (ha == NULL) {
 766                 QL_PRINT_2(CE_CONT, "failed, unknown minor=%d\n",
 767                     getminor((dev_t)arg));
 768                 *resultp = NULL;
 769                 return (rval);
 770         }
 771 
 772         QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
 773 
 774         switch (cmd) {
 775         case DDI_INFO_DEVT2DEVINFO:
 776                 *resultp = ha->dip;
 777                 rval = DDI_SUCCESS;
 778                 break;
 779         case DDI_INFO_DEVT2INSTANCE:
 780                 *resultp = (void *)(uintptr_t)(ha->instance);
 781                 rval = DDI_SUCCESS;
 782                 break;
 783         default:
 784                 EL(ha, "failed, unsupported cmd=%d\n", cmd);
 785                 rval = DDI_FAILURE;
 786                 break;
 787         }
 788 
 789         QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
 790 
 791         return (rval);
 792 }
 793 
 794 /*
 795  * ql_attach
 796  *      Configure and attach an instance of the driver
 797  *      for a port.
 798  *
 799  * Input:
 800  *      dip = pointer to device information structure.
 801  *      cmd = attach type.
 802  *
 803  * Returns:
 804  *      DDI_SUCCESS or DDI_FAILURE.
 805  *
 806  * Context:
 807  *      Kernel context.
 808  */
 809 static int
 810 ql_attach(dev_info_t *dip, ddi_attach_cmd_t cmd)
 811 {
 812         off_t                   regsize;
 813         uint32_t                size;
 814         int                     rval, *ptr;
 815         int                     instance;
 816         uint_t                  progress = 0;
 817         char                    *buf;
 818         ushort_t                caps_ptr, cap;
 819         fc_fca_tran_t           *tran;
 820         ql_adapter_state_t      *ha = NULL;
 821 
 822         static char *pmcomps[] = {
 823                 NULL,
 824                 PM_LEVEL_D3_STR,                /* Device OFF */
 825                 PM_LEVEL_D0_STR,                /* Device ON */
 826         };
 827 
 828         QL_PRINT_3(CE_CONT, "(%d): started, cmd=%xh\n",
 829             ddi_get_instance(dip), cmd);
 830 
 831         buf = (char *)(kmem_zalloc(MAXPATHLEN, KM_SLEEP));
 832 
 833         switch (cmd) {
 834         case DDI_ATTACH:
 835                 /* first get the instance */
 836                 instance = ddi_get_instance(dip);
 837 
 838                 cmn_err(CE_CONT, "!Qlogic %s(%d) FCA Driver v%s\n",
 839                     QL_NAME, instance, QL_VERSION);
 840 
 841                 /* Correct OS version? */
 842                 if (ql_os_release_level != 11) {
 843                         cmn_err(CE_WARN, "%s(%d): This driver is for Solaris "
 844                             "11", QL_NAME, instance);
 845                         goto attach_failed;
 846                 }
 847 
 848                 /* Hardware is installed in a DMA-capable slot? */
 849                 if (ddi_slaveonly(dip) == DDI_SUCCESS) {
 850                         cmn_err(CE_WARN, "%s(%d): slave only", QL_NAME,
 851                             instance);
 852                         goto attach_failed;
 853                 }
 854 
 855                 /* No support for high-level interrupts */
 856                 if (ddi_intr_hilevel(dip, 0) != 0) {
 857                         cmn_err(CE_WARN, "%s(%d): High level interrupt"
 858                             " not supported", QL_NAME, instance);
 859                         goto attach_failed;
 860                 }
 861 
 862                 /* Allocate our per-device-instance structure */
 863                 if (ddi_soft_state_zalloc(ql_state,
 864                     instance) != DDI_SUCCESS) {
 865                         cmn_err(CE_WARN, "%s(%d): soft state alloc failed",
 866                             QL_NAME, instance);
 867                         goto attach_failed;
 868                 }
 869                 progress |= QL_SOFT_STATE_ALLOCED;
 870 
 871                 ha = ddi_get_soft_state(ql_state, instance);
 872                 if (ha == NULL) {
 873                         cmn_err(CE_WARN, "%s(%d): can't get soft state",
 874                             QL_NAME, instance);
 875                         goto attach_failed;
 876                 }
 877                 ha->dip = dip;
 878                 ha->instance = instance;
 879                 ha->hba.base_address = ha;
 880                 ha->pha = ha;
 881 
 882                 if (ql_el_trace_desc_ctor(ha) != DDI_SUCCESS) {
 883                         cmn_err(CE_WARN, "%s(%d): can't setup el tracing",
 884                             QL_NAME, instance);
 885                         goto attach_failed;
 886                 }
 887 
 888                 /* Get extended logging and dump flags. */
 889                 ql_common_properties(ha);
 890 
 891                 if (strcmp(ddi_driver_name(ddi_get_parent(dip)),
 892                     "sbus") == 0) {
 893                         EL(ha, "%s SBUS card detected", QL_NAME);
 894                         ha->cfg_flags |= CFG_SBUS_CARD;
 895                 }
 896 
 897                 ha->dev = kmem_zalloc(sizeof (*ha->dev) *
 898                     DEVICE_HEAD_LIST_SIZE, KM_SLEEP);
 899 
 900                 ha->outstanding_cmds = kmem_zalloc(
 901                     sizeof (*ha->outstanding_cmds) * MAX_OUTSTANDING_COMMANDS,
 902                     KM_SLEEP);
 903 
 904                 ha->ub_array = kmem_zalloc(sizeof (*ha->ub_array) *
 905                     QL_UB_LIMIT, KM_SLEEP);
 906 
 907                 ha->adapter_stats = kmem_zalloc(sizeof (*ha->adapter_stats),
 908                     KM_SLEEP);
 909 
 910                 (void) ddi_pathname(dip, buf);
 911                 ha->devpath = kmem_zalloc(strlen(buf)+1, KM_SLEEP);
 912                 if (ha->devpath == NULL) {
 913                         EL(ha, "devpath mem alloc failed\n");
 914                 } else {
 915                         (void) strcpy(ha->devpath, buf);
 916                         EL(ha, "devpath is: %s\n", ha->devpath);
 917                 }
 918 
 919                 if (CFG_IST(ha, CFG_SBUS_CARD)) {
 920                         /*
 921                          * For cards where PCI is mapped to sbus e.g. Ivory.
 922                          *
 923                          * 0x00 : 0x000 - 0x0FF PCI Config Space for 2200
 924                          *      : 0x100 - 0x3FF PCI IO space for 2200
 925                          * 0x01 : 0x000 - 0x0FF PCI Config Space for fpga
 926                          *      : 0x100 - 0x3FF PCI IO Space for fpga
 927                          */
 928                         if (ddi_regs_map_setup(dip, 0, (caddr_t *)&ha->iobase,
 929                             0x100, 0x300, &ql_dev_acc_attr, &ha->dev_handle) !=
 930                             DDI_SUCCESS) {
 931                                 cmn_err(CE_WARN, "%s(%d): Unable to map device"
 932                                     " registers", QL_NAME, instance);
 933                                 goto attach_failed;
 934                         }
 935                         if (ddi_regs_map_setup(dip, 1,
 936                             (caddr_t *)&ha->sbus_fpga_iobase, 0, 0x400,
 937                             &ql_dev_acc_attr, &ha->sbus_fpga_dev_handle) !=
 938                             DDI_SUCCESS) {
 939                                 /* We should not fail attach here */
 940                                 cmn_err(CE_WARN, "%s(%d): Unable to map FPGA",
 941                                     QL_NAME, instance);
 942                                 ha->sbus_fpga_iobase = NULL;
 943                         }
 944                         progress |= QL_REGS_MAPPED;
 945 
 946                         /*
 947                          * We should map config space before adding interrupt
 948                          * So that the chip type (2200 or 2300) can be
 949                          * determined before the interrupt routine gets a
 950                          * chance to execute.
 951                          */
 952                         if (ddi_regs_map_setup(dip, 0,
 953                             (caddr_t *)&ha->sbus_config_base, 0, 0x100,
 954                             &ql_dev_acc_attr, &ha->sbus_config_handle) !=
 955                             DDI_SUCCESS) {
 956                                 cmn_err(CE_WARN, "%s(%d): Unable to map sbus "
 957                                     "config registers", QL_NAME, instance);
 958                                 goto attach_failed;
 959                         }
 960                         progress |= QL_CONFIG_SPACE_SETUP;
 961                 } else {
 962                         /*LINTED [Solaris DDI_DEV_T_ANY Lint error]*/
 963                         rval = ddi_prop_lookup_int_array(DDI_DEV_T_ANY, dip,
 964                             DDI_PROP_DONTPASS, "reg", &ptr, &size);
 965                         if (rval != DDI_PROP_SUCCESS) {
 966                                 cmn_err(CE_WARN, "%s(%d): Unable to get PCI "
 967                                     "address registers", QL_NAME, instance);
 968                                 goto attach_failed;
 969                         } else {
 970                                 ha->pci_bus_addr = ptr[0];
 971                                 ha->function_number = (uint8_t)
 972                                     (ha->pci_bus_addr >> 8 & 7);
 973                                 ddi_prop_free(ptr);
 974                         }
 975 
 976                         /*
 977                          * We should map config space before adding interrupt
 978                          * So that the chip type (2200 or 2300) can be
 979                          * determined before the interrupt routine gets a
 980                          * chance to execute.
 981                          */
 982                         if (pci_config_setup(ha->dip, &ha->pci_handle) !=
 983                             DDI_SUCCESS) {
 984                                 cmn_err(CE_WARN, "%s(%d): can't setup PCI "
 985                                     "config space", QL_NAME, instance);
 986                                 goto attach_failed;
 987                         }
 988                         progress |= QL_CONFIG_SPACE_SETUP;
 989 
 990                         /*
 991                          * Setup the ISP2200 registers address mapping to be
 992                          * accessed by this particular driver.
 993                          * 0x0   Configuration Space
 994                          * 0x1   I/O Space
 995                          * 0x2   32-bit Memory Space address
 996                          * 0x3   64-bit Memory Space address
 997                          */
 998                         size = ql_pci_config_get32(ha, PCI_CONF_BASE0) & BIT_0 ?
 999                             2 : 1;
1000                         if (ddi_dev_regsize(dip, size, ®size) !=
1001                             DDI_SUCCESS ||
1002                             ddi_regs_map_setup(dip, size, &ha->iobase,
1003                             0, regsize, &ql_dev_acc_attr, &ha->dev_handle) !=
1004                             DDI_SUCCESS) {
1005                                 cmn_err(CE_WARN, "%s(%d): regs_map_setup(mem) "
1006                                     "failed", QL_NAME, instance);
1007                                 goto attach_failed;
1008                         }
1009                         progress |= QL_REGS_MAPPED;
1010 
1011                         /*
1012                          * We need I/O space mappings for 23xx HBAs for
1013                          * loading flash (FCode). The chip has a bug due to
1014                          * which loading flash fails through mem space
1015                          * mappings in PCI-X mode.
1016                          */
1017                         if (size == 1) {
1018                                 ha->iomap_iobase = ha->iobase;
1019                                 ha->iomap_dev_handle = ha->dev_handle;
1020                         } else {
1021                                 if (ddi_dev_regsize(dip, 1, ®size) !=
1022                                     DDI_SUCCESS ||
1023                                     ddi_regs_map_setup(dip, 1,
1024                                     &ha->iomap_iobase, 0, regsize,
1025                                     &ql_dev_acc_attr, &ha->iomap_dev_handle) !=
1026                                     DDI_SUCCESS) {
1027                                         cmn_err(CE_WARN, "%s(%d): regs_map_"
1028                                             "setup(I/O) failed", QL_NAME,
1029                                             instance);
1030                                         goto attach_failed;
1031                                 }
1032                                 progress |= QL_IOMAP_IOBASE_MAPPED;
1033                         }
1034                 }
1035 
1036                 ha->subsys_id = (uint16_t)ql_pci_config_get16(ha,
1037                     PCI_CONF_SUBSYSID);
1038                 ha->subven_id = (uint16_t)ql_pci_config_get16(ha,
1039                     PCI_CONF_SUBVENID);
1040                 ha->ven_id = (uint16_t)ql_pci_config_get16(ha,
1041                     PCI_CONF_VENID);
1042                 ha->device_id = (uint16_t)ql_pci_config_get16(ha,
1043                     PCI_CONF_DEVID);
1044                 ha->rev_id = (uint8_t)ql_pci_config_get8(ha,
1045                     PCI_CONF_REVID);
1046 
1047                 EL(ha, "ISP%x chip detected (RevID=%x, VenID=%x, SVenID=%x, "
1048                     "SSysID=%x)\n", ha->device_id, ha->rev_id, ha->ven_id,
1049                     ha->subven_id, ha->subsys_id);
1050 
1051                 switch (ha->device_id) {
1052                 case 0x2300:
1053                 case 0x2312:
1054                 case 0x2322:
1055                 case 0x6312:
1056                 case 0x6322:
1057                         if (ql_pci_config_get8(ha, PCI_CONF_IPIN) == 2) {
1058                                 ha->flags |= FUNCTION_1;
1059                         }
1060                         if ((ha->device_id == 0x6322) ||
1061                             (ha->device_id == 0x2322)) {
1062                                 ha->cfg_flags |= CFG_CTRL_6322;
1063                                 ha->fw_class = 0x6322;
1064                                 ha->risc_dump_size = QL_6322_FW_DUMP_SIZE;
1065                         } else {
1066                                 ha->cfg_flags |= CFG_CTRL_2300;
1067                                 ha->fw_class = 0x2300;
1068                                 ha->risc_dump_size = QL_2300_FW_DUMP_SIZE;
1069                         }
1070                         ha->reg_off = ®_off_2300;
1071                         if (ql_fwmodule_resolve(ha) != QL_SUCCESS) {
1072                                 goto attach_failed;
1073                         }
1074                         ha->fcp_cmd = ql_command_iocb;
1075                         ha->ip_cmd = ql_ip_iocb;
1076                         ha->ms_cmd = ql_ms_iocb;
1077                         if (CFG_IST(ha, CFG_SBUS_CARD)) {
1078                                 ha->cmd_segs = CMD_TYPE_2_DATA_SEGMENTS;
1079                                 ha->cmd_cont_segs = CONT_TYPE_0_DATA_SEGMENTS;
1080                         } else {
1081                                 ha->cmd_segs = CMD_TYPE_3_DATA_SEGMENTS;
1082                                 ha->cmd_cont_segs = CONT_TYPE_1_DATA_SEGMENTS;
1083                         }
1084                         break;
1085 
1086                 case 0x2200:
1087                         ha->cfg_flags |= CFG_CTRL_2200;
1088                         ha->reg_off = ®_off_2200;
1089                         ha->fw_class = 0x2200;
1090                         if (ql_fwmodule_resolve(ha) != QL_SUCCESS) {
1091                                 goto attach_failed;
1092                         }
1093                         ha->risc_dump_size = QL_2200_FW_DUMP_SIZE;
1094                         ha->fcp_cmd = ql_command_iocb;
1095                         ha->ip_cmd = ql_ip_iocb;
1096                         ha->ms_cmd = ql_ms_iocb;
1097                         if (CFG_IST(ha, CFG_SBUS_CARD)) {
1098                                 ha->cmd_segs = CMD_TYPE_2_DATA_SEGMENTS;
1099                                 ha->cmd_cont_segs = CONT_TYPE_0_DATA_SEGMENTS;
1100                         } else {
1101                                 ha->cmd_segs = CMD_TYPE_3_DATA_SEGMENTS;
1102                                 ha->cmd_cont_segs = CONT_TYPE_1_DATA_SEGMENTS;
1103                         }
1104                         break;
1105 
1106                 case 0x2422:
1107                 case 0x2432:
1108                 case 0x5422:
1109                 case 0x5432:
1110                 case 0x8432:
1111                         if (ql_pci_config_get8(ha, PCI_CONF_IPIN) == 2) {
1112                                 ha->flags |= FUNCTION_1;
1113                         }
1114                         ha->cfg_flags |= CFG_CTRL_2422;
1115                         if (ha->device_id == 0x8432) {
1116                                 ha->cfg_flags |= CFG_CTRL_MENLO;
1117                         } else {
1118                                 ha->flags |= VP_ENABLED;
1119                         }
1120 
1121                         ha->reg_off = ®_off_2400_2500;
1122                         ha->fw_class = 0x2400;
1123                         if (ql_fwmodule_resolve(ha) != QL_SUCCESS) {
1124                                 goto attach_failed;
1125                         }
1126                         ha->risc_dump_size = QL_24XX_FW_DUMP_SIZE;
1127                         ha->fcp_cmd = ql_command_24xx_iocb;
1128                         ha->ip_cmd = ql_ip_24xx_iocb;
1129                         ha->ms_cmd = ql_ms_24xx_iocb;
1130                         ha->els_cmd = ql_els_24xx_iocb;
1131                         ha->cmd_segs = CMD_TYPE_7_DATA_SEGMENTS;
1132                         ha->cmd_cont_segs = CONT_TYPE_1_DATA_SEGMENTS;
1133                         break;
1134 
1135                 case 0x2522:
1136                 case 0x2532:
1137                         if (ql_pci_config_get8(ha, PCI_CONF_IPIN) == 2) {
1138                                 ha->flags |= FUNCTION_1;
1139                         }
1140                         ha->cfg_flags |= CFG_CTRL_25XX;
1141                         ha->flags |= VP_ENABLED;
1142                         ha->fw_class = 0x2500;
1143                         ha->reg_off = ®_off_2400_2500;
1144                         if (ql_fwmodule_resolve(ha) != QL_SUCCESS) {
1145                                 goto attach_failed;
1146                         }
1147                         ha->risc_dump_size = QL_25XX_FW_DUMP_SIZE;
1148                         ha->fcp_cmd = ql_command_24xx_iocb;
1149                         ha->ip_cmd = ql_ip_24xx_iocb;
1150                         ha->ms_cmd = ql_ms_24xx_iocb;
1151                         ha->els_cmd = ql_els_24xx_iocb;
1152                         ha->cmd_segs = CMD_TYPE_7_DATA_SEGMENTS;
1153                         ha->cmd_cont_segs = CONT_TYPE_1_DATA_SEGMENTS;
1154                         break;
1155 
1156                 case 0x8001:
1157                         if (ql_pci_config_get8(ha, PCI_CONF_IPIN) == 4) {
1158                                 ha->flags |= FUNCTION_1;
1159                         }
1160                         ha->cfg_flags |= CFG_CTRL_81XX;
1161                         ha->flags |= VP_ENABLED;
1162                         ha->fw_class = 0x8100;
1163                         ha->reg_off = ®_off_2400_2500;
1164                         if (ql_fwmodule_resolve(ha) != QL_SUCCESS) {
1165                                 goto attach_failed;
1166                         }
1167                         ha->risc_dump_size = QL_25XX_FW_DUMP_SIZE;
1168                         ha->fcp_cmd = ql_command_24xx_iocb;
1169                         ha->ip_cmd = ql_ip_24xx_iocb;
1170                         ha->ms_cmd = ql_ms_24xx_iocb;
1171                         ha->cmd_segs = CMD_TYPE_7_DATA_SEGMENTS;
1172                         ha->cmd_cont_segs = CONT_TYPE_1_DATA_SEGMENTS;
1173                         break;
1174 
1175                 case 0x8021:
1176                         if (ha->function_number & BIT_0) {
1177                                 ha->flags |= FUNCTION_1;
1178                         }
1179                         ha->cfg_flags |= CFG_CTRL_8021;
1180                         ha->reg_off = ®_off_8021;
1181                         ha->risc_dump_size = QL_25XX_FW_DUMP_SIZE;
1182                         ha->fcp_cmd = ql_command_24xx_iocb;
1183                         ha->ms_cmd = ql_ms_24xx_iocb;
1184                         ha->cmd_segs = CMD_TYPE_7_DATA_SEGMENTS;
1185                         ha->cmd_cont_segs = CONT_TYPE_1_DATA_SEGMENTS;
1186 
1187                         ha->nx_pcibase = ha->iobase;
1188                         ha->iobase += 0xBC000 + (ha->function_number << 11);
1189                         ha->iomap_iobase += 0xBC000 +
1190                             (ha->function_number << 11);
1191 
1192                         /* map doorbell */
1193                         if (ddi_dev_regsize(dip, 2, ®size) != DDI_SUCCESS ||
1194                             ddi_regs_map_setup(dip, 2, &ha->db_iobase,
1195                             0, regsize, &ql_dev_acc_attr, &ha->db_dev_handle) !=
1196                             DDI_SUCCESS) {
1197                                 cmn_err(CE_WARN, "%s(%d): regs_map_setup"
1198                                     "(doorbell) failed", QL_NAME, instance);
1199                                 goto attach_failed;
1200                         }
1201                         progress |= QL_DB_IOBASE_MAPPED;
1202 
1203                         ha->nx_req_in = (uint32_t *)(ha->db_iobase +
1204                             (ha->function_number << 12));
1205                         ha->db_read = ha->nx_pcibase + (512 * 1024) +
1206                             (ha->function_number * 8);
1207 
1208                         ql_8021_update_crb_int_ptr(ha);
1209                         ql_8021_set_drv_active(ha);
1210                         break;
1211 
1212                 default:
1213                         cmn_err(CE_WARN, "%s(%d): Unsupported device id: %x",
1214                             QL_NAME, instance, ha->device_id);
1215                         goto attach_failed;
1216                 }
1217 
1218                 /* Setup hba buffer. */
1219 
1220                 size = CFG_IST(ha, CFG_CTRL_24258081) ?
1221                     (REQUEST_QUEUE_SIZE + RESPONSE_QUEUE_SIZE) :
1222                     (REQUEST_QUEUE_SIZE + RESPONSE_QUEUE_SIZE +
1223                     RCVBUF_QUEUE_SIZE);
1224 
1225                 if (ql_get_dma_mem(ha, &ha->hba_buf, size, LITTLE_ENDIAN_DMA,
1226                     QL_DMA_RING_ALIGN) != QL_SUCCESS) {
1227                         cmn_err(CE_WARN, "%s(%d): request queue DMA memory "
1228                             "alloc failed", QL_NAME, instance);
1229                         goto attach_failed;
1230                 }
1231                 progress |= QL_HBA_BUFFER_SETUP;
1232 
1233                 /* Setup buffer pointers. */
1234                 ha->request_dvma = ha->hba_buf.cookie.dmac_laddress +
1235                     REQUEST_Q_BUFFER_OFFSET;
1236                 ha->request_ring_bp = (struct cmd_entry *)
1237                     ((caddr_t)ha->hba_buf.bp + REQUEST_Q_BUFFER_OFFSET);
1238 
1239                 ha->response_dvma = ha->hba_buf.cookie.dmac_laddress +
1240                     RESPONSE_Q_BUFFER_OFFSET;
1241                 ha->response_ring_bp = (struct sts_entry *)
1242                     ((caddr_t)ha->hba_buf.bp + RESPONSE_Q_BUFFER_OFFSET);
1243 
1244                 ha->rcvbuf_dvma = ha->hba_buf.cookie.dmac_laddress +
1245                     RCVBUF_Q_BUFFER_OFFSET;
1246                 ha->rcvbuf_ring_bp = (struct rcvbuf *)
1247                     ((caddr_t)ha->hba_buf.bp + RCVBUF_Q_BUFFER_OFFSET);
1248 
1249                 /* Allocate resource for QLogic IOCTL */
1250                 (void) ql_alloc_xioctl_resource(ha);
1251 
1252                 /* Setup interrupts */
1253                 if ((rval = ql_setup_interrupts(ha)) != DDI_SUCCESS) {
1254                         cmn_err(CE_WARN, "%s(%d): Failed to add interrupt, "
1255                             "rval=%xh", QL_NAME, instance, rval);
1256                         goto attach_failed;
1257                 }
1258 
1259                 progress |= (QL_INTR_ADDED | QL_MUTEX_CV_INITED);
1260 
1261                 if (ql_nvram_cache_desc_ctor(ha) != DDI_SUCCESS) {
1262                         cmn_err(CE_WARN, "%s(%d): can't setup nvram cache",
1263                             QL_NAME, instance);
1264                         goto attach_failed;
1265                 }
1266 
1267                 /*
1268                  * Allocate an N Port information structure
1269                  * for use when in P2P topology.
1270                  */
1271                 ha->n_port = (ql_n_port_info_t *)
1272                     kmem_zalloc(sizeof (ql_n_port_info_t), KM_SLEEP);
1273                 if (ha->n_port == NULL) {
1274                         cmn_err(CE_WARN, "%s(%d): Failed to create N Port info",
1275                             QL_NAME, instance);
1276                         goto attach_failed;
1277                 }
1278 
1279                 progress |= QL_N_PORT_INFO_CREATED;
1280 
1281                 /*
1282                  * Determine support for Power Management
1283                  */
1284                 caps_ptr = (uint8_t)ql_pci_config_get8(ha, PCI_CONF_CAP_PTR);
1285 
1286                 while (caps_ptr != PCI_CAP_NEXT_PTR_NULL) {
1287                         cap = (uint8_t)ql_pci_config_get8(ha, caps_ptr);
1288                         if (cap == PCI_CAP_ID_PM) {
1289                                 ha->pm_capable = 1;
1290                                 break;
1291                         }
1292                         caps_ptr = (uint8_t)ql_pci_config_get8(ha, caps_ptr +
1293                             PCI_CAP_NEXT_PTR);
1294                 }
1295 
1296                 if (ha->pm_capable) {
1297                         /*
1298                          * Enable PM for 2200 based HBAs only.
1299                          */
1300                         if (ha->device_id != 0x2200) {
1301                                 ha->pm_capable = 0;
1302                         }
1303                 }
1304 
1305                 if (ha->pm_capable) {
1306                         ha->pm_capable = ql_enable_pm;
1307                 }
1308 
1309                 if (ha->pm_capable) {
1310                         /*
1311                          * Initialize power management bookkeeping;
1312                          * components are created idle.
1313                          */
1314                         (void) sprintf(buf, "NAME=%s(%d)", QL_NAME, instance);
1315                         pmcomps[0] = buf;
1316 
1317                         /*LINTED [Solaris DDI_DEV_T_NONE Lint warning]*/
1318                         if (ddi_prop_update_string_array(DDI_DEV_T_NONE,
1319                             dip, "pm-components", pmcomps,
1320                             sizeof (pmcomps) / sizeof (pmcomps[0])) !=
1321                             DDI_PROP_SUCCESS) {
1322                                 cmn_err(CE_WARN, "%s(%d): failed to create"
1323                                     " pm-components property", QL_NAME,
1324                                     instance);
1325 
1326                                 /* Initialize adapter. */
1327                                 ha->power_level = PM_LEVEL_D0;
1328                                 if (ql_initialize_adapter(ha) != QL_SUCCESS) {
1329                                         cmn_err(CE_WARN, "%s(%d): failed to"
1330                                             " initialize adapter", QL_NAME,
1331                                             instance);
1332                                         goto attach_failed;
1333                                 }
1334                         } else {
1335                                 ha->power_level = PM_LEVEL_D3;
1336                                 if (pm_raise_power(dip, QL_POWER_COMPONENT,
1337                                     PM_LEVEL_D0) != DDI_SUCCESS) {
1338                                         cmn_err(CE_WARN, "%s(%d): failed to"
1339                                             " raise power or initialize"
1340                                             " adapter", QL_NAME, instance);
1341                                 }
1342                         }
1343                 } else {
1344                         /* Initialize adapter. */
1345                         ha->power_level = PM_LEVEL_D0;
1346                         if (ql_initialize_adapter(ha) != QL_SUCCESS) {
1347                                 cmn_err(CE_WARN, "%s(%d): failed to initialize"
1348                                     " adapter", QL_NAME, instance);
1349                         }
1350                 }
1351 
1352                 if (ha->fw_major_version == 0 && ha->fw_minor_version == 0 &&
1353                     ha->fw_subminor_version == 0) {
1354                         cmn_err(CE_NOTE, "!%s(%d): Firmware not loaded",
1355                             QL_NAME, ha->instance);
1356                 } else {
1357                         int     rval;
1358                         char    ver_fmt[256];
1359 
1360                         rval = (int)snprintf(ver_fmt, (size_t)sizeof (ver_fmt),
1361                             "Firmware version %d.%d.%d", ha->fw_major_version,
1362                             ha->fw_minor_version, ha->fw_subminor_version);
1363 
1364                         if (CFG_IST(ha, CFG_CTRL_81XX)) {
1365                                 rval = (int)snprintf(ver_fmt + rval,
1366                                     (size_t)sizeof (ver_fmt),
1367                                     ", MPI fw version %d.%d.%d",
1368                                     ha->mpi_fw_major_version,
1369                                     ha->mpi_fw_minor_version,
1370                                     ha->mpi_fw_subminor_version);
1371 
1372                                 if (ha->subsys_id == 0x17B ||
1373                                     ha->subsys_id == 0x17D) {
1374                                         (void) snprintf(ver_fmt + rval,
1375                                             (size_t)sizeof (ver_fmt),
1376                                             ", PHY fw version %d.%d.%d",
1377                                             ha->phy_fw_major_version,
1378                                             ha->phy_fw_minor_version,
1379                                             ha->phy_fw_subminor_version);
1380                                 }
1381                         }
1382                         cmn_err(CE_NOTE, "!%s(%d): %s",
1383                             QL_NAME, ha->instance, ver_fmt);
1384                 }
1385 
1386                 ha->k_stats = kstat_create(QL_NAME, instance, "statistics",
1387                     "controller", KSTAT_TYPE_RAW,
1388                     (uint32_t)sizeof (ql_adapter_stat_t), KSTAT_FLAG_VIRTUAL);
1389                 if (ha->k_stats == NULL) {
1390                         cmn_err(CE_WARN, "%s(%d): Failed to create kstat",
1391                             QL_NAME, instance);
1392                         goto attach_failed;
1393                 }
1394                 progress |= QL_KSTAT_CREATED;
1395 
1396                 ha->adapter_stats->version = 1;
1397                 ha->k_stats->ks_data = (void *)ha->adapter_stats;
1398                 ha->k_stats->ks_private = ha;
1399                 ha->k_stats->ks_update = ql_kstat_update;
1400                 ha->k_stats->ks_ndata = 1;
1401                 ha->k_stats->ks_data_size = sizeof (ql_adapter_stat_t);
1402                 kstat_install(ha->k_stats);
1403 
1404                 if (ddi_create_minor_node(dip, "devctl", S_IFCHR,
1405                     instance, DDI_NT_NEXUS, 0) != DDI_SUCCESS) {
1406                         cmn_err(CE_WARN, "%s(%d): failed to create minor node",
1407                             QL_NAME, instance);
1408                         goto attach_failed;
1409                 }
1410                 progress |= QL_MINOR_NODE_CREATED;
1411 
1412                 /* Allocate a transport structure for this instance */
1413                 tran = kmem_zalloc(sizeof (fc_fca_tran_t), KM_SLEEP);
1414                 if (tran == NULL) {
1415                         cmn_err(CE_WARN, "%s(%d): failed to allocate transport",
1416                             QL_NAME, instance);
1417                         goto attach_failed;
1418                 }
1419 
1420                 progress |= QL_FCA_TRAN_ALLOCED;
1421 
1422                 /* fill in the structure */
1423                 tran->fca_numports = 1;
1424                 tran->fca_version = FCTL_FCA_MODREV_5;
1425                 if (CFG_IST(ha, CFG_CTRL_2422)) {
1426                         tran->fca_num_npivports = MAX_24_VIRTUAL_PORTS;
1427                 } else if (CFG_IST(ha, CFG_CTRL_2581)) {
1428                         tran->fca_num_npivports = MAX_25_VIRTUAL_PORTS;
1429                 }
1430                 bcopy(ha->loginparams.node_ww_name.raw_wwn,
1431                     tran->fca_perm_pwwn.raw_wwn, 8);
1432 
1433                 EL(ha, "FCA version %d\n", tran->fca_version);
1434 
1435                 /* Specify the amount of space needed in each packet */
1436                 tran->fca_pkt_size = sizeof (ql_srb_t);
1437 
1438                 /* command limits are usually dictated by hardware */
1439                 tran->fca_cmd_max = MAX_OUTSTANDING_COMMANDS;
1440 
1441                 /* dmaattr are static, set elsewhere. */
1442                 if (CFG_IST(ha, CFG_ENABLE_64BIT_ADDRESSING)) {
1443                         tran->fca_dma_attr = &ql_64bit_io_dma_attr;
1444                         tran->fca_dma_fcp_cmd_attr = &ql_64fcp_cmd_dma_attr;
1445                         tran->fca_dma_fcp_rsp_attr = &ql_64fcp_rsp_dma_attr;
1446                         tran->fca_dma_fcp_data_attr = &ql_64fcp_data_dma_attr;
1447                         tran->fca_dma_fcsm_cmd_attr = &ql_64fcsm_cmd_dma_attr;
1448                         tran->fca_dma_fcsm_rsp_attr = &ql_64fcsm_rsp_dma_attr;
1449                         tran->fca_dma_fcip_cmd_attr = &ql_64fcip_cmd_dma_attr;
1450                         tran->fca_dma_fcip_rsp_attr = &ql_64fcip_rsp_dma_attr;
1451                 } else {
1452                         tran->fca_dma_attr = &ql_32bit_io_dma_attr;
1453                         tran->fca_dma_fcp_cmd_attr = &ql_32fcp_cmd_dma_attr;
1454                         tran->fca_dma_fcp_rsp_attr = &ql_32fcp_rsp_dma_attr;
1455                         tran->fca_dma_fcp_data_attr = &ql_32fcp_data_dma_attr;
1456                         tran->fca_dma_fcsm_cmd_attr = &ql_32fcsm_cmd_dma_attr;
1457                         tran->fca_dma_fcsm_rsp_attr = &ql_32fcsm_rsp_dma_attr;
1458                         tran->fca_dma_fcip_cmd_attr = &ql_32fcip_cmd_dma_attr;
1459                         tran->fca_dma_fcip_rsp_attr = &ql_32fcip_rsp_dma_attr;
1460                 }
1461 
1462                 tran->fca_acc_attr = &ql_dev_acc_attr;
1463                 tran->fca_iblock = &(ha->iblock_cookie);
1464 
1465                 /* the remaining values are simply function vectors */
1466                 tran->fca_bind_port = ql_bind_port;
1467                 tran->fca_unbind_port = ql_unbind_port;
1468                 tran->fca_init_pkt = ql_init_pkt;
1469                 tran->fca_un_init_pkt = ql_un_init_pkt;
1470                 tran->fca_els_send = ql_els_send;
1471                 tran->fca_get_cap = ql_get_cap;
1472                 tran->fca_set_cap = ql_set_cap;
1473                 tran->fca_getmap = ql_getmap;
1474                 tran->fca_transport = ql_transport;
1475                 tran->fca_ub_alloc = ql_ub_alloc;
1476                 tran->fca_ub_free = ql_ub_free;
1477                 tran->fca_ub_release = ql_ub_release;
1478                 tran->fca_abort = ql_abort;
1479                 tran->fca_reset = ql_reset;
1480                 tran->fca_port_manage = ql_port_manage;
1481                 tran->fca_get_device = ql_get_device;
1482 
1483                 /* give it to the FC transport */
1484                 if (fc_fca_attach(dip, tran) != DDI_SUCCESS) {
1485                         cmn_err(CE_WARN, "%s(%d): FCA attach failed", QL_NAME,
1486                             instance);
1487                         goto attach_failed;
1488                 }
1489                 progress |= QL_FCA_ATTACH_DONE;
1490 
1491                 /* Stash the structure so it can be freed at detach */
1492                 ha->tran = tran;
1493 
1494                 /* Acquire global state lock. */
1495                 GLOBAL_STATE_LOCK();
1496 
1497                 /* Add adapter structure to link list. */
1498                 ql_add_link_b(&ql_hba, &ha->hba);
1499 
1500                 /* Start one second driver timer. */
1501                 if (ql_timer_timeout_id == NULL) {
1502                         ql_timer_ticks = drv_usectohz(1000000);
1503                         ql_timer_timeout_id = timeout(ql_timer, (void *)0,
1504                             ql_timer_ticks);
1505                 }
1506 
1507                 /* Release global state lock. */
1508                 GLOBAL_STATE_UNLOCK();
1509 
1510                 /* Determine and populate HBA fru info */
1511                 ql_setup_fruinfo(ha);
1512 
1513                 /* Setup task_daemon thread. */
1514                 (void) thread_create(NULL, 0, (void (*)())ql_task_daemon, ha,
1515                     0, &p0, TS_RUN, minclsyspri);
1516 
1517                 progress |= QL_TASK_DAEMON_STARTED;
1518 
1519                 ddi_report_dev(dip);
1520 
1521                 /* Disable link reset in panic path */
1522                 ha->lip_on_panic = 1;
1523 
1524                 rval = DDI_SUCCESS;
1525                 break;
1526 
1527 attach_failed:
1528                 if (progress & QL_FCA_ATTACH_DONE) {
1529                         (void) fc_fca_detach(dip);
1530                         progress &= ~QL_FCA_ATTACH_DONE;
1531                 }
1532 
1533                 if (progress & QL_FCA_TRAN_ALLOCED) {
1534                         kmem_free(tran, sizeof (fc_fca_tran_t));
1535                         progress &= ~QL_FCA_TRAN_ALLOCED;
1536                 }
1537 
1538                 if (progress & QL_MINOR_NODE_CREATED) {
1539                         ddi_remove_minor_node(dip, "devctl");
1540                         progress &= ~QL_MINOR_NODE_CREATED;
1541                 }
1542 
1543                 if (progress & QL_KSTAT_CREATED) {
1544                         kstat_delete(ha->k_stats);
1545                         progress &= ~QL_KSTAT_CREATED;
1546                 }
1547 
1548                 if (progress & QL_N_PORT_INFO_CREATED) {
1549                         kmem_free(ha->n_port, sizeof (ql_n_port_info_t));
1550                         progress &= ~QL_N_PORT_INFO_CREATED;
1551                 }
1552 
1553                 if (progress & QL_TASK_DAEMON_STARTED) {
1554                         TASK_DAEMON_LOCK(ha);
1555 
1556                         ha->task_daemon_flags |= TASK_DAEMON_STOP_FLG;
1557 
1558                         cv_signal(&ha->cv_task_daemon);
1559 
1560                         /* Release task daemon lock. */
1561                         TASK_DAEMON_UNLOCK(ha);
1562 
1563                         /* Wait for for task daemon to stop running. */
1564                         while (ha->task_daemon_flags & TASK_DAEMON_STOP_FLG) {
1565                                 ql_delay(ha, 10000);
1566                         }
1567                         progress &= ~QL_TASK_DAEMON_STARTED;
1568                 }
1569 
1570                 if (progress & QL_DB_IOBASE_MAPPED) {
1571                         ql_8021_clr_drv_active(ha);
1572                         ddi_regs_map_free(&ha->db_dev_handle);
1573                         progress &= ~QL_DB_IOBASE_MAPPED;
1574                 }
1575                 if (progress & QL_IOMAP_IOBASE_MAPPED) {
1576                         ddi_regs_map_free(&ha->iomap_dev_handle);
1577                         progress &= ~QL_IOMAP_IOBASE_MAPPED;
1578                 }
1579 
1580                 if (progress & QL_CONFIG_SPACE_SETUP) {
1581                         if (CFG_IST(ha, CFG_SBUS_CARD)) {
1582                                 ddi_regs_map_free(&ha->sbus_config_handle);
1583                         } else {
1584                                 pci_config_teardown(&ha->pci_handle);
1585                         }
1586                         progress &= ~QL_CONFIG_SPACE_SETUP;
1587                 }
1588 
1589                 if (progress & QL_INTR_ADDED) {
1590                         ql_disable_intr(ha);
1591                         ql_release_intr(ha);
1592                         progress &= ~QL_INTR_ADDED;
1593                 }
1594 
1595                 if (progress & QL_MUTEX_CV_INITED) {
1596                         ql_destroy_mutex(ha);
1597                         progress &= ~QL_MUTEX_CV_INITED;
1598                 }
1599 
1600                 if (progress & QL_HBA_BUFFER_SETUP) {
1601                         ql_free_phys(ha, &ha->hba_buf);
1602                         progress &= ~QL_HBA_BUFFER_SETUP;
1603                 }
1604 
1605                 if (progress & QL_REGS_MAPPED) {
1606                         ddi_regs_map_free(&ha->dev_handle);
1607                         if (ha->sbus_fpga_iobase != NULL) {
1608                                 ddi_regs_map_free(&ha->sbus_fpga_dev_handle);
1609                         }
1610                         progress &= ~QL_REGS_MAPPED;
1611                 }
1612 
1613                 if (progress & QL_SOFT_STATE_ALLOCED) {
1614 
1615                         ql_fcache_rel(ha->fcache);
1616 
1617                         kmem_free(ha->adapter_stats,
1618                             sizeof (*ha->adapter_stats));
1619 
1620                         kmem_free(ha->ub_array, sizeof (*ha->ub_array) *
1621                             QL_UB_LIMIT);
1622 
1623                         kmem_free(ha->outstanding_cmds,
1624                             sizeof (*ha->outstanding_cmds) *
1625                             MAX_OUTSTANDING_COMMANDS);
1626 
1627                         if (ha->devpath != NULL) {
1628                                 kmem_free(ha->devpath,
1629                                     strlen(ha->devpath) + 1);
1630                         }
1631 
1632                         kmem_free(ha->dev, sizeof (*ha->dev) *
1633                             DEVICE_HEAD_LIST_SIZE);
1634 
1635                         if (ha->xioctl != NULL) {
1636                                 ql_free_xioctl_resource(ha);
1637                         }
1638 
1639                         if (ha->fw_module != NULL) {
1640                                 (void) ddi_modclose(ha->fw_module);
1641                         }
1642                         (void) ql_el_trace_desc_dtor(ha);
1643                         (void) ql_nvram_cache_desc_dtor(ha);
1644 
1645                         ddi_soft_state_free(ql_state, instance);
1646                         progress &= ~QL_SOFT_STATE_ALLOCED;
1647                 }
1648 
1649                 ddi_prop_remove_all(dip);
1650                 rval = DDI_FAILURE;
1651                 break;
1652 
1653         case DDI_RESUME:
1654                 rval = DDI_FAILURE;
1655 
1656                 ha = ddi_get_soft_state(ql_state, ddi_get_instance(dip));
1657                 if (ha == NULL) {
1658                         cmn_err(CE_WARN, "%s(%d): can't get soft state",
1659                             QL_NAME, instance);
1660                         break;
1661                 }
1662 
1663                 ha->power_level = PM_LEVEL_D3;
1664                 if (ha->pm_capable) {
1665                         /*
1666                          * Get ql_power to do power on initialization
1667                          */
1668                         if (pm_raise_power(dip, QL_POWER_COMPONENT,
1669                             PM_LEVEL_D0) != DDI_SUCCESS) {
1670                                 cmn_err(CE_WARN, "%s(%d): can't raise adapter"
1671                                     " power", QL_NAME, instance);
1672                         }
1673                 }
1674 
1675                 /*
1676                  * There is a bug in DR that prevents PM framework
1677                  * from calling ql_power.
1678                  */
1679                 if (ha->power_level == PM_LEVEL_D3) {
1680                         ha->power_level = PM_LEVEL_D0;
1681 
1682                         if (ql_initialize_adapter(ha) != QL_SUCCESS) {
1683                                 cmn_err(CE_WARN, "%s(%d): can't initialize the"
1684                                     " adapter", QL_NAME, instance);
1685                         }
1686 
1687                         /* Wake up task_daemon. */
1688                         ql_awaken_task_daemon(ha, NULL, TASK_DAEMON_ALIVE_FLG,
1689                             0);
1690                 }
1691 
1692                 /* Acquire global state lock. */
1693                 GLOBAL_STATE_LOCK();
1694 
1695                 /* Restart driver timer. */
1696                 if (ql_timer_timeout_id == NULL) {
1697                         ql_timer_timeout_id = timeout(ql_timer, (void *)0,
1698                             ql_timer_ticks);
1699                 }
1700 
1701                 /* Release global state lock. */
1702                 GLOBAL_STATE_UNLOCK();
1703 
1704                 /* Wake up command start routine. */
1705                 ADAPTER_STATE_LOCK(ha);
1706                 ha->flags &= ~ADAPTER_SUSPENDED;
1707                 ADAPTER_STATE_UNLOCK(ha);
1708 
1709                 /*
1710                  * Transport doesn't make FC discovery in polled
1711                  * mode; So we need the daemon thread's services
1712                  * right here.
1713                  */
1714                 (void) callb_generic_cpr(&ha->cprinfo, CB_CODE_CPR_RESUME);
1715 
1716                 rval = DDI_SUCCESS;
1717 
1718                 /* Restart IP if it was running. */
1719                 if (ha->flags & IP_ENABLED && !(ha->flags & IP_INITIALIZED)) {
1720                         (void) ql_initialize_ip(ha);
1721                         ql_isp_rcvbuf(ha);
1722                 }
1723                 break;
1724 
1725         default:
1726                 cmn_err(CE_WARN, "%s(%d): attach, unknown code:"
1727                     " %x", QL_NAME, ddi_get_instance(dip), cmd);
1728                 rval = DDI_FAILURE;
1729                 break;
1730         }
1731 
1732         kmem_free(buf, MAXPATHLEN);
1733 
1734         if (rval != DDI_SUCCESS) {
1735                 /*EMPTY*/
1736                 QL_PRINT_2(CE_CONT, "(%d): failed, rval = %xh\n",
1737                     ddi_get_instance(dip), rval);
1738         } else {
1739                 /*EMPTY*/
1740                 QL_PRINT_3(CE_CONT, "(%d): done\n", ddi_get_instance(dip));
1741         }
1742 
1743         return (rval);
1744 }
1745 
1746 /*
1747  * ql_detach
1748  *      Used to remove all the states associated with a given
1749  *      instances of a device node prior to the removal of that
1750  *      instance from the system.
1751  *
1752  * Input:
1753  *      dip = pointer to device information structure.
1754  *      cmd = type of detach.
1755  *
1756  * Returns:
1757  *      DDI_SUCCESS or DDI_FAILURE.
1758  *
1759  * Context:
1760  *      Kernel context.
1761  */
1762 static int
1763 ql_detach(dev_info_t *dip, ddi_detach_cmd_t cmd)
1764 {
1765         ql_adapter_state_t      *ha, *vha;
1766         ql_tgt_t                *tq;
1767         int                     delay_cnt;
1768         uint16_t                index;
1769         ql_link_t               *link;
1770         char                    *buf;
1771         timeout_id_t            timer_id = NULL;
1772         int                     suspend, rval = DDI_SUCCESS;
1773 
1774         ha = ddi_get_soft_state(ql_state, ddi_get_instance(dip));
1775         if (ha == NULL) {
1776                 QL_PRINT_2(CE_CONT, "(%d): no adapter\n",
1777                     ddi_get_instance(dip));
1778                 return (DDI_FAILURE);
1779         }
1780 
1781         QL_PRINT_3(CE_CONT, "(%d): started, cmd=%xh\n", ha->instance, cmd);
1782 
1783         buf = (char *)(kmem_zalloc(MAXPATHLEN, KM_SLEEP));
1784 
1785         switch (cmd) {
1786         case DDI_DETACH:
1787                 ADAPTER_STATE_LOCK(ha);
1788                 ha->flags |= (ADAPTER_SUSPENDED | ABORT_CMDS_LOOP_DOWN_TMO);
1789                 ADAPTER_STATE_UNLOCK(ha);
1790 
1791                 TASK_DAEMON_LOCK(ha);
1792 
1793                 if (ha->task_daemon_flags & TASK_DAEMON_ALIVE_FLG) {
1794                         ha->task_daemon_flags |= TASK_DAEMON_STOP_FLG;
1795                         cv_signal(&ha->cv_task_daemon);
1796 
1797                         TASK_DAEMON_UNLOCK(ha);
1798 
1799                         (void) ql_wait_for_td_stop(ha);
1800 
1801                         TASK_DAEMON_LOCK(ha);
1802                         if (ha->task_daemon_flags & TASK_DAEMON_STOP_FLG) {
1803                                 ha->task_daemon_flags &= ~TASK_DAEMON_STOP_FLG;
1804                                 EL(ha, "failed, could not stop task daemon\n");
1805                         }
1806                 }
1807                 TASK_DAEMON_UNLOCK(ha);
1808 
1809                 GLOBAL_STATE_LOCK();
1810 
1811                 /* Disable driver timer if no adapters. */
1812                 if (ql_timer_timeout_id && ql_hba.first == &ha->hba &&
1813                     ql_hba.last == &ha->hba) {
1814                         timer_id = ql_timer_timeout_id;
1815                         ql_timer_timeout_id = NULL;
1816                 }
1817                 ql_remove_link(&ql_hba, &ha->hba);
1818 
1819                 GLOBAL_STATE_UNLOCK();
1820 
1821                 if (timer_id) {
1822                         (void) untimeout(timer_id);
1823                 }
1824 
1825                 if (ha->pm_capable) {
1826                         if (pm_lower_power(dip, QL_POWER_COMPONENT,
1827                             PM_LEVEL_D3) != DDI_SUCCESS) {
1828                                 cmn_err(CE_WARN, "%s(%d): failed to lower the"
1829                                     " power", QL_NAME, ha->instance);
1830                         }
1831                 }
1832 
1833                 /*
1834                  * If pm_lower_power shutdown the adapter, there
1835                  * isn't much else to do
1836                  */
1837                 if (ha->power_level != PM_LEVEL_D3) {
1838                         ql_halt(ha, PM_LEVEL_D3);
1839                 }
1840 
1841                 /* Remove virtual ports. */
1842                 while ((vha = ha->vp_next) != NULL) {
1843                         ql_vport_destroy(vha);
1844                 }
1845 
1846                 /* Free target queues. */
1847                 for (index = 0; index < DEVICE_HEAD_LIST_SIZE; index++) {
1848                         link = ha->dev[index].first;
1849                         while (link != NULL) {
1850                                 tq = link->base_address;
1851                                 link = link->next;
1852                                 ql_dev_free(ha, tq);
1853                         }
1854                 }
1855 
1856                 /*
1857                  * Free unsolicited buffers.
1858                  * If we are here then there are no ULPs still
1859                  * alive that wish to talk to ql so free up
1860                  * any SRB_IP_UB_UNUSED buffers that are
1861                  * lingering around
1862                  */
1863                 QL_UB_LOCK(ha);
1864                 for (index = 0; index < QL_UB_LIMIT; index++) {
1865                         fc_unsol_buf_t *ubp = ha->ub_array[index];
1866 
1867                         if (ubp != NULL) {
1868                                 ql_srb_t *sp = ubp->ub_fca_private;
1869 
1870                                 sp->flags |= SRB_UB_FREE_REQUESTED;
1871 
1872                                 while (!(sp->flags & SRB_UB_IN_FCA) ||
1873                                     (sp->flags & (SRB_UB_CALLBACK |
1874                                     SRB_UB_ACQUIRED))) {
1875                                         QL_UB_UNLOCK(ha);
1876                                         delay(drv_usectohz(100000));
1877                                         QL_UB_LOCK(ha);
1878                                 }
1879                                 ha->ub_array[index] = NULL;
1880 
1881                                 QL_UB_UNLOCK(ha);
1882                                 ql_free_unsolicited_buffer(ha, ubp);
1883                                 QL_UB_LOCK(ha);
1884                         }
1885                 }
1886                 QL_UB_UNLOCK(ha);
1887 
1888                 /* Free any saved RISC code. */
1889                 if (ha->risc_code != NULL) {
1890                         kmem_free(ha->risc_code, ha->risc_code_size);
1891                         ha->risc_code = NULL;
1892                         ha->risc_code_size = 0;
1893                 }
1894 
1895                 if (ha->fw_module != NULL) {
1896                         (void) ddi_modclose(ha->fw_module);
1897                         ha->fw_module = NULL;
1898                 }
1899 
1900                 /* Free resources. */
1901                 ddi_prop_remove_all(dip);
1902                 (void) fc_fca_detach(dip);
1903                 kmem_free(ha->tran, sizeof (fc_fca_tran_t));
1904                 ddi_remove_minor_node(dip, "devctl");
1905                 if (ha->k_stats != NULL) {
1906                         kstat_delete(ha->k_stats);
1907                 }
1908 
1909                 if (CFG_IST(ha, CFG_SBUS_CARD)) {
1910                         ddi_regs_map_free(&ha->sbus_config_handle);
1911                 } else {
1912                         if (CFG_IST(ha, CFG_CTRL_8021)) {
1913                                 ql_8021_clr_drv_active(ha);
1914                                 ddi_regs_map_free(&ha->db_dev_handle);
1915                         }
1916                         if (ha->iomap_dev_handle != ha->dev_handle) {
1917                                 ddi_regs_map_free(&ha->iomap_dev_handle);
1918                         }
1919                         pci_config_teardown(&ha->pci_handle);
1920                 }
1921 
1922                 ql_disable_intr(ha);
1923                 ql_release_intr(ha);
1924 
1925                 ql_free_xioctl_resource(ha);
1926 
1927                 ql_destroy_mutex(ha);
1928 
1929                 ql_free_phys(ha, &ha->hba_buf);
1930                 ql_free_phys(ha, &ha->fwexttracebuf);
1931                 ql_free_phys(ha, &ha->fwfcetracebuf);
1932 
1933                 ddi_regs_map_free(&ha->dev_handle);
1934                 if (ha->sbus_fpga_iobase != NULL) {
1935                         ddi_regs_map_free(&ha->sbus_fpga_dev_handle);
1936                 }
1937 
1938                 ql_fcache_rel(ha->fcache);
1939                 if (ha->vcache != NULL) {
1940                         kmem_free(ha->vcache, QL_24XX_VPD_SIZE);
1941                 }
1942 
1943                 if (ha->pi_attrs != NULL) {
1944                         kmem_free(ha->pi_attrs, sizeof (fca_port_attrs_t));
1945                 }
1946 
1947                 kmem_free(ha->adapter_stats, sizeof (*ha->adapter_stats));
1948 
1949                 kmem_free(ha->ub_array, sizeof (*ha->ub_array) * QL_UB_LIMIT);
1950 
1951                 kmem_free(ha->outstanding_cmds,
1952                     sizeof (*ha->outstanding_cmds) * MAX_OUTSTANDING_COMMANDS);
1953 
1954                 if (ha->n_port != NULL) {
1955                         kmem_free(ha->n_port, sizeof (ql_n_port_info_t));
1956                 }
1957 
1958                 if (ha->devpath != NULL) {
1959                         kmem_free(ha->devpath, strlen(ha->devpath) + 1);
1960                 }
1961 
1962                 kmem_free(ha->dev, sizeof (*ha->dev) * DEVICE_HEAD_LIST_SIZE);
1963 
1964                 EL(ha, "detached\n");
1965 
1966                 ddi_soft_state_free(ql_state, (int)ha->instance);
1967 
1968                 break;
1969 
1970         case DDI_SUSPEND:
1971                 ADAPTER_STATE_LOCK(ha);
1972 
1973                 delay_cnt = 0;
1974                 ha->flags |= ADAPTER_SUSPENDED;
1975                 while (ha->flags & ADAPTER_TIMER_BUSY && delay_cnt++ < 10) {
1976                         ADAPTER_STATE_UNLOCK(ha);
1977                         delay(drv_usectohz(1000000));
1978                         ADAPTER_STATE_LOCK(ha);
1979                 }
1980                 if (ha->busy || ha->flags & ADAPTER_TIMER_BUSY) {
1981                         ha->flags &= ~ADAPTER_SUSPENDED;
1982                         ADAPTER_STATE_UNLOCK(ha);
1983                         rval = DDI_FAILURE;
1984                         cmn_err(CE_WARN, "!%s(%d): Fail suspend"
1985                             " busy %xh flags %xh", QL_NAME, ha->instance,
1986                             ha->busy, ha->flags);
1987                         break;
1988                 }
1989 
1990                 ADAPTER_STATE_UNLOCK(ha);
1991 
1992                 if (ha->flags & IP_INITIALIZED) {
1993                         (void) ql_shutdown_ip(ha);
1994                 }
1995 
1996                 if ((suspend = ql_suspend_adapter(ha)) != QL_SUCCESS) {
1997                         ADAPTER_STATE_LOCK(ha);
1998                         ha->flags &= ~ADAPTER_SUSPENDED;
1999                         ADAPTER_STATE_UNLOCK(ha);
2000                         cmn_err(CE_WARN, "%s(%d): Fail suspend rval %xh",
2001                             QL_NAME, ha->instance, suspend);
2002 
2003                         /* Restart IP if it was running. */
2004                         if (ha->flags & IP_ENABLED &&
2005                             !(ha->flags & IP_INITIALIZED)) {
2006                                 (void) ql_initialize_ip(ha);
2007                                 ql_isp_rcvbuf(ha);
2008                         }
2009                         rval = DDI_FAILURE;
2010                         break;
2011                 }
2012 
2013                 /* Acquire global state lock. */
2014                 GLOBAL_STATE_LOCK();
2015 
2016                 /* Disable driver timer if last adapter. */
2017                 if (ql_timer_timeout_id && ql_hba.first == &ha->hba &&
2018                     ql_hba.last == &ha->hba) {
2019                         timer_id = ql_timer_timeout_id;
2020                         ql_timer_timeout_id = NULL;
2021                 }
2022                 GLOBAL_STATE_UNLOCK();
2023 
2024                 if (timer_id) {
2025                         (void) untimeout(timer_id);
2026                 }
2027 
2028                 EL(ha, "suspended\n");
2029 
2030                 break;
2031 
2032         default:
2033                 rval = DDI_FAILURE;
2034                 break;
2035         }
2036 
2037         kmem_free(buf, MAXPATHLEN);
2038 
2039         if (rval != DDI_SUCCESS) {
2040                 if (ha != NULL) {
2041                         EL(ha, "failed, rval = %xh\n", rval);
2042                 } else {
2043                         /*EMPTY*/
2044                         QL_PRINT_2(CE_CONT, "(%d): failed, rval = %xh\n",
2045                             ddi_get_instance(dip), rval);
2046                 }
2047         } else {
2048                 /*EMPTY*/
2049                 QL_PRINT_3(CE_CONT, "(%d): done\n", ddi_get_instance(dip));
2050         }
2051 
2052         return (rval);
2053 }
2054 
2055 
2056 /*
2057  * ql_power
2058  *      Power a device attached to the system.
2059  *
2060  * Input:
2061  *      dip = pointer to device information structure.
2062  *      component = device.
2063  *      level = power level.
2064  *
2065  * Returns:
2066  *      DDI_SUCCESS or DDI_FAILURE.
2067  *
2068  * Context:
2069  *      Kernel context.
2070  */
2071 /* ARGSUSED */
2072 static int
2073 ql_power(dev_info_t *dip, int component, int level)
2074 {
2075         int                     rval = DDI_FAILURE;
2076         off_t                   csr;
2077         uint8_t                 saved_pm_val;
2078         ql_adapter_state_t      *ha;
2079         char                    *buf;
2080         char                    *path;
2081 
2082         ha = ddi_get_soft_state(ql_state, ddi_get_instance(dip));
2083         if (ha == NULL || ha->pm_capable == 0) {
2084                 QL_PRINT_2(CE_CONT, "(%d): no hba or PM not supported\n",
2085                     ddi_get_instance(dip));
2086                 return (rval);
2087         }
2088 
2089         QL_PRINT_10(CE_CONT, "(%d,%d): started\n", ha->instance, ha->vp_index);
2090 
2091         buf = (char *)(kmem_zalloc(MAXPATHLEN, KM_SLEEP));
2092         path = (char *)(kmem_zalloc(MAXPATHLEN, KM_SLEEP));
2093 
2094         if (component != QL_POWER_COMPONENT || (level != PM_LEVEL_D0 &&
2095             level != PM_LEVEL_D3)) {
2096                 EL(ha, "invalid, component=%xh or level=%xh\n",
2097                     component, level);
2098                 return (rval);
2099         }
2100 
2101         GLOBAL_HW_LOCK();
2102         csr = (uint8_t)ql_pci_config_get8(ha, PCI_CONF_CAP_PTR) + PCI_PMCSR;
2103         GLOBAL_HW_UNLOCK();
2104 
2105         (void) snprintf(buf, sizeof (buf),
2106             "Qlogic %s(%d): %s\n\t", QL_NAME, ddi_get_instance(dip),
2107             ddi_pathname(dip, path));
2108 
2109         switch (level) {
2110         case PM_LEVEL_D0:       /* power up to D0 state - fully on */
2111 
2112                 QL_PM_LOCK(ha);
2113                 if (ha->power_level == PM_LEVEL_D0) {
2114                         QL_PM_UNLOCK(ha);
2115                         rval = DDI_SUCCESS;
2116                         break;
2117                 }
2118 
2119                 /*
2120                  * Enable interrupts now
2121                  */
2122                 saved_pm_val = ha->power_level;
2123                 ha->power_level = PM_LEVEL_D0;
2124                 QL_PM_UNLOCK(ha);
2125 
2126                 GLOBAL_HW_LOCK();
2127 
2128                 ql_pci_config_put16(ha, csr, PCI_PMCSR_D0);
2129 
2130                 /*
2131                  * Delay after reset, for chip to recover.
2132                  * Otherwise causes system PANIC
2133                  */
2134                 drv_usecwait(200000);
2135 
2136                 GLOBAL_HW_UNLOCK();
2137 
2138                 if (ha->config_saved) {
2139                         ha->config_saved = 0;
2140                         if (QL_RESTORE_CONFIG_REGS(dip) != DDI_SUCCESS) {
2141                                 QL_PM_LOCK(ha);
2142                                 ha->power_level = saved_pm_val;
2143                                 QL_PM_UNLOCK(ha);
2144                                 cmn_err(CE_WARN, "%s failed to restore "
2145                                     "config regs", buf);
2146                                 break;
2147                         }
2148                 }
2149 
2150                 if (ql_initialize_adapter(ha) != QL_SUCCESS) {
2151                         cmn_err(CE_WARN, "%s adapter initialization failed",
2152                             buf);
2153                 }
2154 
2155                 /* Wake up task_daemon. */
2156                 ql_awaken_task_daemon(ha, NULL, TASK_DAEMON_ALIVE_FLG |
2157                     TASK_DAEMON_SLEEPING_FLG, 0);
2158 
2159                 /* Restart IP if it was running. */
2160                 if (ha->flags & IP_ENABLED && !(ha->flags & IP_INITIALIZED)) {
2161                         (void) ql_initialize_ip(ha);
2162                         ql_isp_rcvbuf(ha);
2163                 }
2164 
2165                 cmn_err(CE_NOTE, QL_BANG "ql_power(%d): %s is powered ON\n",
2166                     ha->instance, QL_NAME);
2167 
2168                 rval = DDI_SUCCESS;
2169                 break;
2170 
2171         case PM_LEVEL_D3:       /* power down to D3 state - off */
2172 
2173                 QL_PM_LOCK(ha);
2174 
2175                 if (ha->busy || ((ha->task_daemon_flags &
2176                     TASK_DAEMON_SLEEPING_FLG) == 0)) {
2177                         QL_PM_UNLOCK(ha);
2178                         break;
2179                 }
2180 
2181                 if (ha->power_level == PM_LEVEL_D3) {
2182                         rval = DDI_SUCCESS;
2183                         QL_PM_UNLOCK(ha);
2184                         break;
2185                 }
2186                 QL_PM_UNLOCK(ha);
2187 
2188                 if (QL_SAVE_CONFIG_REGS(dip) != DDI_SUCCESS) {
2189                         cmn_err(CE_WARN, "!Qlogic %s(%d): %s failed to save"
2190                             " config regs", QL_NAME, ha->instance, buf);
2191                         break;
2192                 }
2193                 ha->config_saved = 1;
2194 
2195                 /*
2196                  * Don't enable interrupts. Running mailbox commands with
2197                  * interrupts enabled could cause hangs since pm_run_scan()
2198                  * runs out of a callout thread and on single cpu systems
2199                  * cv_reltimedwait_sig(), called from ql_mailbox_command(),
2200                  * would not get to run.
2201                  */
2202                 TASK_DAEMON_LOCK(ha);
2203                 ha->task_daemon_flags |= TASK_DAEMON_POWERING_DOWN;
2204                 TASK_DAEMON_UNLOCK(ha);
2205 
2206                 ql_halt(ha, PM_LEVEL_D3);
2207 
2208                 /*
2209                  * Setup ql_intr to ignore interrupts from here on.
2210                  */
2211                 QL_PM_LOCK(ha);
2212                 ha->power_level = PM_LEVEL_D3;
2213                 QL_PM_UNLOCK(ha);
2214 
2215                 /*
2216                  * Wait for ISR to complete.
2217                  */
2218                 INTR_LOCK(ha);
2219                 ql_pci_config_put16(ha, csr, PCI_PMCSR_D3HOT);
2220                 INTR_UNLOCK(ha);
2221 
2222                 cmn_err(CE_NOTE, QL_BANG "ql_power(%d): %s is powered OFF\n",
2223                     ha->instance, QL_NAME);
2224 
2225                 rval = DDI_SUCCESS;
2226                 break;
2227         }
2228 
2229         kmem_free(buf, MAXPATHLEN);
2230         kmem_free(path, MAXPATHLEN);
2231 
2232         QL_PRINT_10(CE_CONT, "(%d,%d): done\n", ha->instance, ha->vp_index);
2233 
2234         return (rval);
2235 }
2236 
2237 /*
2238  * ql_quiesce
2239  *      quiesce a device attached to the system.
2240  *
2241  * Input:
2242  *      dip = pointer to device information structure.
2243  *
2244  * Returns:
2245  *      DDI_SUCCESS
2246  *
2247  * Context:
2248  *      Kernel context.
2249  */
2250 static int
2251 ql_quiesce(dev_info_t *dip)
2252 {
2253         ql_adapter_state_t      *ha;
2254         uint32_t                timer;
2255         uint32_t                stat;
2256 
2257         ha = ddi_get_soft_state(ql_state, ddi_get_instance(dip));
2258         if (ha == NULL) {
2259                 /* Oh well.... */
2260                 QL_PRINT_2(CE_CONT, "(%d): no adapter\n",
2261                     ddi_get_instance(dip));
2262                 return (DDI_SUCCESS);
2263         }
2264 
2265         QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
2266 
2267         if (CFG_IST(ha, CFG_CTRL_8021)) {
2268                 (void) ql_stop_firmware(ha);
2269         } else if (CFG_IST(ha, CFG_CTRL_242581)) {
2270                 WRT32_IO_REG(ha, hccr, HC24_CLR_RISC_INT);
2271                 WRT16_IO_REG(ha, mailbox_in[0], MBC_STOP_FIRMWARE);
2272                 WRT32_IO_REG(ha, hccr, HC24_SET_HOST_INT);
2273                 for (timer = 0; timer < 30000; timer++) {
2274                         stat = RD32_IO_REG(ha, risc2host);
2275                         if (stat & BIT_15) {
2276                                 if ((stat & 0xff) < 0x12) {
2277                                         WRT32_IO_REG(ha, hccr,
2278                                             HC24_CLR_RISC_INT);
2279                                         break;
2280                                 }
2281                                 WRT32_IO_REG(ha, hccr, HC24_CLR_RISC_INT);
2282                         }
2283                         drv_usecwait(100);
2284                 }
2285                 /* Reset the chip. */
2286                 WRT32_IO_REG(ha, ctrl_status, ISP_RESET | DMA_SHUTDOWN |
2287                     MWB_4096_BYTES);
2288                 drv_usecwait(100);
2289 
2290         } else {
2291                 /* Disable ISP interrupts. */
2292                 WRT16_IO_REG(ha, ictrl, 0);
2293                 /* Select RISC module registers. */
2294                 WRT16_IO_REG(ha, ctrl_status, 0);
2295                 /* Reset ISP semaphore. */
2296                 WRT16_IO_REG(ha, semaphore, 0);
2297                 /* Reset RISC module. */
2298                 WRT16_IO_REG(ha, hccr, HC_RESET_RISC);
2299                 /* Release RISC module. */
2300                 WRT16_IO_REG(ha, hccr, HC_RELEASE_RISC);
2301         }
2302 
2303         ql_disable_intr(ha);
2304 
2305         QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
2306 
2307         return (DDI_SUCCESS);
2308 }
2309 
2310 /* ************************************************************************ */
2311 /*              Fibre Channel Adapter (FCA) Transport Functions.            */
2312 /* ************************************************************************ */
2313 
2314 /*
2315  * ql_bind_port
2316  *      Handling port binding. The FC Transport attempts to bind an FCA port
2317  *      when it is ready to start transactions on the port. The FC Transport
2318  *      will call the fca_bind_port() function specified in the fca_transport
2319  *      structure it receives. The FCA must fill in the port_info structure
2320  *      passed in the call and also stash the information for future calls.
2321  *
2322  * Input:
2323  *      dip = pointer to FCA information structure.
2324  *      port_info = pointer to port information structure.
2325  *      bind_info = pointer to bind information structure.
2326  *
2327  * Returns:
2328  *      NULL = failure
2329  *
2330  * Context:
2331  *      Kernel context.
2332  */
2333 static opaque_t
2334 ql_bind_port(dev_info_t *dip, fc_fca_port_info_t *port_info,
2335     fc_fca_bind_info_t *bind_info)
2336 {
2337         ql_adapter_state_t      *ha, *vha;
2338         opaque_t                fca_handle = NULL;
2339         port_id_t               d_id;
2340         int                     port_npiv = bind_info->port_npiv;
2341         uchar_t                 *port_nwwn = bind_info->port_nwwn.raw_wwn;
2342         uchar_t                 *port_pwwn = bind_info->port_pwwn.raw_wwn;
2343 
2344         /* get state info based on the dip */
2345         ha = ddi_get_soft_state(ql_state, ddi_get_instance(dip));
2346         if (ha == NULL) {
2347                 QL_PRINT_2(CE_CONT, "(%d): no adapter\n",
2348                     ddi_get_instance(dip));
2349                 return (NULL);
2350         }
2351         QL_PRINT_10(CE_CONT, "(%d,%d): started\n", ha->instance, ha->vp_index);
2352 
2353         /* Verify port number is supported. */
2354         if (port_npiv != 0) {
2355                 if (!(ha->flags & VP_ENABLED)) {
2356                         QL_PRINT_2(CE_CONT, "(%d): FC_NPIV_NOT_SUPPORTED\n",
2357                             ha->instance);
2358                         port_info->pi_error = FC_NPIV_NOT_SUPPORTED;
2359                         return (NULL);
2360                 }
2361                 if (!(ha->flags & POINT_TO_POINT)) {
2362                         QL_PRINT_2(CE_CONT, "(%d): FC_NPIV_WRONG_TOPOLOGY\n",
2363                             ha->instance);
2364                         port_info->pi_error = FC_NPIV_WRONG_TOPOLOGY;
2365                         return (NULL);
2366                 }
2367                 if (!(ha->flags & FDISC_ENABLED)) {
2368                         QL_PRINT_2(CE_CONT, "(%d): switch does not support "
2369                             "FDISC\n", ha->instance);
2370                         port_info->pi_error = FC_NPIV_FDISC_FAILED;
2371                         return (NULL);
2372                 }
2373                 if (bind_info->port_num > (CFG_IST(ha, CFG_CTRL_2422) ?
2374                     MAX_24_VIRTUAL_PORTS : MAX_25_VIRTUAL_PORTS)) {
2375                         QL_PRINT_2(CE_CONT, "(%d): port number=%d "
2376                             "FC_OUTOFBOUNDS\n", ha->instance);
2377                         port_info->pi_error = FC_OUTOFBOUNDS;
2378                         return (NULL);
2379                 }
2380         } else if (bind_info->port_num != 0) {
2381                 QL_PRINT_2(CE_CONT, "(%d): failed, port number=%d is not "
2382                     "supported\n", ha->instance, bind_info->port_num);
2383                 port_info->pi_error = FC_OUTOFBOUNDS;
2384                 return (NULL);
2385         }
2386 
2387         /* Locate port context. */
2388         for (vha = ha; vha != NULL; vha = vha->vp_next) {
2389                 if (vha->vp_index == bind_info->port_num) {
2390                         break;
2391                 }
2392         }
2393 
2394         /* If virtual port does not exist. */
2395         if (vha == NULL) {
2396                 vha = ql_vport_create(ha, (uint8_t)bind_info->port_num);
2397         }
2398 
2399         /* make sure this port isn't already bound */
2400         if (vha->flags & FCA_BOUND) {
2401                 port_info->pi_error = FC_ALREADY;
2402         } else {
2403                 if (vha->vp_index != 0) {
2404                         bcopy(port_nwwn,
2405                             vha->loginparams.node_ww_name.raw_wwn, 8);
2406                         bcopy(port_pwwn,
2407                             vha->loginparams.nport_ww_name.raw_wwn, 8);
2408                 }
2409                 if (vha->vp_index != 0 && !(vha->flags & VP_ENABLED)) {
2410                         if (ql_vport_enable(vha) != QL_SUCCESS) {
2411                                 QL_PRINT_2(CE_CONT, "(%d): failed to enable "
2412                                     "virtual port=%d\n", ha->instance,
2413                                     vha->vp_index);
2414                                 port_info->pi_error = FC_NPIV_FDISC_FAILED;
2415                                 return (NULL);
2416                         }
2417                         cmn_err(CE_CONT, "!Qlogic %s(%d) NPIV(%d) "
2418                             "WWPN=%02x%02x%02x%02x%02x%02x%02x%02x : "
2419                             "WWNN=%02x%02x%02x%02x%02x%02x%02x%02x\n",
2420                             QL_NAME, ha->instance, vha->vp_index,
2421                             port_pwwn[0], port_pwwn[1], port_pwwn[2],
2422                             port_pwwn[3], port_pwwn[4], port_pwwn[5],
2423                             port_pwwn[6], port_pwwn[7],
2424                             port_nwwn[0], port_nwwn[1], port_nwwn[2],
2425                             port_nwwn[3], port_nwwn[4], port_nwwn[5],
2426                             port_nwwn[6], port_nwwn[7]);
2427                 }
2428 
2429                 /* stash the bind_info supplied by the FC Transport */
2430                 vha->bind_info.port_handle = bind_info->port_handle;
2431                 vha->bind_info.port_statec_cb =
2432                     bind_info->port_statec_cb;
2433                 vha->bind_info.port_unsol_cb = bind_info->port_unsol_cb;
2434 
2435                 /* Set port's source ID. */
2436                 port_info->pi_s_id.port_id = vha->d_id.b24;
2437 
2438                 /* copy out the default login parameters */
2439                 bcopy((void *)&vha->loginparams,
2440                     (void *)&port_info->pi_login_params,
2441                     sizeof (la_els_logi_t));
2442 
2443                 /* Set port's hard address if enabled. */
2444                 port_info->pi_hard_addr.hard_addr = 0;
2445                 if (bind_info->port_num == 0) {
2446                         d_id.b24 = ha->d_id.b24;
2447                         if (CFG_IST(ha, CFG_CTRL_24258081)) {
2448                                 if (ha->init_ctrl_blk.cb24.
2449                                     firmware_options_1[0] & BIT_0) {
2450                                         d_id.b.al_pa = ql_index_to_alpa[ha->
2451                                             init_ctrl_blk.cb24.
2452                                             hard_address[0]];
2453                                         port_info->pi_hard_addr.hard_addr =
2454                                             d_id.b24;
2455                                 }
2456                         } else if (ha->init_ctrl_blk.cb.firmware_options[0] &
2457                             BIT_0) {
2458                                 d_id.b.al_pa = ql_index_to_alpa[ha->
2459                                     init_ctrl_blk.cb.hard_address[0]];
2460                                 port_info->pi_hard_addr.hard_addr = d_id.b24;
2461                         }
2462 
2463                         /* Set the node id data */
2464                         if (ql_get_rnid_params(ha,
2465                             sizeof (port_info->pi_rnid_params.params),
2466                             (caddr_t)&port_info->pi_rnid_params.params) ==
2467                             QL_SUCCESS) {
2468                                 port_info->pi_rnid_params.status = FC_SUCCESS;
2469                         } else {
2470                                 port_info->pi_rnid_params.status = FC_FAILURE;
2471                         }
2472 
2473                         /* Populate T11 FC-HBA details */
2474                         ql_populate_hba_fru_details(ha, port_info);
2475                         ha->pi_attrs = kmem_zalloc(sizeof (fca_port_attrs_t),
2476                             KM_SLEEP);
2477                         if (ha->pi_attrs != NULL) {
2478                                 bcopy(&port_info->pi_attrs, ha->pi_attrs,
2479                                     sizeof (fca_port_attrs_t));
2480                         }
2481                 } else {
2482                         port_info->pi_rnid_params.status = FC_FAILURE;
2483                         if (ha->pi_attrs != NULL) {
2484                                 bcopy(ha->pi_attrs, &port_info->pi_attrs,
2485                                     sizeof (fca_port_attrs_t));
2486                         }
2487                 }
2488 
2489                 /* Generate handle for this FCA. */
2490                 fca_handle = (opaque_t)vha;
2491 
2492                 ADAPTER_STATE_LOCK(ha);
2493                 vha->flags |= FCA_BOUND;
2494                 ADAPTER_STATE_UNLOCK(ha);
2495                 /* Set port's current state. */
2496                 port_info->pi_port_state = vha->state;
2497         }
2498 
2499         QL_PRINT_10(CE_CONT, "(%d,%d): done, pi_port_state=%xh, "
2500             "pi_s_id.port_id=%xh\n", ha->instance, ha->vp_index,
2501             port_info->pi_port_state, port_info->pi_s_id.port_id);
2502 
2503         return (fca_handle);
2504 }
2505 
2506 /*
2507  * ql_unbind_port
2508  *      To unbind a Fibre Channel Adapter from an FC Port driver.
2509  *
2510  * Input:
2511  *      fca_handle = handle setup by ql_bind_port().
2512  *
2513  * Context:
2514  *      Kernel context.
2515  */
2516 static void
2517 ql_unbind_port(opaque_t fca_handle)
2518 {
2519         ql_adapter_state_t      *ha;
2520         ql_tgt_t                *tq;
2521         uint32_t                flgs;
2522 
2523         ha = ql_fca_handle_to_state(fca_handle);
2524         if (ha == NULL) {
2525                 /*EMPTY*/
2526                 QL_PRINT_2(CE_CONT, "failed, no adapter=%ph\n",
2527                     (void *)fca_handle);
2528         } else {
2529                 QL_PRINT_10(CE_CONT, "(%d,%d): started\n", ha->instance,
2530                     ha->vp_index);
2531 
2532                 if (!(ha->flags & FCA_BOUND)) {
2533                         /*EMPTY*/
2534                         QL_PRINT_2(CE_CONT, "(%d): port=%d already unbound\n",
2535                             ha->instance, ha->vp_index);
2536                 } else {
2537                         if (ha->vp_index != 0 && ha->flags & VP_ENABLED) {
2538                                 if ((tq = ql_loop_id_to_queue(ha,
2539                                     FL_PORT_24XX_HDL)) != NULL) {
2540                                         (void) ql_logout_fabric_port(ha, tq);
2541                                 }
2542                                 (void) ql_vport_control(ha, (uint8_t)
2543                                     (CFG_IST(ha, CFG_CTRL_2425) ?
2544                                     VPC_DISABLE_INIT : VPC_DISABLE_LOGOUT));
2545                                 flgs = FCA_BOUND | VP_ENABLED;
2546                         } else {
2547                                 flgs = FCA_BOUND;
2548                         }
2549                         ADAPTER_STATE_LOCK(ha);
2550                         ha->flags &= ~flgs;
2551                         ADAPTER_STATE_UNLOCK(ha);
2552                 }
2553 
2554                 QL_PRINT_10(CE_CONT, "(%d,%d): done\n", ha->instance,
2555                     ha->vp_index);
2556         }
2557 }
2558 
2559 /*
2560  * ql_init_pkt
2561  *      Initialize FCA portion of packet.
2562  *
2563  * Input:
2564  *      fca_handle = handle setup by ql_bind_port().
2565  *      pkt = pointer to fc_packet.
2566  *
2567  * Returns:
2568  *      FC_SUCCESS - the packet has successfully been initialized.
2569  *      FC_UNBOUND - the fca_handle specified is not bound.
2570  *      FC_NOMEM - the FCA failed initialization due to an allocation error.
2571  *      FC_FAILURE - the FCA failed initialization for undisclosed reasons
2572  *
2573  * Context:
2574  *      Kernel context.
2575  */
2576 /* ARGSUSED */
2577 static int
2578 ql_init_pkt(opaque_t fca_handle, fc_packet_t *pkt, int sleep)
2579 {
2580         ql_adapter_state_t      *ha;
2581         ql_srb_t                *sp;
2582         int                     rval = FC_SUCCESS;
2583 
2584         ha = ql_fca_handle_to_state(fca_handle);
2585         if (ha == NULL) {
2586                 QL_PRINT_2(CE_CONT, "failed, no adapter=%ph\n",
2587                     (void *)fca_handle);
2588                 return (FC_UNBOUND);
2589         }
2590         QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
2591 
2592         sp = (ql_srb_t *)pkt->pkt_fca_private;
2593         sp->flags = 0;
2594 
2595         /* init cmd links */
2596         sp->cmd.base_address = sp;
2597         sp->cmd.prev = NULL;
2598         sp->cmd.next = NULL;
2599         sp->cmd.head = NULL;
2600 
2601         /* init watchdog links */
2602         sp->wdg.base_address = sp;
2603         sp->wdg.prev = NULL;
2604         sp->wdg.next = NULL;
2605         sp->wdg.head = NULL;
2606         sp->pkt = pkt;
2607         sp->ha = ha;
2608         sp->magic_number = QL_FCA_BRAND;
2609         sp->sg_dma.dma_handle = NULL;
2610 #ifndef __sparc
2611         if (CFG_IST(ha, CFG_CTRL_8021)) {
2612                 /* Setup DMA for scatter gather list. */
2613                 sp->sg_dma.size = sizeof (cmd6_2400_dma_t);
2614                 sp->sg_dma.type = LITTLE_ENDIAN_DMA;
2615                 sp->sg_dma.cookie_count = 1;
2616                 sp->sg_dma.alignment = 64;
2617                 if (ql_alloc_phys(ha, &sp->sg_dma, KM_SLEEP) != QL_SUCCESS) {
2618                         rval = FC_NOMEM;
2619                 }
2620         }
2621 #endif  /* __sparc */
2622 
2623         QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
2624 
2625         return (rval);
2626 }
2627 
2628 /*
2629  * ql_un_init_pkt
2630  *      Release all local resources bound to packet.
2631  *
2632  * Input:
2633  *      fca_handle = handle setup by ql_bind_port().
2634  *      pkt = pointer to fc_packet.
2635  *
2636  * Returns:
2637  *      FC_SUCCESS - the packet has successfully been invalidated.
2638  *      FC_UNBOUND - the fca_handle specified is not bound.
2639  *      FC_BADPACKET - the packet has not been initialized or has
2640  *                      already been freed by this FCA.
2641  *
2642  * Context:
2643  *      Kernel context.
2644  */
2645 static int
2646 ql_un_init_pkt(opaque_t fca_handle, fc_packet_t *pkt)
2647 {
2648         ql_adapter_state_t *ha;
2649         int rval;
2650         ql_srb_t *sp;
2651 
2652         ha = ql_fca_handle_to_state(fca_handle);
2653         if (ha == NULL) {
2654                 QL_PRINT_2(CE_CONT, "failed, no adapter=%ph\n",
2655                     (void *)fca_handle);
2656                 return (FC_UNBOUND);
2657         }
2658         QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
2659 
2660         sp = (ql_srb_t *)pkt->pkt_fca_private;
2661 
2662         if (sp->magic_number != QL_FCA_BRAND) {
2663                 EL(ha, "failed, FC_BADPACKET\n");
2664                 rval = FC_BADPACKET;
2665         } else {
2666                 sp->magic_number = NULL;
2667                 ql_free_phys(ha, &sp->sg_dma);
2668                 rval = FC_SUCCESS;
2669         }
2670 
2671         QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
2672 
2673         return (rval);
2674 }
2675 
2676 /*
2677  * ql_els_send
2678  *      Issue a extended link service request.
2679  *
2680  * Input:
2681  *      fca_handle = handle setup by ql_bind_port().
2682  *      pkt = pointer to fc_packet.
2683  *
2684  * Returns:
2685  *      FC_SUCCESS - the command was successful.
2686  *      FC_ELS_FREJECT - the command was rejected by a Fabric.
2687  *      FC_ELS_PREJECT - the command was rejected by an N-port.
2688  *      FC_TRANSPORT_ERROR - a transport error occurred.
2689  *      FC_UNBOUND - the fca_handle specified is not bound.
2690  *      FC_ELS_BAD - the FCA can not issue the requested ELS.
2691  *
2692  * Context:
2693  *      Kernel context.
2694  */
2695 static int
2696 ql_els_send(opaque_t fca_handle, fc_packet_t *pkt)
2697 {
2698         ql_adapter_state_t      *ha;
2699         int                     rval;
2700         clock_t                 timer = drv_usectohz(30000000);
2701         ls_code_t               els;
2702         la_els_rjt_t            rjt;
2703         ql_srb_t                *sp = (ql_srb_t *)pkt->pkt_fca_private;
2704 
2705         /* Verify proper command. */
2706         ha = ql_cmd_setup(fca_handle, pkt, &rval);
2707         if (ha == NULL) {
2708                 QL_PRINT_2(CE_CONT, "failed, ql_cmd_setup=%xh, fcah=%ph\n",
2709                     rval, fca_handle);
2710                 return (FC_INVALID_REQUEST);
2711         }
2712         QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
2713 
2714         /* Wait for suspension to end. */
2715         TASK_DAEMON_LOCK(ha);
2716         while (ha->task_daemon_flags & QL_SUSPENDED) {
2717                 ha->task_daemon_flags |= SUSPENDED_WAKEUP_FLG;
2718 
2719                 /* 30 seconds from now */
2720                 if (cv_reltimedwait(&ha->pha->cv_dr_suspended,
2721                     &ha->pha->task_daemon_mutex, timer, TR_CLOCK_TICK) == -1) {
2722                         /*
2723                          * The timeout time 'timer' was
2724                          * reached without the condition
2725                          * being signaled.
2726                          */
2727                         pkt->pkt_state = FC_PKT_TRAN_BSY;
2728                         pkt->pkt_reason = FC_REASON_XCHG_BSY;
2729 
2730                         /* Release task daemon lock. */
2731                         TASK_DAEMON_UNLOCK(ha);
2732 
2733                         EL(ha, "QL_SUSPENDED failed=%xh\n",
2734                             QL_FUNCTION_TIMEOUT);
2735                         return (FC_TRAN_BUSY);
2736                 }
2737         }
2738         /* Release task daemon lock. */
2739         TASK_DAEMON_UNLOCK(ha);
2740 
2741         /* Setup response header. */
2742         bcopy((void *)&pkt->pkt_cmd_fhdr, (void *)&pkt->pkt_resp_fhdr,
2743             sizeof (fc_frame_hdr_t));
2744 
2745         if (pkt->pkt_rsplen) {
2746                 bzero((void *)pkt->pkt_resp, pkt->pkt_rsplen);
2747         }
2748 
2749         pkt->pkt_resp_fhdr.d_id = ha->d_id.b24;
2750         pkt->pkt_resp_fhdr.s_id = pkt->pkt_cmd_fhdr.d_id;
2751         pkt->pkt_resp_fhdr.r_ctl = R_CTL_EXTENDED_SVC |
2752             R_CTL_SOLICITED_CONTROL;
2753         pkt->pkt_resp_fhdr.f_ctl = F_CTL_XCHG_CONTEXT | F_CTL_LAST_SEQ |
2754             F_CTL_END_SEQ;
2755 
2756         sp->flags &= ~(SRB_UB_CALLBACK | SRB_UB_RSCN | SRB_UB_FCP |
2757             SRB_FCP_CMD_PKT | SRB_FCP_DATA_PKT | SRB_FCP_RSP_PKT |
2758             SRB_IP_PKT | SRB_COMMAND_TIMEOUT | SRB_UB_ACQUIRED | SRB_MS_PKT);
2759 
2760         sp->flags |= SRB_ELS_PKT;
2761 
2762         /* map the type of ELS to a function */
2763         ddi_rep_get8(pkt->pkt_cmd_acc, (uint8_t *)&els,
2764             (uint8_t *)pkt->pkt_cmd, sizeof (els), DDI_DEV_AUTOINCR);
2765 
2766 #if 0
2767         QL_PRINT_3(CE_CONT, "(%d): command fhdr:\n", ha->instance);
2768         QL_DUMP_3((uint8_t *)&pkt->pkt_cmd_fhdr, 32,
2769             sizeof (fc_frame_hdr_t) / 4);
2770         QL_PRINT_3(CE_CONT, "(%d): command:\n", ha->instance);
2771         QL_DUMP_3((uint8_t *)&els, 32, sizeof (els) / 4);
2772 #endif
2773 
2774         sp->iocb = ha->els_cmd;
2775         sp->req_cnt = 1;
2776 
2777         switch (els.ls_code) {
2778         case LA_ELS_RJT:
2779         case LA_ELS_ACC:
2780                 EL(ha, "LA_ELS_RJT\n");
2781                 pkt->pkt_state = FC_PKT_SUCCESS;
2782                 rval = FC_SUCCESS;
2783                 break;
2784         case LA_ELS_PLOGI:
2785         case LA_ELS_PDISC:
2786                 rval = ql_els_plogi(ha, pkt);
2787                 break;
2788         case LA_ELS_FLOGI:
2789         case LA_ELS_FDISC:
2790                 rval = ql_els_flogi(ha, pkt);
2791                 break;
2792         case LA_ELS_LOGO:
2793                 rval = ql_els_logo(ha, pkt);
2794                 break;
2795         case LA_ELS_PRLI:
2796                 rval = ql_els_prli(ha, pkt);
2797                 break;
2798         case LA_ELS_PRLO:
2799                 rval = ql_els_prlo(ha, pkt);
2800                 break;
2801         case LA_ELS_ADISC:
2802                 rval = ql_els_adisc(ha, pkt);
2803                 break;
2804         case LA_ELS_LINIT:
2805                 rval = ql_els_linit(ha, pkt);
2806                 break;
2807         case LA_ELS_LPC:
2808                 rval = ql_els_lpc(ha, pkt);
2809                 break;
2810         case LA_ELS_LSTS:
2811                 rval = ql_els_lsts(ha, pkt);
2812                 break;
2813         case LA_ELS_SCR:
2814                 rval = ql_els_scr(ha, pkt);
2815                 break;
2816         case LA_ELS_RSCN:
2817                 rval = ql_els_rscn(ha, pkt);
2818                 break;
2819         case LA_ELS_FARP_REQ:
2820                 rval = ql_els_farp_req(ha, pkt);
2821                 break;
2822         case LA_ELS_FARP_REPLY:
2823                 rval = ql_els_farp_reply(ha, pkt);
2824                 break;
2825         case LA_ELS_RLS:
2826                 rval = ql_els_rls(ha, pkt);
2827                 break;
2828         case LA_ELS_RNID:
2829                 rval = ql_els_rnid(ha, pkt);
2830                 break;
2831         default:
2832                 EL(ha, "LA_ELS_RJT, FC_REASON_CMD_UNSUPPORTED=%xh\n",
2833                     els.ls_code);
2834                 /* Build RJT. */
2835                 bzero(&rjt, sizeof (rjt));
2836                 rjt.ls_code.ls_code = LA_ELS_RJT;
2837                 rjt.reason = FC_REASON_CMD_UNSUPPORTED;
2838 
2839                 ddi_rep_put8(pkt->pkt_resp_acc, (uint8_t *)&rjt,
2840                     (uint8_t *)pkt->pkt_resp, sizeof (rjt), DDI_DEV_AUTOINCR);
2841 
2842                 pkt->pkt_state = FC_PKT_LOCAL_RJT;
2843                 pkt->pkt_reason = FC_REASON_UNSUPPORTED;
2844                 rval = FC_SUCCESS;
2845                 break;
2846         }
2847 
2848 #if 0
2849         QL_PRINT_3(CE_CONT, "(%d): response fhdr:\n", ha->instance);
2850         QL_DUMP_3((uint8_t *)&pkt->pkt_resp_fhdr, 32,
2851             sizeof (fc_frame_hdr_t) / 4);
2852 #endif
2853         /*
2854          * Return success if the srb was consumed by an iocb. The packet
2855          * completion callback will be invoked by the response handler.
2856          */
2857         if (rval == QL_CONSUMED) {
2858                 rval = FC_SUCCESS;
2859         } else if (rval == FC_SUCCESS &&
2860             !(pkt->pkt_tran_flags & FC_TRAN_NO_INTR) && pkt->pkt_comp) {
2861                 /* Do command callback only if no error */
2862                 ql_awaken_task_daemon(ha, sp, 0, 0);
2863         }
2864 
2865         if (rval != FC_SUCCESS) {
2866                 EL(ha, "failed, rval = %xh\n", rval);
2867         } else {
2868                 /*EMPTY*/
2869                 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
2870         }
2871         return (rval);
2872 }
2873 
2874 /*
2875  * ql_get_cap
2876  *      Export FCA hardware and software capabilities.
2877  *
2878  * Input:
2879  *      fca_handle = handle setup by ql_bind_port().
2880  *      cap = pointer to the capabilities string.
2881  *      ptr = buffer pointer for return capability.
2882  *
2883  * Returns:
2884  *      FC_CAP_ERROR - no such capability
2885  *      FC_CAP_FOUND - the capability was returned and cannot be set
2886  *      FC_CAP_SETTABLE - the capability was returned and can be set
2887  *      FC_UNBOUND - the fca_handle specified is not bound.
2888  *
2889  * Context:
2890  *      Kernel context.
2891  */
2892 static int
2893 ql_get_cap(opaque_t fca_handle, char *cap, void *ptr)
2894 {
2895         ql_adapter_state_t      *ha;
2896         int                     rval;
2897         uint32_t                *rptr = (uint32_t *)ptr;
2898 
2899         ha = ql_fca_handle_to_state(fca_handle);
2900         if (ha == NULL) {
2901                 QL_PRINT_2(CE_CONT, "failed, no adapter=%ph\n",
2902                     (void *)fca_handle);
2903                 return (FC_UNBOUND);
2904         }
2905         QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
2906 
2907         if (strcmp(cap, FC_NODE_WWN) == 0) {
2908                 bcopy((void *)&ha->loginparams.node_ww_name.raw_wwn[0],
2909                     ptr, 8);
2910                 rval = FC_CAP_FOUND;
2911         } else if (strcmp(cap, FC_LOGIN_PARAMS) == 0) {
2912                 bcopy((void *)&ha->loginparams, ptr,
2913                     sizeof (la_els_logi_t));
2914                 rval = FC_CAP_FOUND;
2915         } else if (strcmp(cap, FC_CAP_UNSOL_BUF) == 0) {
2916                 *rptr = (uint32_t)QL_UB_LIMIT;
2917                 rval = FC_CAP_FOUND;
2918         } else if (strcmp(cap, FC_CAP_NOSTREAM_ON_UNALIGN_BUF) == 0) {
2919 
2920                 dev_info_t      *psydip = NULL;
2921 #ifdef __sparc
2922                 /*
2923                  * Disable streaming for certain 2 chip adapters
2924                  * below Psycho to handle Psycho byte hole issue.
2925                  */
2926                 if ((CFG_IST(ha, CFG_MULTI_CHIP_ADAPTER)) &&
2927                     (!CFG_IST(ha, CFG_SBUS_CARD))) {
2928                         for (psydip = ddi_get_parent(ha->dip); psydip;
2929                             psydip = ddi_get_parent(psydip)) {
2930                                 if (strcmp(ddi_driver_name(psydip),
2931                                     "pcipsy") == 0) {
2932                                         break;
2933                                 }
2934                         }
2935                 }
2936 #endif  /* __sparc */
2937 
2938                 if (psydip) {
2939                         *rptr = (uint32_t)FC_NO_STREAMING;
2940                         EL(ha, "No Streaming\n");
2941                 } else {
2942                         *rptr = (uint32_t)FC_ALLOW_STREAMING;
2943                         EL(ha, "Allow Streaming\n");
2944                 }
2945                 rval = FC_CAP_FOUND;
2946         } else if (strcmp(cap, FC_CAP_PAYLOAD_SIZE) == 0) {
2947                 if (CFG_IST(ha, CFG_CTRL_24258081)) {
2948                         *rptr = (uint32_t)CHAR_TO_SHORT(
2949                             ha->init_ctrl_blk.cb24.max_frame_length[0],
2950                             ha->init_ctrl_blk.cb24.max_frame_length[1]);
2951                 } else {
2952                         *rptr = (uint32_t)CHAR_TO_SHORT(
2953                             ha->init_ctrl_blk.cb.max_frame_length[0],
2954                             ha->init_ctrl_blk.cb.max_frame_length[1]);
2955                 }
2956                 rval = FC_CAP_FOUND;
2957         } else if (strcmp(cap, FC_CAP_POST_RESET_BEHAVIOR) == 0) {
2958                 *rptr = FC_RESET_RETURN_ALL;
2959                 rval = FC_CAP_FOUND;
2960         } else if (strcmp(cap, FC_CAP_FCP_DMA) == 0) {
2961                 *rptr = FC_NO_DVMA_SPACE;
2962                 rval = FC_CAP_FOUND;
2963         } else {
2964                 EL(ha, "unknown=%s, FC_CAP_ERROR\n", cap);
2965                 rval = FC_CAP_ERROR;
2966         }
2967 
2968         QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
2969 
2970         return (rval);
2971 }
2972 
2973 /*
2974  * ql_set_cap
2975  *      Allow the FC Transport to set FCA capabilities if possible.
2976  *
2977  * Input:
2978  *      fca_handle = handle setup by ql_bind_port().
2979  *      cap = pointer to the capabilities string.
2980  *      ptr = buffer pointer for capability.
2981  *
2982  * Returns:
2983  *      FC_CAP_ERROR - no such capability
2984  *      FC_CAP_FOUND - the capability cannot be set by the FC Transport.
2985  *      FC_CAP_SETTABLE - the capability was successfully set.
2986  *      FC_UNBOUND - the fca_handle specified is not bound.
2987  *
2988  * Context:
2989  *      Kernel context.
2990  */
2991 /* ARGSUSED */
2992 static int
2993 ql_set_cap(opaque_t fca_handle, char *cap, void *ptr)
2994 {
2995         ql_adapter_state_t      *ha;
2996         int                     rval;
2997 
2998         ha = ql_fca_handle_to_state(fca_handle);
2999         if (ha == NULL) {
3000                 QL_PRINT_2(CE_CONT, "failed, no adapter=%ph\n",
3001                     (void *)fca_handle);
3002                 return (FC_UNBOUND);
3003         }
3004         QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
3005 
3006         if (strcmp(cap, FC_NODE_WWN) == 0) {
3007                 rval = FC_CAP_FOUND;
3008         } else if (strcmp(cap, FC_LOGIN_PARAMS) == 0) {
3009                 rval = FC_CAP_FOUND;
3010         } else if (strcmp(cap, FC_CAP_UNSOL_BUF) == 0) {
3011                 rval = FC_CAP_FOUND;
3012         } else if (strcmp(cap, FC_CAP_PAYLOAD_SIZE) == 0) {
3013                 rval = FC_CAP_FOUND;
3014         } else if (strcmp(cap, FC_CAP_POST_RESET_BEHAVIOR) == 0) {
3015                 rval = FC_CAP_FOUND;
3016         } else {
3017                 EL(ha, "unknown=%s, FC_CAP_ERROR\n", cap);
3018                 rval = FC_CAP_ERROR;
3019         }
3020 
3021         QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
3022 
3023         return (rval);
3024 }
3025 
3026 /*
3027  * ql_getmap
3028  *      Request of Arbitrated Loop (AL-PA) map.
3029  *
3030  * Input:
3031  *      fca_handle = handle setup by ql_bind_port().
3032  *      mapbuf= buffer pointer for map.
3033  *
3034  * Returns:
3035  *      FC_OLDPORT - the specified port is not operating in loop mode.
3036  *      FC_OFFLINE - the specified port is not online.
3037  *      FC_NOMAP - there is no loop map available for this port.
3038  *      FC_UNBOUND - the fca_handle specified is not bound.
3039  *      FC_SUCCESS - a valid map has been placed in mapbuf.
3040  *
3041  * Context:
3042  *      Kernel context.
3043  */
3044 static int
3045 ql_getmap(opaque_t fca_handle, fc_lilpmap_t *mapbuf)
3046 {
3047         ql_adapter_state_t      *ha;
3048         clock_t                 timer = drv_usectohz(30000000);
3049         int                     rval = FC_SUCCESS;
3050 
3051         ha = ql_fca_handle_to_state(fca_handle);
3052         if (ha == NULL) {
3053                 QL_PRINT_2(CE_CONT, "failed, no adapter=%ph\n",
3054                     (void *)fca_handle);
3055                 return (FC_UNBOUND);
3056         }
3057         QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
3058 
3059         mapbuf->lilp_magic = (uint16_t)MAGIC_LIRP;
3060         mapbuf->lilp_myalpa = ha->d_id.b.al_pa;
3061 
3062         /* Wait for suspension to end. */
3063         TASK_DAEMON_LOCK(ha);
3064         while (ha->task_daemon_flags & QL_SUSPENDED) {
3065                 ha->task_daemon_flags |= SUSPENDED_WAKEUP_FLG;
3066 
3067                 /* 30 seconds from now */
3068                 if (cv_reltimedwait(&ha->pha->cv_dr_suspended,
3069                     &ha->pha->task_daemon_mutex, timer, TR_CLOCK_TICK) == -1) {
3070                         /*
3071                          * The timeout time 'timer' was
3072                          * reached without the condition
3073                          * being signaled.
3074                          */
3075 
3076                         /* Release task daemon lock. */
3077                         TASK_DAEMON_UNLOCK(ha);
3078 
3079                         EL(ha, "QL_SUSPENDED failed, FC_TRAN_BUSY\n");
3080                         return (FC_TRAN_BUSY);
3081                 }
3082         }
3083         /* Release task daemon lock. */
3084         TASK_DAEMON_UNLOCK(ha);
3085 
3086         if (ql_get_loop_position_map(ha, LOOP_POSITION_MAP_SIZE,
3087             (caddr_t)&mapbuf->lilp_length) != QL_SUCCESS) {
3088                 /*
3089                  * Now, since transport drivers cosider this as an
3090                  * offline condition, let's wait for few seconds
3091                  * for any loop transitions before we reset the.
3092                  * chip and restart all over again.
3093                  */
3094                 ql_delay(ha, 2000000);
3095                 EL(ha, "failed, FC_NOMAP\n");
3096                 rval = FC_NOMAP;
3097         } else {
3098                 /*EMPTY*/
3099                 QL_PRINT_3(CE_CONT, "(%d): my_alpa %xh len %xh "
3100                     "data %xh %xh %xh %xh\n", ha->instance,
3101                     mapbuf->lilp_myalpa, mapbuf->lilp_length,
3102                     mapbuf->lilp_alpalist[0], mapbuf->lilp_alpalist[1],
3103                     mapbuf->lilp_alpalist[2], mapbuf->lilp_alpalist[3]);
3104         }
3105 
3106         QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
3107 #if 0
3108         QL_DUMP_3((uint8_t *)mapbuf, 8, sizeof (fc_lilpmap_t));
3109 #endif
3110         return (rval);
3111 }
3112 
3113 /*
3114  * ql_transport
3115  *      Issue an I/O request. Handles all regular requests.
3116  *
3117  * Input:
3118  *      fca_handle = handle setup by ql_bind_port().
3119  *      pkt = pointer to fc_packet.
3120  *
3121  * Returns:
3122  *      FC_SUCCESS - the packet was accepted for transport.
3123  *      FC_TRANSPORT_ERROR - a transport error occurred.
3124  *      FC_BADPACKET - the packet to be transported had not been
3125  *                      initialized by this FCA.
3126  *      FC_UNBOUND - the fca_handle specified is not bound.
3127  *
3128  * Context:
3129  *      Kernel context.
3130  */
3131 static int
3132 ql_transport(opaque_t fca_handle, fc_packet_t *pkt)
3133 {
3134         ql_adapter_state_t      *ha;
3135         int                     rval = FC_TRANSPORT_ERROR;
3136         ql_srb_t                *sp = (ql_srb_t *)pkt->pkt_fca_private;
3137 
3138         /* Verify proper command. */
3139         ha = ql_cmd_setup(fca_handle, pkt, &rval);
3140         if (ha == NULL) {
3141                 QL_PRINT_2(CE_CONT, "failed, ql_cmd_setup=%xh, fcah=%ph\n",
3142                     rval, fca_handle);
3143                 return (rval);
3144         }
3145         QL_PRINT_3(CE_CONT, "(%d): started command:\n", ha->instance);
3146 #if 0
3147         QL_DUMP_3((uint8_t *)&pkt->pkt_cmd_fhdr, 32,
3148             sizeof (fc_frame_hdr_t) / 4);
3149         QL_PRINT_3(CE_CONT, "(%d): command:\n", ha->instance);
3150         QL_DUMP_3((uint8_t *)pkt->pkt_cmd, 8, pkt->pkt_cmdlen);
3151 #endif
3152 
3153         /* Reset SRB flags. */
3154         sp->flags &= ~(SRB_ISP_STARTED | SRB_ISP_COMPLETED | SRB_RETRY |
3155             SRB_POLL | SRB_WATCHDOG_ENABLED | SRB_ABORT | SRB_UB_CALLBACK |
3156             SRB_UB_RSCN | SRB_UB_FCP | SRB_FCP_CMD_PKT | SRB_FCP_DATA_PKT |
3157             SRB_FCP_RSP_PKT | SRB_IP_PKT | SRB_GENERIC_SERVICES_PKT |
3158             SRB_COMMAND_TIMEOUT | SRB_ABORTING | SRB_IN_DEVICE_QUEUE |
3159             SRB_IN_TOKEN_ARRAY | SRB_UB_FREE_REQUESTED | SRB_UB_ACQUIRED |
3160             SRB_MS_PKT | SRB_ELS_PKT);
3161 
3162         pkt->pkt_resp_fhdr.d_id = ha->d_id.b24;
3163         pkt->pkt_resp_fhdr.r_ctl = R_CTL_STATUS;
3164         pkt->pkt_resp_fhdr.s_id = pkt->pkt_cmd_fhdr.d_id;
3165         pkt->pkt_resp_fhdr.f_ctl = pkt->pkt_cmd_fhdr.f_ctl;
3166         pkt->pkt_resp_fhdr.type = pkt->pkt_cmd_fhdr.type;
3167 
3168         switch (pkt->pkt_cmd_fhdr.r_ctl) {
3169         case R_CTL_COMMAND:
3170                 if (pkt->pkt_cmd_fhdr.type == FC_TYPE_SCSI_FCP) {
3171                         sp->flags |= SRB_FCP_CMD_PKT;
3172                         rval = ql_fcp_scsi_cmd(ha, pkt, sp);
3173                 }
3174                 break;
3175 
3176         default:
3177                 /* Setup response header and buffer. */
3178                 if (pkt->pkt_rsplen) {
3179                         bzero((void *)pkt->pkt_resp, pkt->pkt_rsplen);
3180                 }
3181 
3182                 switch (pkt->pkt_cmd_fhdr.r_ctl) {
3183                 case R_CTL_UNSOL_DATA:
3184                         if (pkt->pkt_cmd_fhdr.type == FC_TYPE_IS8802_SNAP) {
3185                                 sp->flags |= SRB_IP_PKT;
3186                                 rval = ql_fcp_ip_cmd(ha, pkt, sp);
3187                         }
3188                         break;
3189 
3190                 case R_CTL_UNSOL_CONTROL:
3191                         if (pkt->pkt_cmd_fhdr.type == FC_TYPE_FC_SERVICES) {
3192                                 sp->flags |= SRB_GENERIC_SERVICES_PKT;
3193                                 rval = ql_fc_services(ha, pkt);
3194                         }
3195                         break;
3196 
3197                 case R_CTL_SOLICITED_DATA:
3198                 case R_CTL_STATUS:
3199                 default:
3200                         pkt->pkt_state = FC_PKT_LOCAL_RJT;
3201                         pkt->pkt_reason = FC_REASON_UNSUPPORTED;
3202                         rval = FC_TRANSPORT_ERROR;
3203                         EL(ha, "unknown, r_ctl=%xh\n",
3204                             pkt->pkt_cmd_fhdr.r_ctl);
3205                         break;
3206                 }
3207         }
3208 
3209         if (rval != FC_SUCCESS) {
3210                 EL(ha, "failed, rval = %xh\n", rval);
3211         } else {
3212                 /*EMPTY*/
3213                 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
3214         }
3215 
3216         return (rval);
3217 }
3218 
3219 /*
3220  * ql_ub_alloc
3221  *      Allocate buffers for unsolicited exchanges.
3222  *
3223  * Input:
3224  *      fca_handle = handle setup by ql_bind_port().
3225  *      tokens = token array for each buffer.
3226  *      size = size of each buffer.
3227  *      count = pointer to number of buffers.
3228  *      type = the FC-4 type the buffers are reserved for.
3229  *              1 = Extended Link Services, 5 = LLC/SNAP
3230  *
3231  * Returns:
3232  *      FC_FAILURE - buffers could not be allocated.
3233  *      FC_TOOMANY - the FCA could not allocate the requested
3234  *                      number of buffers.
3235  *      FC_SUCCESS - unsolicited buffers were allocated.
3236  *      FC_UNBOUND - the fca_handle specified is not bound.
3237  *
3238  * Context:
3239  *      Kernel context.
3240  */
3241 static int
3242 ql_ub_alloc(opaque_t fca_handle, uint64_t tokens[], uint32_t size,
3243     uint32_t *count, uint32_t type)
3244 {
3245         ql_adapter_state_t      *ha;
3246         caddr_t                 bufp = NULL;
3247         fc_unsol_buf_t          *ubp;
3248         ql_srb_t                *sp;
3249         uint32_t                index;
3250         uint32_t                cnt;
3251         uint32_t                ub_array_index = 0;
3252         int                     rval = FC_SUCCESS;
3253         int                     ub_updated = FALSE;
3254 
3255         /* Check handle. */
3256         ha = ql_fca_handle_to_state(fca_handle);
3257         if (ha == NULL) {
3258                 QL_PRINT_2(CE_CONT, "failed, no adapter=%ph\n",
3259                     (void *)fca_handle);
3260                 return (FC_UNBOUND);
3261         }
3262         QL_PRINT_3(CE_CONT, "(%d,%d): started, count = %xh\n",
3263             ha->instance, ha->vp_index, *count);
3264 
3265         QL_PM_LOCK(ha);
3266         if (ha->power_level != PM_LEVEL_D0) {
3267                 QL_PM_UNLOCK(ha);
3268                 QL_PRINT_3(CE_CONT, "(%d,%d): down done\n", ha->instance,
3269                     ha->vp_index);
3270                 return (FC_FAILURE);
3271         }
3272         QL_PM_UNLOCK(ha);
3273 
3274         /* Acquire adapter state lock. */
3275         ADAPTER_STATE_LOCK(ha);
3276 
3277         /* Check the count. */
3278         if ((*count + ha->ub_allocated) > QL_UB_LIMIT) {
3279                 *count = 0;
3280                 EL(ha, "failed, FC_TOOMANY\n");
3281                 rval = FC_TOOMANY;
3282         }
3283 
3284         /*
3285          * reset ub_array_index
3286          */
3287         ub_array_index = 0;
3288 
3289         /*
3290          * Now proceed to allocate any buffers required
3291          */
3292         for (index = 0; index < *count && rval == FC_SUCCESS; index++) {
3293                 /* Allocate all memory needed. */
3294                 ubp = (fc_unsol_buf_t *)kmem_zalloc(sizeof (fc_unsol_buf_t),
3295                     KM_SLEEP);
3296                 if (ubp == NULL) {
3297                         EL(ha, "failed, FC_FAILURE\n");
3298                         rval = FC_FAILURE;
3299                 } else {
3300                         sp = kmem_zalloc(sizeof (ql_srb_t), KM_SLEEP);
3301                         if (sp == NULL) {
3302                                 kmem_free(ubp, sizeof (fc_unsol_buf_t));
3303                                 rval = FC_FAILURE;
3304                         } else {
3305                                 if (type == FC_TYPE_IS8802_SNAP) {
3306 #ifdef  __sparc
3307                                         if (ql_get_dma_mem(ha,
3308                                             &sp->ub_buffer, size,
3309                                             BIG_ENDIAN_DMA,
3310                                             QL_DMA_DATA_ALIGN) != QL_SUCCESS) {
3311                                                 rval = FC_FAILURE;
3312                                                 kmem_free(ubp,
3313                                                     sizeof (fc_unsol_buf_t));
3314                                                 kmem_free(sp,
3315                                                     sizeof (ql_srb_t));
3316                                         } else {
3317                                                 bufp = sp->ub_buffer.bp;
3318                                                 sp->ub_size = size;
3319                                         }
3320 #else
3321                                         if (ql_get_dma_mem(ha,
3322                                             &sp->ub_buffer, size,
3323                                             LITTLE_ENDIAN_DMA,
3324                                             QL_DMA_DATA_ALIGN) != QL_SUCCESS) {
3325                                                 rval = FC_FAILURE;
3326                                                 kmem_free(ubp,
3327                                                     sizeof (fc_unsol_buf_t));
3328                                                 kmem_free(sp,
3329                                                     sizeof (ql_srb_t));
3330                                         } else {
3331                                                 bufp = sp->ub_buffer.bp;
3332                                                 sp->ub_size = size;
3333                                         }
3334 #endif
3335                                 } else {
3336                                         bufp = kmem_zalloc(size, KM_SLEEP);
3337                                         if (bufp == NULL) {
3338                                                 rval = FC_FAILURE;
3339                                                 kmem_free(ubp,
3340                                                     sizeof (fc_unsol_buf_t));
3341                                                 kmem_free(sp,
3342                                                     sizeof (ql_srb_t));
3343                                         } else {
3344                                                 sp->ub_size = size;
3345                                         }
3346                                 }
3347                         }
3348                 }
3349 
3350                 if (rval == FC_SUCCESS) {
3351                         /* Find next available slot. */
3352                         QL_UB_LOCK(ha);
3353                         while (ha->ub_array[ub_array_index] != NULL) {
3354                                 ub_array_index++;
3355                         }
3356 
3357                         ubp->ub_fca_private = (void *)sp;
3358 
3359                         /* init cmd links */
3360                         sp->cmd.base_address = sp;
3361                         sp->cmd.prev = NULL;
3362                         sp->cmd.next = NULL;
3363                         sp->cmd.head = NULL;
3364 
3365                         /* init wdg links */
3366                         sp->wdg.base_address = sp;
3367                         sp->wdg.prev = NULL;
3368                         sp->wdg.next = NULL;
3369                         sp->wdg.head = NULL;
3370                         sp->ha = ha;
3371 
3372                         ubp->ub_buffer = bufp;
3373                         ubp->ub_bufsize = size;
3374                         ubp->ub_port_handle = fca_handle;
3375                         ubp->ub_token = ub_array_index;
3376 
3377                         /* Save the token. */
3378                         tokens[index] = ub_array_index;
3379 
3380                         /* Setup FCA private information. */
3381                         sp->ub_type = type;
3382                         sp->handle = ub_array_index;
3383                         sp->flags |= SRB_UB_IN_FCA;
3384 
3385                         ha->ub_array[ub_array_index] = ubp;
3386                         ha->ub_allocated++;
3387                         ub_updated = TRUE;
3388                         QL_UB_UNLOCK(ha);
3389                 }
3390         }
3391 
3392         /* Release adapter state lock. */
3393         ADAPTER_STATE_UNLOCK(ha);
3394 
3395         /* IP buffer. */
3396         if (ub_updated) {
3397                 if ((type == FC_TYPE_IS8802_SNAP) &&
3398                     (!(CFG_IST(ha, (CFG_CTRL_6322 | CFG_CTRL_2581))))) {
3399 
3400                         ADAPTER_STATE_LOCK(ha);
3401                         ha->flags |= IP_ENABLED;
3402                         ADAPTER_STATE_UNLOCK(ha);
3403 
3404                         if (!(ha->flags & IP_INITIALIZED)) {
3405                                 if (CFG_IST(ha, CFG_CTRL_2422)) {
3406                                         ha->ip_init_ctrl_blk.cb24.mtu_size[0] =
3407                                             LSB(ql_ip_mtu);
3408                                         ha->ip_init_ctrl_blk.cb24.mtu_size[1] =
3409                                             MSB(ql_ip_mtu);
3410                                         ha->ip_init_ctrl_blk.cb24.buf_size[0] =
3411                                             LSB(size);
3412                                         ha->ip_init_ctrl_blk.cb24.buf_size[1] =
3413                                             MSB(size);
3414 
3415                                         cnt = CHAR_TO_SHORT(
3416                                             ha->ip_init_ctrl_blk.cb24.cc[0],
3417                                             ha->ip_init_ctrl_blk.cb24.cc[1]);
3418 
3419                                         if (cnt < *count) {
3420                                                 ha->ip_init_ctrl_blk.cb24.cc[0]
3421                                                     = LSB(*count);
3422                                                 ha->ip_init_ctrl_blk.cb24.cc[1]
3423                                                     = MSB(*count);
3424                                         }
3425                                 } else {
3426                                         ha->ip_init_ctrl_blk.cb.mtu_size[0] =
3427                                             LSB(ql_ip_mtu);
3428                                         ha->ip_init_ctrl_blk.cb.mtu_size[1] =
3429                                             MSB(ql_ip_mtu);
3430                                         ha->ip_init_ctrl_blk.cb.buf_size[0] =
3431                                             LSB(size);
3432                                         ha->ip_init_ctrl_blk.cb.buf_size[1] =
3433                                             MSB(size);
3434 
3435                                         cnt = CHAR_TO_SHORT(
3436                                             ha->ip_init_ctrl_blk.cb.cc[0],
3437                                             ha->ip_init_ctrl_blk.cb.cc[1]);
3438 
3439                                         if (cnt < *count) {
3440                                                 ha->ip_init_ctrl_blk.cb.cc[0] =
3441                                                     LSB(*count);
3442                                                 ha->ip_init_ctrl_blk.cb.cc[1] =
3443                                                     MSB(*count);
3444                                         }
3445                                 }
3446 
3447                                 (void) ql_initialize_ip(ha);
3448                         }
3449                         ql_isp_rcvbuf(ha);
3450                 }
3451         }
3452 
3453         if (rval != FC_SUCCESS) {
3454                 EL(ha, "failed=%xh\n", rval);
3455         } else {
3456                 /*EMPTY*/
3457                 QL_PRINT_3(CE_CONT, "(%d,%d): done\n", ha->instance,
3458                     ha->vp_index);
3459         }
3460         return (rval);
3461 }
3462 
3463 /*
3464  * ql_ub_free
3465  *      Free unsolicited buffers.
3466  *
3467  * Input:
3468  *      fca_handle = handle setup by ql_bind_port().
3469  *      count = number of buffers.
3470  *      tokens = token array for each buffer.
3471  *
3472  * Returns:
3473  *      FC_SUCCESS - the requested buffers have been freed.
3474  *      FC_UNBOUND - the fca_handle specified is not bound.
3475  *      FC_UB_BADTOKEN - an invalid token was encountered.
3476  *                       No buffers have been released.
3477  *
3478  * Context:
3479  *      Kernel context.
3480  */
3481 static int
3482 ql_ub_free(opaque_t fca_handle, uint32_t count, uint64_t tokens[])
3483 {
3484         ql_adapter_state_t      *ha;
3485         ql_srb_t                *sp;
3486         uint32_t                index;
3487         uint64_t                ub_array_index;
3488         int                     rval = FC_SUCCESS;
3489 
3490         /* Check handle. */
3491         ha = ql_fca_handle_to_state(fca_handle);
3492         if (ha == NULL) {
3493                 QL_PRINT_2(CE_CONT, "failed, no adapter=%ph\n",
3494                     (void *)fca_handle);
3495                 return (FC_UNBOUND);
3496         }
3497         QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
3498 
3499         /* Acquire adapter state lock. */
3500         ADAPTER_STATE_LOCK(ha);
3501 
3502         /* Check all returned tokens. */
3503         for (index = 0; index < count; index++) {
3504                 fc_unsol_buf_t  *ubp;
3505 
3506                 /* Check the token range. */
3507                 if ((ub_array_index = tokens[index]) >= QL_UB_LIMIT) {
3508                         EL(ha, "failed, FC_UB_BADTOKEN\n");
3509                         rval = FC_UB_BADTOKEN;
3510                         break;
3511                 }
3512 
3513                 /* Check the unsolicited buffer array. */
3514                 QL_UB_LOCK(ha);
3515                 ubp = ha->ub_array[ub_array_index];
3516 
3517                 if (ubp == NULL) {
3518                         EL(ha, "failed, FC_UB_BADTOKEN-2\n");
3519                         rval = FC_UB_BADTOKEN;
3520                         QL_UB_UNLOCK(ha);
3521                         break;
3522                 }
3523 
3524                 /* Check the state of the unsolicited buffer. */
3525                 sp = ha->ub_array[ub_array_index]->ub_fca_private;
3526                 sp->flags |= SRB_UB_FREE_REQUESTED;
3527 
3528                 while (!(sp->flags & SRB_UB_IN_FCA) ||
3529                     (sp->flags & (SRB_UB_CALLBACK | SRB_UB_ACQUIRED))) {
3530                         QL_UB_UNLOCK(ha);
3531                         ADAPTER_STATE_UNLOCK(ha);
3532                         delay(drv_usectohz(100000));
3533                         ADAPTER_STATE_LOCK(ha);
3534                         QL_UB_LOCK(ha);
3535                 }
3536                 ha->ub_array[ub_array_index] = NULL;
3537                 QL_UB_UNLOCK(ha);
3538                 ql_free_unsolicited_buffer(ha, ubp);
3539         }
3540 
3541         if (rval == FC_SUCCESS) {
3542                 /*
3543                  * Signal any pending hardware reset when there are
3544                  * no more unsolicited buffers in use.
3545                  */
3546                 if (ha->ub_allocated == 0) {
3547                         cv_broadcast(&ha->pha->cv_ub);
3548                 }
3549         }
3550 
3551         /* Release adapter state lock. */
3552         ADAPTER_STATE_UNLOCK(ha);
3553 
3554         if (rval != FC_SUCCESS) {
3555                 EL(ha, "failed=%xh\n", rval);
3556         } else {
3557                 /*EMPTY*/
3558                 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
3559         }
3560         return (rval);
3561 }
3562 
3563 /*
3564  * ql_ub_release
3565  *      Release unsolicited buffers from FC Transport
3566  *      to FCA for future use.
3567  *
3568  * Input:
3569  *      fca_handle = handle setup by ql_bind_port().
3570  *      count = number of buffers.
3571  *      tokens = token array for each buffer.
3572  *
3573  * Returns:
3574  *      FC_SUCCESS - the requested buffers have been released.
3575  *      FC_UNBOUND - the fca_handle specified is not bound.
3576  *      FC_UB_BADTOKEN - an invalid token was encountered.
3577  *              No buffers have been released.
3578  *
3579  * Context:
3580  *      Kernel context.
3581  */
3582 static int
3583 ql_ub_release(opaque_t fca_handle, uint32_t count, uint64_t tokens[])
3584 {
3585         ql_adapter_state_t      *ha;
3586         ql_srb_t                *sp;
3587         uint32_t                index;
3588         uint64_t                ub_array_index;
3589         int                     rval = FC_SUCCESS;
3590         int                     ub_ip_updated = FALSE;
3591 
3592         /* Check handle. */
3593         ha = ql_fca_handle_to_state(fca_handle);
3594         if (ha == NULL) {
3595                 QL_PRINT_2(CE_CONT, ": failed, no adapter=%ph\n",
3596                     (void *)fca_handle);
3597                 return (FC_UNBOUND);
3598         }
3599         QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
3600 
3601         /* Acquire adapter state lock. */
3602         ADAPTER_STATE_LOCK(ha);
3603         QL_UB_LOCK(ha);
3604 
3605         /* Check all returned tokens. */
3606         for (index = 0; index < count; index++) {
3607                 /* Check the token range. */
3608                 if ((ub_array_index = tokens[index]) >= QL_UB_LIMIT) {
3609                         EL(ha, "failed, FC_UB_BADTOKEN\n");
3610                         rval = FC_UB_BADTOKEN;
3611                         break;
3612                 }
3613 
3614                 /* Check the unsolicited buffer array. */
3615                 if (ha->ub_array[ub_array_index] == NULL) {
3616                         EL(ha, "failed, FC_UB_BADTOKEN-2\n");
3617                         rval = FC_UB_BADTOKEN;
3618                         break;
3619                 }
3620 
3621                 /* Check the state of the unsolicited buffer. */
3622                 sp = ha->ub_array[ub_array_index]->ub_fca_private;
3623                 if (sp->flags & SRB_UB_IN_FCA) {
3624                         EL(ha, "failed, FC_UB_BADTOKEN-3\n");
3625                         rval = FC_UB_BADTOKEN;
3626                         break;
3627                 }
3628         }
3629 
3630         /* If all tokens checkout, release the buffers. */
3631         if (rval == FC_SUCCESS) {
3632                 /* Check all returned tokens. */
3633                 for (index = 0; index < count; index++) {
3634                         fc_unsol_buf_t  *ubp;
3635 
3636                         ub_array_index = tokens[index];
3637                         ubp = ha->ub_array[ub_array_index];
3638                         sp = ubp->ub_fca_private;
3639 
3640                         ubp->ub_resp_flags = 0;
3641                         sp->flags &= ~(SRB_UB_ACQUIRED | SRB_UB_CALLBACK);
3642                         sp->flags |= SRB_UB_IN_FCA;
3643 
3644                         /* IP buffer. */
3645                         if (sp->ub_type == FC_TYPE_IS8802_SNAP) {
3646                                 ub_ip_updated = TRUE;
3647                         }
3648                 }
3649         }
3650 
3651         QL_UB_UNLOCK(ha);
3652         /* Release adapter state lock. */
3653         ADAPTER_STATE_UNLOCK(ha);
3654 
3655         /*
3656          * XXX: We should call ql_isp_rcvbuf() to return a
3657          * buffer to ISP only if the number of buffers fall below
3658          * the low water mark.
3659          */
3660         if (ub_ip_updated) {
3661                 ql_isp_rcvbuf(ha);
3662         }
3663 
3664         if (rval != FC_SUCCESS) {
3665                 EL(ha, "failed, rval = %xh\n", rval);
3666         } else {
3667                 /*EMPTY*/
3668                 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
3669         }
3670         return (rval);
3671 }
3672 
3673 /*
3674  * ql_abort
3675  *      Abort a packet.
3676  *
3677  * Input:
3678  *      fca_handle = handle setup by ql_bind_port().
3679  *      pkt = pointer to fc_packet.
3680  *      flags = KM_SLEEP flag.
3681  *
3682  * Returns:
3683  *      FC_SUCCESS - the packet has successfully aborted.
3684  *      FC_ABORTED - the packet has successfully aborted.
3685  *      FC_ABORTING - the packet is being aborted.
3686  *      FC_ABORT_FAILED - the packet could not be aborted.
3687  *      FC_TRANSPORT_ERROR - a transport error occurred while attempting
3688  *              to abort the packet.
3689  *      FC_BADEXCHANGE - no packet found.
3690  *      FC_UNBOUND - the fca_handle specified is not bound.
3691  *
3692  * Context:
3693  *      Kernel context.
3694  */
3695 static int
3696 ql_abort(opaque_t fca_handle, fc_packet_t *pkt, int flags)
3697 {
3698         port_id_t               d_id;
3699         ql_link_t               *link;
3700         ql_adapter_state_t      *ha, *pha;
3701         ql_srb_t                *sp;
3702         ql_tgt_t                *tq;
3703         ql_lun_t                *lq;
3704         int                     rval = FC_ABORTED;
3705 
3706         ha = ql_fca_handle_to_state(fca_handle);
3707         if (ha == NULL) {
3708                 QL_PRINT_2(CE_CONT, "failed, no adapter=%ph\n",
3709                     (void *)fca_handle);
3710                 return (FC_UNBOUND);
3711         }
3712 
3713         pha = ha->pha;
3714 
3715         QL_PRINT_3(CE_CONT, "(%d,%d): started\n", ha->instance, ha->vp_index);
3716 
3717         /* Get target queue pointer. */
3718         d_id.b24 = pkt->pkt_cmd_fhdr.d_id;
3719         tq = ql_d_id_to_queue(ha, d_id);
3720 
3721         if ((tq == NULL) || (pha->task_daemon_flags & LOOP_DOWN)) {
3722                 if (tq == NULL) {
3723                         EL(ha, "failed, FC_TRANSPORT_ERROR\n");
3724                         rval = FC_TRANSPORT_ERROR;
3725                 } else {
3726                         EL(ha, "failed, FC_OFFLINE\n");
3727                         rval = FC_OFFLINE;
3728                 }
3729                 return (rval);
3730         }
3731 
3732         sp = (ql_srb_t *)pkt->pkt_fca_private;
3733         lq = sp->lun_queue;
3734 
3735         /* Set poll flag if sleep wanted. */
3736         if (flags == KM_SLEEP) {
3737                 sp->flags |= SRB_POLL;
3738         }
3739 
3740         /* Acquire target queue lock. */
3741         DEVICE_QUEUE_LOCK(tq);
3742         REQUEST_RING_LOCK(ha);
3743 
3744         /* If command not already started. */
3745         if (!(sp->flags & SRB_ISP_STARTED)) {
3746                 /* Check pending queue for command. */
3747                 sp = NULL;
3748                 for (link = pha->pending_cmds.first; link != NULL;
3749                     link = link->next) {
3750                         sp = link->base_address;
3751                         if (sp == (ql_srb_t *)pkt->pkt_fca_private) {
3752                                 /* Remove srb from q. */
3753                                 ql_remove_link(&pha->pending_cmds, &sp->cmd);
3754                                 break;
3755                         } else {
3756                                 sp = NULL;
3757                         }
3758                 }
3759                 REQUEST_RING_UNLOCK(ha);
3760 
3761                 if (sp == NULL) {
3762                         /* Check for cmd on device queue. */
3763                         for (link = lq->cmd.first; link != NULL;
3764                             link = link->next) {
3765                                 sp = link->base_address;
3766                                 if (sp == (ql_srb_t *)pkt->pkt_fca_private) {
3767                                         /* Remove srb from q. */
3768                                         ql_remove_link(&lq->cmd, &sp->cmd);
3769                                         break;
3770                                 } else {
3771                                         sp = NULL;
3772                                 }
3773                         }
3774                 }
3775                 /* Release device lock */
3776                 DEVICE_QUEUE_UNLOCK(tq);
3777 
3778                 /* If command on target queue. */
3779                 if (sp != NULL) {
3780                         sp->flags &= ~SRB_IN_DEVICE_QUEUE;
3781 
3782                         /* Set return status */
3783                         pkt->pkt_reason = CS_ABORTED;
3784 
3785                         sp->cmd.next = NULL;
3786                         ql_done(&sp->cmd);
3787                         rval = FC_ABORTED;
3788                 } else {
3789                         EL(ha, "failed, FC_BADEXCHANGE\n");
3790                         rval = FC_BADEXCHANGE;
3791                 }
3792         } else if (sp->flags & SRB_ISP_COMPLETED) {
3793                 /* Release device queue lock. */
3794                 REQUEST_RING_UNLOCK(ha);
3795                 DEVICE_QUEUE_UNLOCK(tq);
3796                 EL(ha, "failed, already done, FC_FAILURE\n");
3797                 rval = FC_FAILURE;
3798         } else if ((sp->pkt->pkt_cmd_fhdr.r_ctl == R_CTL_SOLICITED_DATA) ||
3799             (sp->pkt->pkt_cmd_fhdr.r_ctl == R_CTL_STATUS)) {
3800                 /*
3801                  * If here, target data/resp ctio is with Fw.
3802                  * Since firmware is supposed to terminate such I/Os
3803                  * with an error, we need not do any thing. If FW
3804                  * decides not to terminate those IOs and simply keep
3805                  * quite then we need to initiate cleanup here by
3806                  * calling ql_done.
3807                  */
3808                 REQUEST_RING_UNLOCK(ha);
3809                 DEVICE_QUEUE_UNLOCK(tq);
3810                 rval = FC_ABORTED;
3811         } else {
3812                 request_t       *ep = pha->request_ring_bp;
3813                 uint16_t        cnt;
3814 
3815                 if (sp->handle != 0) {
3816                         for (cnt = 0; cnt < REQUEST_ENTRY_CNT; cnt++) {
3817                                 if (sp->handle == ddi_get32(
3818                                     pha->hba_buf.acc_handle, &ep->handle)) {
3819                                         ep->entry_type = INVALID_ENTRY_TYPE;
3820                                         break;
3821                                 }
3822                                 ep++;
3823                         }
3824                 }
3825 
3826                 /* Release device queue lock. */
3827                 REQUEST_RING_UNLOCK(ha);
3828                 DEVICE_QUEUE_UNLOCK(tq);
3829 
3830                 sp->flags |= SRB_ABORTING;
3831                 (void) ql_abort_command(ha, sp);
3832                 pkt->pkt_reason = CS_ABORTED;
3833                 rval = FC_ABORTED;
3834         }
3835 
3836         QL_PRINT_3(CE_CONT, "(%d,%d): done\n", ha->instance, ha->vp_index);
3837 
3838         return (rval);
3839 }
3840 
3841 /*
3842  * ql_reset
3843  *      Reset link or hardware.
3844  *
3845  * Input:
3846  *      fca_handle = handle setup by ql_bind_port().
3847  *      cmd = reset type command.
3848  *
3849  * Returns:
3850  *      FC_SUCCESS - reset has successfully finished.
3851  *      FC_UNBOUND - the fca_handle specified is not bound.
3852  *      FC_FAILURE - reset failed.
3853  *
3854  * Context:
3855  *      Kernel context.
3856  */
3857 static int
3858 ql_reset(opaque_t fca_handle, uint32_t cmd)
3859 {
3860         ql_adapter_state_t      *ha;
3861         int                     rval = FC_SUCCESS, rval2;
3862 
3863         ha = ql_fca_handle_to_state(fca_handle);
3864         if (ha == NULL) {
3865                 QL_PRINT_2(CE_CONT, "failed, no adapter=%ph\n",
3866                     (void *)fca_handle);
3867                 return (FC_UNBOUND);
3868         }
3869 
3870         QL_PRINT_3(CE_CONT, "(%d,%d): started, cmd=%d\n", ha->instance,
3871             ha->vp_index, cmd);
3872 
3873         switch (cmd) {
3874         case FC_FCA_CORE:
3875                 /* dump firmware core if specified. */
3876                 if (ha->vp_index == 0) {
3877                         if (ql_dump_firmware(ha) != QL_SUCCESS) {
3878                                 EL(ha, "failed, FC_FAILURE\n");
3879                                 rval = FC_FAILURE;
3880                         }
3881                 }
3882                 break;
3883         case FC_FCA_LINK_RESET:
3884                 if (!(ha->pha->task_daemon_flags & LOOP_DOWN)) {
3885                         if (ql_loop_reset(ha) != QL_SUCCESS) {
3886                                 EL(ha, "failed, FC_FAILURE-2\n");
3887                                 rval = FC_FAILURE;
3888                         }
3889                 }
3890                 break;
3891         case FC_FCA_RESET_CORE:
3892         case FC_FCA_RESET:
3893                 /* if dump firmware core if specified. */
3894                 if (cmd == FC_FCA_RESET_CORE) {
3895                         if (ha->vp_index != 0) {
3896                                 rval2 = ha->pha->task_daemon_flags & LOOP_DOWN
3897                                     ? QL_SUCCESS : ql_loop_reset(ha);
3898                         } else {
3899                                 rval2 = ql_dump_firmware(ha);
3900                         }
3901                         if (rval2 != QL_SUCCESS) {
3902                                 EL(ha, "failed, FC_FAILURE-3\n");
3903                                 rval = FC_FAILURE;
3904                         }
3905                 }
3906 
3907                 /* Free up all unsolicited buffers. */
3908                 if (ha->ub_allocated != 0) {
3909                         /* Inform to release buffers. */
3910                         ha->state = FC_PORT_SPEED_MASK(ha->state);
3911                         ha->state |= FC_STATE_RESET_REQUESTED;
3912                         if (ha->flags & FCA_BOUND) {
3913                                 (ha->bind_info.port_statec_cb)
3914                                     (ha->bind_info.port_handle,
3915                                     ha->state);
3916                         }
3917                 }
3918 
3919                 ha->state = FC_PORT_SPEED_MASK(ha->state);
3920 
3921                 /* All buffers freed */
3922                 if (ha->ub_allocated == 0) {
3923                         /* Hardware reset. */
3924                         if (cmd == FC_FCA_RESET) {
3925                                 if (ha->vp_index == 0) {
3926                                         (void) ql_abort_isp(ha);
3927                                 } else if (!(ha->pha->task_daemon_flags &
3928                                     LOOP_DOWN)) {
3929                                         (void) ql_loop_reset(ha);
3930                                 }
3931                         }
3932 
3933                         /* Inform that the hardware has been reset */
3934                         ha->state |= FC_STATE_RESET;
3935                 } else {
3936                         /*
3937                          * the port driver expects an online if
3938                          * buffers are not freed.
3939                          */
3940                         if (ha->topology & QL_LOOP_CONNECTION) {
3941                                 ha->state |= FC_STATE_LOOP;
3942                         } else {
3943                                 ha->state |= FC_STATE_ONLINE;
3944                         }
3945                 }
3946 
3947                 TASK_DAEMON_LOCK(ha);
3948                 ha->task_daemon_flags |= FC_STATE_CHANGE;
3949                 TASK_DAEMON_UNLOCK(ha);
3950 
3951                 ql_awaken_task_daemon(ha, NULL, FC_STATE_CHANGE, 0);
3952 
3953                 break;
3954         default:
3955                 EL(ha, "unknown cmd=%xh\n", cmd);
3956                 break;
3957         }
3958 
3959         if (rval != FC_SUCCESS) {
3960                 EL(ha, "cmd=%xh, failed=%xh\n", cmd, rval);
3961         } else {
3962                 /*EMPTY*/
3963                 QL_PRINT_3(CE_CONT, "(%d,%d): done\n", ha->instance,
3964                     ha->vp_index);
3965         }
3966 
3967         return (rval);
3968 }
3969 
3970 /*
3971  * ql_port_manage
3972  *      Perform port management or diagnostics.
3973  *
3974  * Input:
3975  *      fca_handle = handle setup by ql_bind_port().
3976  *      cmd = pointer to command structure.
3977  *
3978  * Returns:
3979  *      FC_SUCCESS - the request completed successfully.
3980  *      FC_FAILURE - the request did not complete successfully.
3981  *      FC_UNBOUND - the fca_handle specified is not bound.
3982  *
3983  * Context:
3984  *      Kernel context.
3985  */
3986 static int
3987 ql_port_manage(opaque_t fca_handle, fc_fca_pm_t *cmd)
3988 {
3989         clock_t                 timer;
3990         uint16_t                index;
3991         uint32_t                *bp;
3992         port_id_t               d_id;
3993         ql_link_t               *link;
3994         ql_adapter_state_t      *ha, *pha;
3995         ql_tgt_t                *tq;
3996         dma_mem_t               buffer_xmt, buffer_rcv;
3997         size_t                  length;
3998         uint32_t                cnt;
3999         char                    buf[80];
4000         lbp_t                   *lb;
4001         ql_mbx_data_t           mr;
4002         app_mbx_cmd_t           *mcp;
4003         int                     i0;
4004         uint8_t                 *bptr;
4005         int                     rval2, rval = FC_SUCCESS;
4006         uint32_t                opcode;
4007         uint32_t                set_flags = 0;
4008 
4009         ha = ql_fca_handle_to_state(fca_handle);
4010         if (ha == NULL) {
4011                 QL_PRINT_2(CE_CONT, ": failed, no adapter=%ph\n",
4012                     (void *)fca_handle);
4013                 return (FC_UNBOUND);
4014         }
4015         pha = ha->pha;
4016 
4017         QL_PRINT_3(CE_CONT, "(%d): started=%xh\n", ha->instance,
4018             cmd->pm_cmd_code);
4019 
4020         ql_awaken_task_daemon(ha, NULL, DRIVER_STALL, 0);
4021 
4022         /*
4023          * Wait for all outstanding commands to complete
4024          */
4025         index = (uint16_t)ql_wait_outstanding(ha);
4026 
4027         if (index != MAX_OUTSTANDING_COMMANDS) {
4028                 ql_awaken_task_daemon(ha, NULL, 0, DRIVER_STALL);
4029                 ql_restart_queues(ha);
4030                 EL(ha, "failed, FC_TRAN_BUSY\n");
4031                 return (FC_TRAN_BUSY);
4032         }
4033 
4034         switch (cmd->pm_cmd_code) {
4035         case FC_PORT_BYPASS:
4036                 d_id.b24 = *cmd->pm_cmd_buf;
4037                 tq = ql_d_id_to_queue(ha, d_id);
4038                 if (tq == NULL || ql_loop_port_bypass(ha, tq) != QL_SUCCESS) {
4039                         EL(ha, "failed, FC_PORT_BYPASS FC_FAILURE\n");
4040                         rval = FC_FAILURE;
4041                 }
4042                 break;
4043         case FC_PORT_UNBYPASS:
4044                 d_id.b24 = *cmd->pm_cmd_buf;
4045                 tq = ql_d_id_to_queue(ha, d_id);
4046                 if (tq == NULL || ql_loop_port_enable(ha, tq) != QL_SUCCESS) {
4047                         EL(ha, "failed, FC_PORT_UNBYPASS FC_FAILURE\n");
4048                         rval = FC_FAILURE;
4049                 }
4050                 break;
4051         case FC_PORT_GET_FW_REV:
4052                 (void) sprintf(buf, "%d.%d.%d", pha->fw_major_version,
4053                     pha->fw_minor_version, pha->fw_subminor_version);
4054                 length = strlen(buf) + 1;
4055                 if (cmd->pm_data_len < length) {
4056                         cmd->pm_data_len = length;
4057                         EL(ha, "failed, FC_PORT_GET_FW_REV FC_FAILURE\n");
4058                         rval = FC_FAILURE;
4059                 } else {
4060                         (void) strcpy(cmd->pm_data_buf, buf);
4061                 }
4062                 break;
4063 
4064         case FC_PORT_GET_FCODE_REV: {
4065                 caddr_t         fcode_ver_buf = NULL;
4066 
4067                 i0 = 0;
4068                 /*LINTED [Solaris DDI_DEV_T_ANY Lint warning]*/
4069                 rval2 = ddi_getlongprop(DDI_DEV_T_ANY, ha->dip,
4070                     DDI_PROP_DONTPASS | DDI_PROP_CANSLEEP, "version",
4071                     (caddr_t)&fcode_ver_buf, &i0);
4072                 length = (uint_t)i0;
4073 
4074                 if (rval2 != DDI_PROP_SUCCESS) {
4075                         EL(ha, "failed, getting version = %xh\n", rval2);
4076                         length = 20;
4077                         fcode_ver_buf = kmem_alloc(length, KM_SLEEP);
4078                         if (fcode_ver_buf != NULL) {
4079                                 (void) sprintf(fcode_ver_buf,
4080                                     "NO FCODE FOUND");
4081                         }
4082                 }
4083 
4084                 if (cmd->pm_data_len < length) {
4085                         EL(ha, "length error, FC_PORT_GET_FCODE_REV "
4086                             "dst=%ld, src=%ld\n", cmd->pm_data_len, length);
4087                         cmd->pm_data_len = length;
4088                         rval = FC_FAILURE;
4089                 } else if (fcode_ver_buf != NULL) {
4090                         bcopy((void *)fcode_ver_buf, (void *)cmd->pm_data_buf,
4091                             length);
4092                 }
4093 
4094                 if (fcode_ver_buf != NULL) {
4095                         kmem_free(fcode_ver_buf, length);
4096                 }
4097                 break;
4098         }
4099 
4100         case FC_PORT_GET_DUMP:
4101                 QL_DUMP_LOCK(pha);
4102                 if (cmd->pm_data_len < (size_t)pha->risc_dump_size) {
4103                         EL(ha, "failed, FC_PORT_GET_DUMP incorrect "
4104                             "length=%lxh\n", cmd->pm_data_len);
4105                         cmd->pm_data_len = pha->risc_dump_size;
4106                         rval = FC_FAILURE;
4107                 } else if (pha->ql_dump_state & QL_DUMPING) {
4108                         EL(ha, "failed, FC_PORT_GET_DUMP FC_TRAN_BUSY\n");
4109                         rval = FC_TRAN_BUSY;
4110                 } else if (pha->ql_dump_state & QL_DUMP_VALID) {
4111                         (void) ql_ascii_fw_dump(ha, cmd->pm_data_buf);
4112                         pha->ql_dump_state |= QL_DUMP_UPLOADED;
4113                 } else {
4114                         EL(ha, "failed, FC_PORT_GET_DUMP no dump file\n");
4115                         rval = FC_FAILURE;
4116                 }
4117                 QL_DUMP_UNLOCK(pha);
4118                 break;
4119         case FC_PORT_FORCE_DUMP:
4120                 PORTMANAGE_LOCK(ha);
4121                 if (ql_dump_firmware(ha) != QL_SUCCESS) {
4122                         EL(ha, "failed, FC_PORT_FORCE_DUMP FC_FAILURE\n");
4123                         rval = FC_FAILURE;
4124                 }
4125                 PORTMANAGE_UNLOCK(ha);
4126                 break;
4127         case FC_PORT_DOWNLOAD_FW:
4128                 PORTMANAGE_LOCK(ha);
4129                 if (CFG_IST(ha, CFG_CTRL_24258081)) {
4130                         if (ql_24xx_load_flash(ha, (uint8_t *)cmd->pm_data_buf,
4131                             (uint32_t)cmd->pm_data_len,
4132                             ha->flash_fw_addr << 2) != QL_SUCCESS) {
4133                                 EL(ha, "failed, FC_PORT_DOWNLOAD_FW\n");
4134                                 rval = FC_FAILURE;
4135                         }
4136                         ql_reset_chip(ha);
4137                         set_flags |= ISP_ABORT_NEEDED;
4138                 } else {
4139                         /* Save copy of the firmware. */
4140                         if (pha->risc_code != NULL) {
4141                                 kmem_free(pha->risc_code, pha->risc_code_size);
4142                                 pha->risc_code = NULL;
4143                                 pha->risc_code_size = 0;
4144                         }
4145 
4146                         pha->risc_code = kmem_alloc(cmd->pm_data_len,
4147                             KM_SLEEP);
4148                         if (pha->risc_code != NULL) {
4149                                 pha->risc_code_size =
4150                                     (uint32_t)cmd->pm_data_len;
4151                                 bcopy(cmd->pm_data_buf, pha->risc_code,
4152                                     cmd->pm_data_len);
4153 
4154                                 /* Do abort to force reload. */
4155                                 ql_reset_chip(ha);
4156                                 if (ql_abort_isp(ha) != QL_SUCCESS) {
4157                                         kmem_free(pha->risc_code,
4158                                             pha->risc_code_size);
4159                                         pha->risc_code = NULL;
4160                                         pha->risc_code_size = 0;
4161                                         ql_reset_chip(ha);
4162                                         (void) ql_abort_isp(ha);
4163                                         EL(ha, "failed, FC_PORT_DOWNLOAD_FW"
4164                                             " FC_FAILURE\n");
4165                                         rval = FC_FAILURE;
4166                                 }
4167                         }
4168                 }
4169                 PORTMANAGE_UNLOCK(ha);
4170                 break;
4171         case FC_PORT_GET_DUMP_SIZE:
4172                 bp = (uint32_t *)cmd->pm_data_buf;
4173                 *bp = pha->risc_dump_size;
4174                 break;
4175         case FC_PORT_DIAG:
4176                 /*
4177                  * Prevents concurrent diags
4178                  */
4179                 PORTMANAGE_LOCK(ha);
4180 
4181                 /* Wait for suspension to end. */
4182                 for (timer = 0; timer < 3000 &&
4183                     pha->task_daemon_flags & QL_LOOP_TRANSITION; timer++) {
4184                         ql_delay(ha, 10000);
4185                 }
4186 
4187                 if (pha->task_daemon_flags & QL_LOOP_TRANSITION) {
4188                         EL(ha, "failed, FC_TRAN_BUSY-2\n");
4189                         rval = FC_TRAN_BUSY;
4190                         PORTMANAGE_UNLOCK(ha);
4191                         break;
4192                 }
4193 
4194                 switch (cmd->pm_cmd_flags) {
4195                 case QL_DIAG_EXEFMW:
4196                         if (ql_start_firmware(ha) != QL_SUCCESS) {
4197                                 EL(ha, "failed, QL_DIAG_EXEFMW FC_FAILURE\n");
4198                                 rval = FC_FAILURE;
4199                         }
4200                         break;
4201                 case QL_DIAG_CHKCMDQUE:
4202                         for (i0 = 1, cnt = 0; i0 < MAX_OUTSTANDING_COMMANDS;
4203                             i0++) {
4204                                 cnt += (pha->outstanding_cmds[i0] != NULL);
4205                         }
4206                         if (cnt != 0) {
4207                                 EL(ha, "failed, QL_DIAG_CHKCMDQUE "
4208                                     "FC_FAILURE\n");
4209                                 rval = FC_FAILURE;
4210                         }
4211                         break;
4212                 case QL_DIAG_FMWCHKSUM:
4213                         if (ql_verify_checksum(ha) != QL_SUCCESS) {
4214                                 EL(ha, "failed, QL_DIAG_FMWCHKSUM "
4215                                     "FC_FAILURE\n");
4216                                 rval = FC_FAILURE;
4217                         }
4218                         break;
4219                 case QL_DIAG_SLFTST:
4220                         if (ql_online_selftest(ha) != QL_SUCCESS) {
4221                                 EL(ha, "failed, QL_DIAG_SLFTST FC_FAILURE\n");
4222                                 rval = FC_FAILURE;
4223                         }
4224                         ql_reset_chip(ha);
4225                         set_flags |= ISP_ABORT_NEEDED;
4226                         break;
4227                 case QL_DIAG_REVLVL:
4228                         if (cmd->pm_stat_len <
4229                             sizeof (ql_adapter_revlvl_t)) {
4230                                 EL(ha, "failed, QL_DIAG_REVLVL FC_NOMEM, "
4231                                     "slen=%lxh, rlvllen=%lxh\n",
4232                                     cmd->pm_stat_len,
4233                                     sizeof (ql_adapter_revlvl_t));
4234                                 rval = FC_NOMEM;
4235                         } else {
4236                                 bcopy((void *)&(pha->adapter_stats->revlvl),
4237                                     cmd->pm_stat_buf,
4238                                     (size_t)cmd->pm_stat_len);
4239                                 cmd->pm_stat_len =
4240                                     sizeof (ql_adapter_revlvl_t);
4241                         }
4242                         break;
4243                 case QL_DIAG_LPBMBX:
4244 
4245                         if (cmd->pm_data_len != sizeof (struct app_mbx_cmd)) {
4246                                 EL(ha, "failed, QL_DIAG_LPBMBX "
4247                                     "FC_INVALID_REQUEST, pmlen=%lxh, "
4248                                     "reqd=%lxh\n", cmd->pm_data_len,
4249                                     sizeof (struct app_mbx_cmd));
4250                                 rval = FC_INVALID_REQUEST;
4251                                 break;
4252                         }
4253                         /*
4254                          * Don't do the wrap test on a 2200 when the
4255                          * firmware is running.
4256                          */
4257                         if (!CFG_IST(ha, CFG_CTRL_2200)) {
4258                                 mcp = (app_mbx_cmd_t *)cmd->pm_data_buf;
4259                                 mr.mb[1] = mcp->mb[1];
4260                                 mr.mb[2] = mcp->mb[2];
4261                                 mr.mb[3] = mcp->mb[3];
4262                                 mr.mb[4] = mcp->mb[4];
4263                                 mr.mb[5] = mcp->mb[5];
4264                                 mr.mb[6] = mcp->mb[6];
4265                                 mr.mb[7] = mcp->mb[7];
4266 
4267                                 bcopy(&mr.mb[0], &mr.mb[10],
4268                                     sizeof (uint16_t) * 8);
4269 
4270                                 if (ql_mbx_wrap_test(ha, &mr) != QL_SUCCESS) {
4271                                         EL(ha, "failed, QL_DIAG_LPBMBX "
4272                                             "FC_FAILURE\n");
4273                                         rval = FC_FAILURE;
4274                                         break;
4275                                 } else {
4276                                         for (i0 = 1; i0 < 8; i0++) {
4277                                                 if (mr.mb[i0] !=
4278                                                     mr.mb[i0 + 10]) {
4279                                                         EL(ha, "failed, "
4280                                                             "QL_DIAG_LPBMBX "
4281                                                             "FC_FAILURE-2\n");
4282                                                         rval = FC_FAILURE;
4283                                                         break;
4284                                                 }
4285                                         }
4286                                 }
4287 
4288                                 if (rval == FC_FAILURE) {
4289                                         (void) ql_flash_errlog(ha,
4290                                             FLASH_ERRLOG_ISP_ERR, 0,
4291                                             RD16_IO_REG(ha, hccr),
4292                                             RD16_IO_REG(ha, istatus));
4293                                         set_flags |= ISP_ABORT_NEEDED;
4294                                 }
4295                         }
4296                         break;
4297                 case QL_DIAG_LPBDTA:
4298                         /*
4299                          * For loopback data, we receive the
4300                          * data back in pm_stat_buf. This provides
4301                          * the user an opportunity to compare the
4302                          * transmitted and received data.
4303                          *
4304                          * NB: lb->options are:
4305                          *      0 --> Ten bit loopback
4306                          *      1 --> One bit loopback
4307                          *      2 --> External loopback
4308                          */
4309                         if (cmd->pm_data_len > 65536) {
4310                                 rval = FC_TOOMANY;
4311                                 EL(ha, "failed, QL_DIAG_LPBDTA "
4312                                     "FC_TOOMANY=%lxh\n", cmd->pm_data_len);
4313                                 break;
4314                         }
4315                         if (ql_get_dma_mem(ha, &buffer_xmt,
4316                             (uint32_t)cmd->pm_data_len, LITTLE_ENDIAN_DMA,
4317                             QL_DMA_DATA_ALIGN) != QL_SUCCESS) {
4318                                 EL(ha, "failed, QL_DIAG_LPBDTA FC_NOMEM\n");
4319                                 rval = FC_NOMEM;
4320                                 break;
4321                         }
4322                         if (ql_get_dma_mem(ha, &buffer_rcv,
4323                             (uint32_t)cmd->pm_data_len, LITTLE_ENDIAN_DMA,
4324                             QL_DMA_DATA_ALIGN) != QL_SUCCESS) {
4325                                 EL(ha, "failed, QL_DIAG_LPBDTA FC_NOMEM-2\n");
4326                                 rval = FC_NOMEM;
4327                                 break;
4328                         }
4329                         ddi_rep_put8(buffer_xmt.acc_handle,
4330                             (uint8_t *)cmd->pm_data_buf,
4331                             (uint8_t *)buffer_xmt.bp,
4332                             cmd->pm_data_len, DDI_DEV_AUTOINCR);
4333 
4334                         /* 22xx's adapter must be in loop mode for test. */
4335                         if (CFG_IST(ha, CFG_CTRL_2200)) {
4336                                 bptr = &ha->init_ctrl_blk.cb.add_fw_opt[0];
4337                                 if (ha->flags & POINT_TO_POINT ||
4338                                     (ha->task_daemon_flags & LOOP_DOWN &&
4339                                     *bptr & (BIT_6 | BIT_5 | BIT_4))) {
4340                                         cnt = *bptr;
4341                                         *bptr = (uint8_t)
4342                                             (*bptr & ~(BIT_6|BIT_5|BIT_4));
4343                                         (void) ql_abort_isp(ha);
4344                                         *bptr = (uint8_t)cnt;
4345                                 }
4346                         }
4347 
4348                         /* Shutdown IP. */
4349                         if (pha->flags & IP_INITIALIZED) {
4350                                 (void) ql_shutdown_ip(pha);
4351                         }
4352 
4353                         lb = (lbp_t *)cmd->pm_cmd_buf;
4354                         lb->transfer_count =
4355                             (uint32_t)cmd->pm_data_len;
4356                         lb->transfer_segment_count = 0;
4357                         lb->receive_segment_count = 0;
4358                         lb->transfer_data_address =
4359                             buffer_xmt.cookie.dmac_address;
4360                         lb->receive_data_address =
4361                             buffer_rcv.cookie.dmac_address;
4362 
4363                         if (ql_loop_back(ha, 0, lb,
4364                             buffer_xmt.cookie.dmac_notused,
4365                             buffer_rcv.cookie.dmac_notused) == QL_SUCCESS) {
4366                                 bzero((void *)cmd->pm_stat_buf,
4367                                     cmd->pm_stat_len);
4368                                 ddi_rep_get8(buffer_rcv.acc_handle,
4369                                     (uint8_t *)cmd->pm_stat_buf,
4370                                     (uint8_t *)buffer_rcv.bp,
4371                                     cmd->pm_stat_len, DDI_DEV_AUTOINCR);
4372                                 rval = FC_SUCCESS;
4373                         } else {
4374                                 EL(ha, "failed, QL_DIAG_LPBDTA FC_FAILURE\n");
4375                                 rval = FC_FAILURE;
4376                         }
4377 
4378                         ql_free_phys(ha, &buffer_xmt);
4379                         ql_free_phys(ha, &buffer_rcv);
4380 
4381                         /* Needed to recover the f/w */
4382                         set_flags |= ISP_ABORT_NEEDED;
4383 
4384                         /* Restart IP if it was shutdown. */
4385                         if (pha->flags & IP_ENABLED &&
4386                             !(pha->flags & IP_INITIALIZED)) {
4387                                 (void) ql_initialize_ip(pha);
4388                                 ql_isp_rcvbuf(pha);
4389                         }
4390 
4391                         break;
4392                 case QL_DIAG_ECHO: {
4393                         /*
4394                          * issue an echo command with a user supplied
4395                          * data pattern and destination address
4396                          */
4397                         echo_t          echo;           /* temp echo struct */
4398 
4399                         /* Setup echo cmd & adjust for platform */
4400                         opcode = QL_ECHO_CMD;
4401                         BIG_ENDIAN_32(&opcode);
4402 
4403                         /*
4404                          * due to limitations in the ql
4405                          * firmaware the echo data field is
4406                          * limited to 220
4407                          */
4408                         if ((cmd->pm_cmd_len > QL_ECHO_CMD_LENGTH) ||
4409                             (cmd->pm_stat_len > QL_ECHO_CMD_LENGTH)) {
4410                                 EL(ha, "failed, QL_DIAG_ECHO FC_TOOMANY, "
4411                                     "cmdl1=%lxh, statl2=%lxh\n",
4412                                     cmd->pm_cmd_len, cmd->pm_stat_len);
4413                                 rval = FC_TOOMANY;
4414                                 break;
4415                         }
4416 
4417                         /*
4418                          * the input data buffer has the user
4419                          * supplied data pattern.  The "echoed"
4420                          * data will be DMAed into the output
4421                          * data buffer.  Therefore the length
4422                          * of the output buffer must be equal
4423                          * to or greater then the input buffer
4424                          * length
4425                          */
4426                         if (cmd->pm_cmd_len > cmd->pm_stat_len) {
4427                                 EL(ha, "failed, QL_DIAG_ECHO FC_TOOMANY-2,"
4428                                     " cmdl1=%lxh, statl2=%lxh\n",
4429                                     cmd->pm_cmd_len, cmd->pm_stat_len);
4430                                 rval = FC_TOOMANY;
4431                                 break;
4432                         }
4433                         /* add four bytes for the opcode */
4434                         echo.transfer_count = (uint32_t)(cmd->pm_cmd_len + 4);
4435 
4436                         /*
4437                          * are we 32 or 64 bit addressed???
4438                          * We need to get the appropriate
4439                          * DMA and set the command options;
4440                          * 64 bit (bit 6) or 32 bit
4441                          * (no bit 6) addressing.
4442                          * while we are at it lets ask for
4443                          * real echo (bit 15)
4444                          */
4445                         echo.options = BIT_15;
4446                         if (CFG_IST(ha, CFG_ENABLE_64BIT_ADDRESSING) &&
4447                             !(CFG_IST(ha, CFG_CTRL_8081))) {
4448                                 echo.options = (uint16_t)
4449                                     (echo.options | BIT_6);
4450                         }
4451 
4452                         /*
4453                          * Set up the DMA mappings for the
4454                          * output and input data buffers.
4455                          * First the output buffer
4456                          */
4457                         if (ql_get_dma_mem(ha, &buffer_xmt,
4458                             (uint32_t)(cmd->pm_data_len + 4),
4459                             LITTLE_ENDIAN_DMA,
4460                             QL_DMA_DATA_ALIGN) != QL_SUCCESS) {
4461                                 EL(ha, "failed, QL_DIAG_ECHO FC_NOMEM\n");
4462                                 rval = FC_NOMEM;
4463                                 break;
4464                         }
4465                         echo.transfer_data_address = buffer_xmt.cookie;
4466 
4467                         /* Next the input buffer */
4468                         if (ql_get_dma_mem(ha, &buffer_rcv,
4469                             (uint32_t)(cmd->pm_data_len + 4),
4470                             LITTLE_ENDIAN_DMA,
4471                             QL_DMA_DATA_ALIGN) != QL_SUCCESS) {
4472                                 /*
4473                                  * since we could not allocate
4474                                  * DMA space for the input
4475                                  * buffer we need to clean up
4476                                  * by freeing the DMA space
4477                                  * we allocated for the output
4478                                  * buffer
4479                                  */
4480                                 ql_free_phys(ha, &buffer_xmt);
4481                                 EL(ha, "failed, QL_DIAG_ECHO FC_NOMEM-2\n");
4482                                 rval = FC_NOMEM;
4483                                 break;
4484                         }
4485                         echo.receive_data_address = buffer_rcv.cookie;
4486 
4487                         /*
4488                          * copy the 4 byte ECHO op code to the
4489                          * allocated DMA space
4490                          */
4491                         ddi_rep_put8(buffer_xmt.acc_handle, (uint8_t *)&opcode,
4492                             (uint8_t *)buffer_xmt.bp, 4, DDI_DEV_AUTOINCR);
4493 
4494                         /*
4495                          * copy the user supplied data to the
4496                          * allocated DMA space
4497                          */
4498                         ddi_rep_put8(buffer_xmt.acc_handle,
4499                             (uint8_t *)cmd->pm_cmd_buf,
4500                             (uint8_t *)buffer_xmt.bp + 4, cmd->pm_cmd_len,
4501                             DDI_DEV_AUTOINCR);
4502 
4503                         /* Shutdown IP. */
4504                         if (pha->flags & IP_INITIALIZED) {
4505                                 (void) ql_shutdown_ip(pha);
4506                         }
4507 
4508                         /* send the echo */
4509                         if (ql_echo(ha, 0, &echo) == QL_SUCCESS) {
4510                                 ddi_rep_put8(buffer_rcv.acc_handle,
4511                                     (uint8_t *)buffer_rcv.bp + 4,
4512                                     (uint8_t *)cmd->pm_stat_buf,
4513                                     cmd->pm_stat_len, DDI_DEV_AUTOINCR);
4514                         } else {
4515                                 EL(ha, "failed, QL_DIAG_ECHO FC_FAILURE\n");
4516                                 rval = FC_FAILURE;
4517                         }
4518 
4519                         /* Restart IP if it was shutdown. */
4520                         if (pha->flags & IP_ENABLED &&
4521                             !(pha->flags & IP_INITIALIZED)) {
4522                                 (void) ql_initialize_ip(pha);
4523                                 ql_isp_rcvbuf(pha);
4524                         }
4525                         /* free up our DMA buffers */
4526                         ql_free_phys(ha, &buffer_xmt);
4527                         ql_free_phys(ha, &buffer_rcv);
4528                         break;
4529                 }
4530                 default:
4531                         EL(ha, "unknown=%xh, FC_PORT_DIAG "
4532                             "FC_INVALID_REQUEST\n", cmd->pm_cmd_flags);
4533                         rval = FC_INVALID_REQUEST;
4534                         break;
4535                 }
4536                 PORTMANAGE_UNLOCK(ha);
4537                 break;
4538         case FC_PORT_LINK_STATE:
4539                 /* Check for name equal to null. */
4540                 for (index = 0; index < 8 && index < cmd->pm_cmd_len;
4541                     index++) {
4542                         if (cmd->pm_cmd_buf[index] != 0) {
4543                                 break;
4544                         }
4545                 }
4546 
4547                 /* If name not null. */
4548                 if (index < 8 && cmd->pm_cmd_len >= 8) {
4549                         /* Locate device queue. */
4550                         tq = NULL;
4551                         for (index = 0; index < DEVICE_HEAD_LIST_SIZE &&
4552                             tq == NULL; index++) {
4553                                 for (link = ha->dev[index].first; link != NULL;
4554                                     link = link->next) {
4555                                         tq = link->base_address;
4556 
4557                                         if (bcmp((void *)&tq->port_name[0],
4558                                             (void *)cmd->pm_cmd_buf, 8) == 0) {
4559                                                 break;
4560                                         } else {
4561                                                 tq = NULL;
4562                                         }
4563                                 }
4564                         }
4565 
4566                         if (tq != NULL && VALID_DEVICE_ID(ha, tq->loop_id)) {
4567                                 cmd->pm_stat_buf[0] = (int8_t)LSB(ha->state);
4568                                 cmd->pm_stat_buf[1] = (int8_t)MSB(ha->state);
4569                         } else {
4570                                 cnt = FC_PORT_SPEED_MASK(ha->state) |
4571                                     FC_STATE_OFFLINE;
4572                                 cmd->pm_stat_buf[0] = (int8_t)LSB(cnt);
4573                                 cmd->pm_stat_buf[1] = (int8_t)MSB(cnt);
4574                         }
4575                 } else {
4576                         cmd->pm_stat_buf[0] = (int8_t)LSB(ha->state);
4577                         cmd->pm_stat_buf[1] = (int8_t)MSB(ha->state);
4578                 }
4579                 break;
4580         case FC_PORT_INITIALIZE:
4581                 if (cmd->pm_cmd_len >= 8) {
4582                         tq = NULL;
4583                         for (index = 0; index < DEVICE_HEAD_LIST_SIZE &&
4584                             tq == NULL; index++) {
4585                                 for (link = ha->dev[index].first; link != NULL;
4586                                     link = link->next) {
4587                                         tq = link->base_address;
4588 
4589                                         if (bcmp((void *)&tq->port_name[0],
4590                                             (void *)cmd->pm_cmd_buf, 8) == 0) {
4591                                                 if (!VALID_DEVICE_ID(ha,
4592                                                     tq->loop_id)) {
4593                                                         tq = NULL;
4594                                                 }
4595                                                 break;
4596                                         } else {
4597                                                 tq = NULL;
4598                                         }
4599                                 }
4600                         }
4601 
4602                         if (tq == NULL || ql_target_reset(ha, tq,
4603                             ha->loop_reset_delay) != QL_SUCCESS) {
4604                                 EL(ha, "failed, FC_PORT_INITIALIZE "
4605                                     "FC_FAILURE\n");
4606                                 rval = FC_FAILURE;
4607                         }
4608                 } else {
4609                         EL(ha, "failed, FC_PORT_INITIALIZE FC_FAILURE-2, "
4610                             "clen=%lxh\n", cmd->pm_cmd_len);
4611 
4612                         rval = FC_FAILURE;
4613                 }
4614                 break;
4615         case FC_PORT_RLS:
4616                 if (cmd->pm_data_len < sizeof (fc_rls_acc_t)) {
4617                         EL(ha, "failed, buffer size passed: %lxh, "
4618                             "req: %lxh\n", cmd->pm_data_len,
4619                             (sizeof (fc_rls_acc_t)));
4620                         rval = FC_FAILURE;
4621                 } else if (LOOP_NOT_READY(pha)) {
4622                         EL(ha, "loop NOT ready\n");
4623                         bzero(cmd->pm_data_buf, cmd->pm_data_len);
4624                 } else if (ql_get_link_status(ha, ha->loop_id,
4625                     cmd->pm_data_len, cmd->pm_data_buf, 0) != QL_SUCCESS) {
4626                         EL(ha, "failed, FC_PORT_RLS FC_FAILURE\n");
4627                         rval = FC_FAILURE;
4628 #ifdef _BIG_ENDIAN
4629                 } else {
4630                         fc_rls_acc_t            *rls;
4631 
4632                         rls = (fc_rls_acc_t *)cmd->pm_data_buf;
4633                         LITTLE_ENDIAN_32(&rls->rls_link_fail);
4634                         LITTLE_ENDIAN_32(&rls->rls_sync_loss);
4635                         LITTLE_ENDIAN_32(&rls->rls_sig_loss);
4636                         LITTLE_ENDIAN_32(&rls->rls_invalid_crc);
4637 #endif /* _BIG_ENDIAN */
4638                 }
4639                 break;
4640         case FC_PORT_GET_NODE_ID:
4641                 if (ql_get_rnid_params(ha, cmd->pm_data_len,
4642                     cmd->pm_data_buf) != QL_SUCCESS) {
4643                         EL(ha, "failed, FC_PORT_GET_NODE_ID FC_FAILURE\n");
4644                         rval = FC_FAILURE;
4645                 }
4646                 break;
4647         case FC_PORT_SET_NODE_ID:
4648                 if (ql_set_rnid_params(ha, cmd->pm_data_len,
4649                     cmd->pm_data_buf) != QL_SUCCESS) {
4650                         EL(ha, "failed, FC_PORT_SET_NODE_ID FC_FAILURE\n");
4651                         rval = FC_FAILURE;
4652                 }
4653                 break;
4654         case FC_PORT_DOWNLOAD_FCODE:
4655                 PORTMANAGE_LOCK(ha);
4656                 if ((CFG_IST(ha, CFG_CTRL_24258081)) == 0) {
4657                         rval = ql_load_flash(ha, (uint8_t *)cmd->pm_data_buf,
4658                             (uint32_t)cmd->pm_data_len);
4659                 } else {
4660                         if (cmd->pm_data_buf[0] == 4 &&
4661                             cmd->pm_data_buf[8] == 0 &&
4662                             cmd->pm_data_buf[9] == 0x10 &&
4663                             cmd->pm_data_buf[10] == 0 &&
4664                             cmd->pm_data_buf[11] == 0) {
4665                                 rval = ql_24xx_load_flash(ha,
4666                                     (uint8_t *)cmd->pm_data_buf,
4667                                     (uint32_t)cmd->pm_data_len,
4668                                     ha->flash_fw_addr << 2);
4669                         } else {
4670                                 rval = ql_24xx_load_flash(ha,
4671                                     (uint8_t *)cmd->pm_data_buf,
4672                                     (uint32_t)cmd->pm_data_len, 0);
4673                         }
4674                 }
4675 
4676                 if (rval != QL_SUCCESS) {
4677                         EL(ha, "failed, FC_PORT_DOWNLOAD_FCODE FC_FAILURE\n");
4678                         rval = FC_FAILURE;
4679                 } else {
4680                         rval = FC_SUCCESS;
4681                 }
4682                 ql_reset_chip(ha);
4683                 set_flags |= ISP_ABORT_NEEDED;
4684                 PORTMANAGE_UNLOCK(ha);
4685                 break;
4686         default:
4687                 EL(ha, "unknown=%xh, FC_BADCMD\n", cmd->pm_cmd_code);
4688                 rval = FC_BADCMD;
4689                 break;
4690         }
4691 
4692         /* Wait for suspension to end. */
4693         ql_awaken_task_daemon(ha, NULL, set_flags, DRIVER_STALL);
4694         timer = 0;
4695 
4696         while (timer++ < 3000 &&
4697             ha->task_daemon_flags & (QL_LOOP_TRANSITION | DRIVER_STALL)) {
4698                 ql_delay(ha, 10000);
4699         }
4700 
4701         ql_restart_queues(ha);
4702 
4703         if (rval != FC_SUCCESS) {
4704                 EL(ha, "failed, rval = %xh\n", rval);
4705         } else {
4706                 /*EMPTY*/
4707                 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
4708         }
4709 
4710         return (rval);
4711 }
4712 
4713 static opaque_t
4714 ql_get_device(opaque_t fca_handle, fc_portid_t d_id)
4715 {
4716         port_id_t               id;
4717         ql_adapter_state_t      *ha;
4718         ql_tgt_t                *tq;
4719 
4720         id.r.rsvd_1 = 0;
4721         id.b24 = d_id.port_id;
4722 
4723         ha = ql_fca_handle_to_state(fca_handle);
4724         if (ha == NULL) {
4725                 QL_PRINT_2(CE_CONT, "failed, no adapter=%ph\n",
4726                     (void *)fca_handle);
4727                 return (NULL);
4728         }
4729         QL_PRINT_3(CE_CONT, "(%d): started, d_id=%xh\n", ha->instance, id.b24);
4730 
4731         tq = ql_d_id_to_queue(ha, id);
4732 
4733         if (tq == NULL) {
4734                 EL(ha, "failed, tq=NULL\n");
4735         } else {
4736                 /*EMPTY*/
4737                 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
4738         }
4739         return (tq);
4740 }
4741 
4742 /* ************************************************************************ */
4743 /*                      FCA Driver Local Support Functions.                 */
4744 /* ************************************************************************ */
4745 
4746 /*
4747  * ql_cmd_setup
4748  *      Verifies proper command.
4749  *
4750  * Input:
4751  *      fca_handle = handle setup by ql_bind_port().
4752  *      pkt = pointer to fc_packet.
4753  *      rval = pointer for return value.
4754  *
4755  * Returns:
4756  *      Adapter state pointer, NULL = failure.
4757  *
4758  * Context:
4759  *      Kernel context.
4760  */
4761 static ql_adapter_state_t *
4762 ql_cmd_setup(opaque_t fca_handle, fc_packet_t *pkt, int *rval)
4763 {
4764         ql_adapter_state_t      *ha, *pha;
4765         ql_srb_t                *sp = (ql_srb_t *)pkt->pkt_fca_private;
4766         ql_tgt_t                *tq;
4767         port_id_t               d_id;
4768 
4769         pkt->pkt_resp_resid = 0;
4770         pkt->pkt_data_resid = 0;
4771 
4772         /* check that the handle is assigned by this FCA */
4773         ha = ql_fca_handle_to_state(fca_handle);
4774         if (ha == NULL) {
4775                 *rval = FC_UNBOUND;
4776                 QL_PRINT_2(CE_CONT, "failed, no adapter=%ph\n",
4777                     (void *)fca_handle);
4778                 return (NULL);
4779         }
4780         pha = ha->pha;
4781 
4782         QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
4783 
4784         if (ddi_in_panic() || pkt->pkt_tran_flags & FC_TRAN_DUMPING) {
4785                 return (ha);
4786         }
4787 
4788         if (!(pha->flags & ONLINE)) {
4789                 pkt->pkt_state = FC_PKT_LOCAL_RJT;
4790                 pkt->pkt_reason = FC_REASON_HW_ERROR;
4791                 *rval = FC_TRANSPORT_ERROR;
4792                 EL(ha, "failed, not online hf=%xh\n", pha->flags);
4793                 return (NULL);
4794         }
4795 
4796         /* Exit on loop down. */
4797         if (CFG_IST(ha, CFG_ENABLE_LINK_DOWN_REPORTING) &&
4798             pha->task_daemon_flags & LOOP_DOWN &&
4799             pha->loop_down_timer <= pha->loop_down_abort_time) {
4800                 pkt->pkt_state = FC_PKT_PORT_OFFLINE;
4801                 pkt->pkt_reason = FC_REASON_NO_CONNECTION;
4802                 *rval = FC_OFFLINE;
4803                 EL(ha, "failed, loop down tdf=%xh\n", pha->task_daemon_flags);
4804                 return (NULL);
4805         }
4806 
4807         if (pkt->pkt_cmd_fhdr.r_ctl == R_CTL_COMMAND &&
4808             pkt->pkt_cmd_fhdr.type == FC_TYPE_SCSI_FCP) {
4809                 tq = (ql_tgt_t *)pkt->pkt_fca_device;
4810                 if ((tq == NULL) || (!VALID_DEVICE_ID(ha, tq->loop_id))) {
4811                         d_id.r.rsvd_1 = 0;
4812                         d_id.b24 = pkt->pkt_cmd_fhdr.d_id;
4813                         tq = ql_d_id_to_queue(ha, d_id);
4814 
4815                         pkt->pkt_fca_device = (opaque_t)tq;
4816                 }
4817 
4818                 if (tq != NULL) {
4819                         DEVICE_QUEUE_LOCK(tq);
4820                         if (tq->flags & (TQF_RSCN_RCVD |
4821                             TQF_NEED_AUTHENTICATION)) {
4822                                 *rval = FC_DEVICE_BUSY;
4823                                 DEVICE_QUEUE_UNLOCK(tq);
4824                                 EL(ha, "failed, busy qf=%xh, d_id=%xh\n",
4825                                     tq->flags, tq->d_id.b24);
4826                                 return (NULL);
4827                         }
4828                         DEVICE_QUEUE_UNLOCK(tq);
4829                 }
4830         }
4831 
4832         /*
4833          * Check DMA pointers.
4834          */
4835         *rval = DDI_SUCCESS;
4836         if (pkt->pkt_cmd_acc != NULL && pkt->pkt_cmdlen) {
4837                 QL_CLEAR_DMA_HANDLE(pkt->pkt_cmd_dma);
4838                 *rval = ddi_check_dma_handle(pkt->pkt_cmd_dma);
4839                 if (*rval == DDI_SUCCESS) {
4840                         *rval = ddi_check_acc_handle(pkt->pkt_cmd_acc);
4841                 }
4842         }
4843 
4844         if (pkt->pkt_resp_acc != NULL && *rval == DDI_SUCCESS &&
4845             pkt->pkt_rsplen != 0) {
4846                 QL_CLEAR_DMA_HANDLE(pkt->pkt_resp_dma);
4847                 *rval = ddi_check_dma_handle(pkt->pkt_resp_dma);
4848                 if (*rval == DDI_SUCCESS) {
4849                         *rval = ddi_check_acc_handle(pkt->pkt_resp_acc);
4850                 }
4851         }
4852 
4853         /*
4854          * Minimum branch conditional; Change it with care.
4855          */
4856         if (((pkt->pkt_data_acc != NULL) & (*rval == DDI_SUCCESS) &
4857             (pkt->pkt_datalen != 0)) != 0) {
4858                 QL_CLEAR_DMA_HANDLE(pkt->pkt_data_dma);
4859                 *rval = ddi_check_dma_handle(pkt->pkt_data_dma);
4860                 if (*rval == DDI_SUCCESS) {
4861                         *rval = ddi_check_acc_handle(pkt->pkt_data_acc);
4862                 }
4863         }
4864 
4865         if (*rval != DDI_SUCCESS) {
4866                 pkt->pkt_state = FC_PKT_TRAN_ERROR;
4867                 pkt->pkt_reason = FC_REASON_DMA_ERROR;
4868 
4869                 /* Do command callback. */
4870                 if (!(pkt->pkt_tran_flags & FC_TRAN_NO_INTR) && pkt->pkt_comp) {
4871                         ql_awaken_task_daemon(ha, sp, 0, 0);
4872                 }
4873                 *rval = FC_BADPACKET;
4874                 EL(ha, "failed, bad DMA pointers\n");
4875                 return (NULL);
4876         }
4877 
4878         if (sp->magic_number != QL_FCA_BRAND) {
4879                 *rval = FC_BADPACKET;
4880                 EL(ha, "failed, magic number=%xh\n", sp->magic_number);
4881                 return (NULL);
4882         }
4883         *rval = FC_SUCCESS;
4884 
4885         QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
4886 
4887         return (ha);
4888 }
4889 
4890 /*
4891  * ql_els_plogi
4892  *      Issue a extended link service port login request.
4893  *
4894  * Input:
4895  *      ha = adapter state pointer.
4896  *      pkt = pointer to fc_packet.
4897  *
4898  * Returns:
4899  *      FC_SUCCESS - the packet was accepted for transport.
4900  *      FC_TRANSPORT_ERROR - a transport error occurred.
4901  *
4902  * Context:
4903  *      Kernel context.
4904  */
4905 static int
4906 ql_els_plogi(ql_adapter_state_t *ha, fc_packet_t *pkt)
4907 {
4908         ql_tgt_t                *tq = NULL;
4909         port_id_t               d_id;
4910         la_els_logi_t           acc;
4911         class_svc_param_t       *class3_param;
4912         int                     ret;
4913         int                     rval = FC_SUCCESS;
4914 
4915         QL_PRINT_3(CE_CONT, "(%d): started, d_id=%xh\n", ha->instance,
4916             pkt->pkt_cmd_fhdr.d_id);
4917 
4918         TASK_DAEMON_LOCK(ha);
4919         if (!(ha->task_daemon_flags & STATE_ONLINE)) {
4920                 TASK_DAEMON_UNLOCK(ha);
4921                 QL_PRINT_3(CE_CONT, "(%d): offline done\n", ha->instance);
4922                 return (FC_OFFLINE);
4923         }
4924         TASK_DAEMON_UNLOCK(ha);
4925 
4926         bzero(&acc, sizeof (acc));
4927         d_id.b24 = pkt->pkt_cmd_fhdr.d_id;
4928 
4929         ret = QL_SUCCESS;
4930 
4931         if (CFG_IST(ha, CFG_CTRL_2425) && ha->topology & QL_N_PORT) {
4932                 /*
4933                  * In p2p topology it sends a PLOGI after determining
4934                  * it has the N_Port login initiative.
4935                  */
4936                 ret = ql_p2p_plogi(ha, pkt);
4937         }
4938         if (ret == QL_CONSUMED) {
4939                 return (ret);
4940         }
4941 
4942         switch (ret = ql_login_port(ha, d_id)) {
4943         case QL_SUCCESS:
4944                 tq = ql_d_id_to_queue(ha, d_id);
4945                 break;
4946 
4947         case QL_LOOP_ID_USED:
4948                 if ((ret = ql_login_port(ha, d_id)) == QL_SUCCESS) {
4949                         tq = ql_d_id_to_queue(ha, d_id);
4950                 }
4951                 break;
4952 
4953         default:
4954                 break;
4955         }
4956 
4957         if (ret != QL_SUCCESS) {
4958                 /*
4959                  * Invalidate this entry so as to seek a fresh loop ID
4960                  * in case firmware reassigns it to something else
4961                  */
4962                 tq = ql_d_id_to_queue(ha, d_id);
4963                 if (tq && (ret != QL_MEMORY_ALLOC_FAILED)) {
4964                         tq->loop_id = PORT_NO_LOOP_ID;
4965                 }
4966         } else if (tq) {
4967                 (void) ql_get_port_database(ha, tq, PDF_ADISC);
4968         }
4969 
4970         if (tq != NULL && VALID_DEVICE_ID(ha, tq->loop_id) &&
4971             (ret != QL_MEMORY_ALLOC_FAILED) && PD_PORT_LOGIN(tq)) {
4972 
4973                 /* Build ACC. */
4974                 acc.ls_code.ls_code = LA_ELS_ACC;
4975                 acc.common_service.fcph_version = 0x2006;
4976                 acc.common_service.cmn_features = 0x8800;
4977                 acc.common_service.rx_bufsize = QL_MAX_FRAME_SIZE(ha);
4978                 acc.common_service.conc_sequences = 0xff;
4979                 acc.common_service.relative_offset = 0x03;
4980                 acc.common_service.e_d_tov = 0x7d0;
4981 
4982                 bcopy((void *)&tq->port_name[0],
4983                     (void *)&acc.nport_ww_name.raw_wwn[0], 8);
4984                 bcopy((void *)&tq->node_name[0],
4985                     (void *)&acc.node_ww_name.raw_wwn[0], 8);
4986 
4987                 class3_param = (class_svc_param_t *)&acc.class_3;
4988                 class3_param->class_valid_svc_opt = 0x8000;
4989                 class3_param->recipient_ctl = tq->class3_recipient_ctl;
4990                 class3_param->rcv_data_size = tq->class3_rcv_data_size;
4991                 class3_param->conc_sequences = tq->class3_conc_sequences;
4992                 class3_param->open_sequences_per_exch =
4993                     tq->class3_open_sequences_per_exch;
4994 
4995                 if ((ql_busy_plogi(ha, pkt, tq) == FC_TRAN_BUSY)) {
4996                         acc.ls_code.ls_code = LA_ELS_RJT;
4997                         pkt->pkt_state = FC_PKT_TRAN_BSY;
4998                         pkt->pkt_reason = FC_REASON_XCHG_BSY;
4999                         EL(ha, "LA_ELS_RJT, FC_REASON_XCHG_BSY\n");
5000                         rval = FC_TRAN_BUSY;
5001                 } else {
5002                         DEVICE_QUEUE_LOCK(tq);
5003                         tq->logout_sent = 0;
5004                         tq->flags &= ~TQF_NEED_AUTHENTICATION;
5005                         if (CFG_IST(ha, CFG_CTRL_242581)) {
5006                                 tq->flags |= TQF_IIDMA_NEEDED;
5007                         }
5008                         DEVICE_QUEUE_UNLOCK(tq);
5009 
5010                         if (CFG_IST(ha, CFG_CTRL_242581)) {
5011                                 TASK_DAEMON_LOCK(ha);
5012                                 ha->task_daemon_flags |= TD_IIDMA_NEEDED;
5013                                 TASK_DAEMON_UNLOCK(ha);
5014                         }
5015 
5016                         pkt->pkt_state = FC_PKT_SUCCESS;
5017                 }
5018         } else {
5019                 /* Build RJT. */
5020                 acc.ls_code.ls_code = LA_ELS_RJT;
5021 
5022                 switch (ret) {
5023                 case QL_FUNCTION_TIMEOUT:
5024                         pkt->pkt_state = FC_PKT_TIMEOUT;
5025                         pkt->pkt_reason = FC_REASON_HW_ERROR;
5026                         break;
5027 
5028                 case QL_MEMORY_ALLOC_FAILED:
5029                         pkt->pkt_state = FC_PKT_LOCAL_BSY;
5030                         pkt->pkt_reason = FC_REASON_NOMEM;
5031                         rval = FC_TRAN_BUSY;
5032                         break;
5033 
5034                 case QL_FABRIC_NOT_INITIALIZED:
5035                         pkt->pkt_state = FC_PKT_FABRIC_BSY;
5036                         pkt->pkt_reason = FC_REASON_NO_CONNECTION;
5037                         rval = FC_TRAN_BUSY;
5038                         break;
5039 
5040                 default:
5041                         pkt->pkt_state = FC_PKT_TRAN_ERROR;
5042                         pkt->pkt_reason = FC_REASON_NO_CONNECTION;
5043                         break;
5044                 }
5045 
5046                 EL(ha, "Plogi unsuccess for %xh state %xh reason %xh "
5047                     "ret %xh rval %xh\n", d_id.b24, pkt->pkt_state,
5048                     pkt->pkt_reason, ret, rval);
5049         }
5050 
5051         if (tq != NULL) {
5052                 DEVICE_QUEUE_LOCK(tq);
5053                 tq->flags &= ~(TQF_PLOGI_PROGRS | TQF_QUEUE_SUSPENDED);
5054                 if (rval == FC_TRAN_BUSY) {
5055                         if (tq->d_id.b24 != BROADCAST_ADDR) {
5056                                 tq->flags |= TQF_NEED_AUTHENTICATION;
5057                         }
5058                 }
5059                 DEVICE_QUEUE_UNLOCK(tq);
5060         }
5061 
5062         ddi_rep_put8(pkt->pkt_resp_acc, (uint8_t *)&acc,
5063             (uint8_t *)pkt->pkt_resp, sizeof (acc), DDI_DEV_AUTOINCR);
5064 
5065         if (rval != FC_SUCCESS) {
5066                 EL(ha, "failed, rval = %xh\n", rval);
5067         } else {
5068                 /*EMPTY*/
5069                 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
5070         }
5071         return (rval);
5072 }
5073 
5074 /*
5075  * ql_p2p_plogi
5076  *      Start an extended link service port login request using
5077  *      an ELS Passthru iocb.
5078  *
5079  * Input:
5080  *      ha = adapter state pointer.
5081  *      pkt = pointer to fc_packet.
5082  *
5083  * Returns:
5084  *      QL_CONSUMMED - the iocb was queued for transport.
5085  *
5086  * Context:
5087  *      Kernel context.
5088  */
5089 static int
5090 ql_p2p_plogi(ql_adapter_state_t *ha, fc_packet_t *pkt)
5091 {
5092         uint16_t        id;
5093         ql_tgt_t        tmp;
5094         ql_tgt_t        *tq = &tmp;
5095         int             rval;
5096         port_id_t       d_id;
5097         ql_srb_t        *sp = (ql_srb_t *)pkt->pkt_fca_private;
5098 
5099         tq->d_id.b.al_pa = 0;
5100         tq->d_id.b.area = 0;
5101         tq->d_id.b.domain = 0;
5102 
5103         /*
5104          * Verify that the port database hasn't moved beneath our feet by
5105          * switching to the appropriate n_port_handle if necessary.  This is
5106          * less unplesant than the error recovery if the wrong one is used.
5107          */
5108         for (id = 0; id <= LAST_LOCAL_LOOP_ID; id++) {
5109                 tq->loop_id = id;
5110                 rval = ql_get_port_database(ha, tq, PDF_NONE);
5111                 EL(ha, "rval=%xh\n", rval);
5112                 /* check all the ones not logged in for possible use */
5113                 if (rval == QL_NOT_LOGGED_IN) {
5114                         if (tq->master_state == PD_STATE_PLOGI_PENDING) {
5115                                 ha->n_port->n_port_handle = tq->loop_id;
5116                                 EL(ha, "n_port_handle =%xh, master state=%x\n",
5117                                     tq->loop_id, tq->master_state);
5118                                 break;
5119                         }
5120                         /*
5121                          * Use a 'port unavailable' entry only
5122                          * if we used it before.
5123                          */
5124                         if (tq->master_state == PD_STATE_PORT_UNAVAILABLE) {
5125                                 /* if the port_id matches, reuse it */
5126                                 if (pkt->pkt_cmd_fhdr.d_id == tq->d_id.b24) {
5127                                         EL(ha, "n_port_handle =%xh,"
5128                                             "master state=%xh\n",
5129                                             tq->loop_id, tq->master_state);
5130                                         break;
5131                                 } else if (tq->loop_id ==
5132                                     ha->n_port->n_port_handle) {
5133                                     // avoid a lint error
5134                                         uint16_t *hndl;
5135                                         uint16_t val;
5136 
5137                                         hndl = &ha->n_port->n_port_handle;
5138                                         val = *hndl;
5139                                         val++;
5140                                         val++;
5141                                         *hndl = val;
5142                                 }
5143                         EL(ha, "rval=%xh, id=%d, n_port_handle =%xh, "
5144                             "master state=%x\n", rval, id, tq->loop_id,
5145                             tq->master_state);
5146                         }
5147 
5148                 }
5149                 if (rval == QL_SUCCESS) {
5150                         if ((tq->flags & TQF_INITIATOR_DEVICE) == 0) {
5151                                 ha->n_port->n_port_handle = tq->loop_id;
5152                                 EL(ha, "n_port_handle =%xh, master state=%x\n",
5153                                     tq->loop_id, tq->master_state);
5154                                 break;
5155                         }
5156                         EL(ha, "rval=%xh, id=%d, n_port_handle =%xh, "
5157                             "master state=%x\n", rval, id, tq->loop_id,
5158                             tq->master_state);
5159                 }
5160         }
5161         (void) ddi_dma_sync(pkt->pkt_cmd_dma, 0, 0, DDI_DMA_SYNC_FORDEV);
5162 
5163         d_id.b24 = pkt->pkt_cmd_fhdr.d_id;
5164         tq = ql_d_id_to_queue(ha, d_id);
5165         ql_timeout_insert(ha, tq, sp);
5166         ql_start_iocb(ha, sp);
5167 
5168         return (QL_CONSUMED);
5169 }
5170 
5171 
5172 /*
5173  * ql_els_flogi
5174  *      Issue a extended link service fabric login request.
5175  *
5176  * Input:
5177  *      ha = adapter state pointer.
5178  *      pkt = pointer to fc_packet.
5179  *
5180  * Returns:
5181  *      FC_SUCCESS - the packet was accepted for transport.
5182  *      FC_TRANSPORT_ERROR - a transport error occurred.
5183  *
5184  * Context:
5185  *      Kernel context.
5186  */
5187 static int
5188 ql_els_flogi(ql_adapter_state_t *ha, fc_packet_t *pkt)
5189 {
5190         ql_tgt_t                *tq = NULL;
5191         port_id_t               d_id;
5192         la_els_logi_t           acc;
5193         class_svc_param_t       *class3_param;
5194         int                     rval = FC_SUCCESS;
5195         int                     accept = 0;
5196 
5197         QL_PRINT_3(CE_CONT, "(%d): started, d_id=%xh\n", ha->instance,
5198             pkt->pkt_cmd_fhdr.d_id);
5199 
5200         bzero(&acc, sizeof (acc));
5201         d_id.b24 = pkt->pkt_cmd_fhdr.d_id;
5202 
5203         if (CFG_IST(ha, CFG_CTRL_2425) && ha->topology & QL_N_PORT) {
5204                 /*
5205                  * d_id of zero in a FLOGI accept response in a point to point
5206                  * topology triggers evaluation of N Port login initiative.
5207                  */
5208                 pkt->pkt_resp_fhdr.d_id = 0;
5209                 /*
5210                  * An N_Port already logged in with the firmware
5211                  * will have the only database entry.
5212                  */
5213                 if (LOCAL_LOOP_ID(ha->n_port->n_port_handle)) {
5214                         tq = ql_loop_id_to_queue(ha, ha->n_port->n_port_handle);
5215                 }
5216 
5217                 if (tq != NULL) {
5218                         /*
5219                          * If the target port has initiative send
5220                          * up a PLOGI about the new device.
5221                          */
5222                         if ((ql_wwn_cmp(ha, (la_wwn_t *)&tq->port_name[0],
5223                             (la_wwn_t *)(CFG_IST(ha, CFG_CTRL_2425) ?
5224                             &ha->init_ctrl_blk.cb24.port_name[0] :
5225                             &ha->init_ctrl_blk.cb.port_name[0])) == 1)) {
5226                                 ha->send_plogi_timer = 3;
5227                         } else {
5228                                 ha->send_plogi_timer = 0;
5229                         }
5230                         pkt->pkt_resp_fhdr.s_id = tq->d_id.b24;
5231                 } else {
5232                         /*
5233                          * An N_Port not logged in with the firmware will not
5234                          * have a database entry.  We accept anyway and rely
5235                          * on a PLOGI from the upper layers to set the d_id
5236                          * and s_id.
5237                          */
5238                         accept = 1;
5239                 }
5240         } else {
5241                 tq = ql_d_id_to_queue(ha, d_id);
5242         }
5243         if ((tq != NULL) || (accept != NULL)) {
5244                 /* Build ACC. */
5245                 pkt->pkt_state = FC_PKT_SUCCESS;
5246                 class3_param = (class_svc_param_t *)&acc.class_3;
5247 
5248                 acc.ls_code.ls_code = LA_ELS_ACC;
5249                 acc.common_service.fcph_version = 0x2006;
5250                 if (ha->topology & QL_N_PORT) {
5251                         /* clear F_Port indicator */
5252                         acc.common_service.cmn_features = 0x0800;
5253                 } else {
5254                         acc.common_service.cmn_features = 0x1b00;
5255                 }
5256                 CFG_IST(ha, CFG_CTRL_24258081) ?
5257                     (acc.common_service.rx_bufsize = CHAR_TO_SHORT(
5258                     ha->init_ctrl_blk.cb24.max_frame_length[0],
5259                     ha->init_ctrl_blk.cb24.max_frame_length[1])) :
5260                     (acc.common_service.rx_bufsize = CHAR_TO_SHORT(
5261                     ha->init_ctrl_blk.cb.max_frame_length[0],
5262                     ha->init_ctrl_blk.cb.max_frame_length[1]));
5263                 acc.common_service.conc_sequences = 0xff;
5264                 acc.common_service.relative_offset = 0x03;
5265                 acc.common_service.e_d_tov = 0x7d0;
5266                 if (accept) {
5267                         /* Use the saved N_Port WWNN and WWPN */
5268                         if (ha->n_port != NULL) {
5269                                 bcopy((void *)&ha->n_port->port_name[0],
5270                                     (void *)&acc.nport_ww_name.raw_wwn[0], 8);
5271                                 bcopy((void *)&ha->n_port->node_name[0],
5272                                     (void *)&acc.node_ww_name.raw_wwn[0], 8);
5273                                 /* mark service options invalid */
5274                                 class3_param->class_valid_svc_opt = 0x0800;
5275                         } else {
5276                                 EL(ha, "ha->n_port is NULL\n");
5277                                 /* Build RJT. */
5278                                 acc.ls_code.ls_code = LA_ELS_RJT;
5279 
5280                                 pkt->pkt_state = FC_PKT_TRAN_ERROR;
5281                                 pkt->pkt_reason = FC_REASON_NO_CONNECTION;
5282                         }
5283                 } else {
5284                         bcopy((void *)&tq->port_name[0],
5285                             (void *)&acc.nport_ww_name.raw_wwn[0], 8);
5286                         bcopy((void *)&tq->node_name[0],
5287                             (void *)&acc.node_ww_name.raw_wwn[0], 8);
5288 
5289                         class3_param = (class_svc_param_t *)&acc.class_3;
5290                         class3_param->class_valid_svc_opt = 0x8800;
5291                         class3_param->recipient_ctl = tq->class3_recipient_ctl;
5292                         class3_param->rcv_data_size = tq->class3_rcv_data_size;
5293                         class3_param->conc_sequences =
5294                             tq->class3_conc_sequences;
5295                         class3_param->open_sequences_per_exch =
5296                             tq->class3_open_sequences_per_exch;
5297                 }
5298         } else {
5299                 /* Build RJT. */
5300                 acc.ls_code.ls_code = LA_ELS_RJT;
5301 
5302                 pkt->pkt_state = FC_PKT_TRAN_ERROR;
5303                 pkt->pkt_reason = FC_REASON_NO_CONNECTION;
5304                 EL(ha, "LA_ELS_RJT, FC_REASON_NO_CONNECTION\n");
5305         }
5306 
5307         ddi_rep_put8(pkt->pkt_resp_acc, (uint8_t *)&acc,
5308             (uint8_t *)pkt->pkt_resp, sizeof (acc), DDI_DEV_AUTOINCR);
5309 
5310         if (rval != FC_SUCCESS) {
5311                 EL(ha, "failed, rval = %xh\n", rval);
5312         } else {
5313                 /*EMPTY*/
5314                 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
5315         }
5316         return (rval);
5317 }
5318 
5319 /*
5320  * ql_els_logo
5321  *      Issue a extended link service logout request.
5322  *
5323  * Input:
5324  *      ha = adapter state pointer.
5325  *      pkt = pointer to fc_packet.
5326  *
5327  * Returns:
5328  *      FC_SUCCESS - the packet was accepted for transport.
5329  *      FC_TRANSPORT_ERROR - a transport error occurred.
5330  *
5331  * Context:
5332  *      Kernel context.
5333  */
5334 static int
5335 ql_els_logo(ql_adapter_state_t *ha, fc_packet_t *pkt)
5336 {
5337         port_id_t       d_id;
5338         ql_tgt_t        *tq;
5339         la_els_logo_t   acc;
5340         int             rval = FC_SUCCESS;
5341 
5342         QL_PRINT_3(CE_CONT, "(%d): started, d_id=%xh\n", ha->instance,
5343             pkt->pkt_cmd_fhdr.d_id);
5344 
5345         bzero(&acc, sizeof (acc));
5346         d_id.b24 = pkt->pkt_cmd_fhdr.d_id;
5347 
5348         tq = ql_d_id_to_queue(ha, d_id);
5349         if (tq) {
5350                 DEVICE_QUEUE_LOCK(tq);
5351                 if (tq->d_id.b24 == BROADCAST_ADDR) {
5352                         DEVICE_QUEUE_UNLOCK(tq);
5353                         return (FC_SUCCESS);
5354                 }
5355 
5356                 tq->flags |= TQF_NEED_AUTHENTICATION;
5357 
5358                 do {
5359                         DEVICE_QUEUE_UNLOCK(tq);
5360                         (void) ql_abort_device(ha, tq, 1);
5361 
5362                         /*
5363                          * Wait for commands to drain in F/W (doesn't
5364                          * take more than a few milliseconds)
5365                          */
5366                         ql_delay(ha, 10000);
5367 
5368                         DEVICE_QUEUE_LOCK(tq);
5369                 } while (tq->outcnt);
5370 
5371                 DEVICE_QUEUE_UNLOCK(tq);
5372         }
5373 
5374         if (ql_logout_port(ha, d_id) == QL_SUCCESS) {
5375                 /* Build ACC. */
5376                 acc.ls_code.ls_code = LA_ELS_ACC;
5377 
5378                 pkt->pkt_state = FC_PKT_SUCCESS;
5379         } else {
5380                 /* Build RJT. */
5381                 acc.ls_code.ls_code = LA_ELS_RJT;
5382 
5383                 pkt->pkt_state = FC_PKT_TRAN_ERROR;
5384                 pkt->pkt_reason = FC_REASON_NO_CONNECTION;
5385                 EL(ha, "LA_ELS_RJT, FC_REASON_NO_CONNECTION\n");
5386         }
5387 
5388         ddi_rep_put8(pkt->pkt_resp_acc, (uint8_t *)&acc,
5389             (uint8_t *)pkt->pkt_resp, sizeof (acc), DDI_DEV_AUTOINCR);
5390 
5391         if (rval != FC_SUCCESS) {
5392                 EL(ha, "failed, rval = %xh\n", rval);
5393         } else {
5394                 /*EMPTY*/
5395                 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
5396         }
5397         return (rval);
5398 }
5399 
5400 /*
5401  * ql_els_prli
5402  *      Issue a extended link service process login request.
5403  *
5404  * Input:
5405  *      ha = adapter state pointer.
5406  *      pkt = pointer to fc_packet.
5407  *
5408  * Returns:
5409  *      FC_SUCCESS - the packet was accepted for transport.
5410  *      FC_TRANSPORT_ERROR - a transport error occurred.
5411  *
5412  * Context:
5413  *      Kernel context.
5414  */
5415 static int
5416 ql_els_prli(ql_adapter_state_t *ha, fc_packet_t *pkt)
5417 {
5418         ql_tgt_t                *tq;
5419         port_id_t               d_id;
5420         la_els_prli_t           acc;
5421         prli_svc_param_t        *param;
5422         ql_srb_t                *sp = (ql_srb_t *)pkt->pkt_fca_private;
5423         int                     rval = FC_SUCCESS;
5424 
5425         QL_PRINT_3(CE_CONT, "(%d): started, d_id=%xh\n", ha->instance,
5426             pkt->pkt_cmd_fhdr.d_id);
5427 
5428         d_id.b24 = pkt->pkt_cmd_fhdr.d_id;
5429 
5430         tq = ql_d_id_to_queue(ha, d_id);
5431         if (tq != NULL) {
5432                 (void) ql_get_port_database(ha, tq, PDF_NONE);
5433 
5434                 if ((ha->topology & QL_N_PORT) &&
5435                     (tq->master_state == PD_STATE_PLOGI_COMPLETED)) {
5436                         ql_timeout_insert(ha, tq, sp);
5437                         ql_start_iocb(ha, sp);
5438                         rval = QL_CONSUMED;
5439                 } else {
5440                         /* Build ACC. */
5441                         bzero(&acc, sizeof (acc));
5442                         acc.ls_code = LA_ELS_ACC;
5443                         acc.page_length = 0x10;
5444                         acc.payload_length = tq->prli_payload_length;
5445 
5446                         param = (prli_svc_param_t *)&acc.service_params[0];
5447                         param->type = 0x08;
5448                         param->rsvd = 0x00;
5449                         param->process_assoc_flags = tq->prli_svc_param_word_0;
5450                         param->process_flags = tq->prli_svc_param_word_3;
5451 
5452                         ddi_rep_put8(pkt->pkt_resp_acc, (uint8_t *)&acc,
5453                             (uint8_t *)pkt->pkt_resp, sizeof (acc),
5454                             DDI_DEV_AUTOINCR);
5455 
5456                         pkt->pkt_state = FC_PKT_SUCCESS;
5457                 }
5458         } else {
5459                 la_els_rjt_t rjt;
5460 
5461                 /* Build RJT. */
5462                 bzero(&rjt, sizeof (rjt));
5463                 rjt.ls_code.ls_code = LA_ELS_RJT;
5464 
5465                 ddi_rep_put8(pkt->pkt_resp_acc, (uint8_t *)&rjt,
5466                     (uint8_t *)pkt->pkt_resp, sizeof (rjt), DDI_DEV_AUTOINCR);
5467 
5468                 pkt->pkt_state = FC_PKT_TRAN_ERROR;
5469                 pkt->pkt_reason = FC_REASON_NO_CONNECTION;
5470                 EL(ha, "LA_ELS_RJT, FC_REASON_NO_CONNECTION\n");
5471         }
5472 
5473         if ((rval != FC_SUCCESS) && (rval != QL_CONSUMED)) {
5474                 EL(ha, "failed, rval = %xh\n", rval);
5475         } else {
5476                 /*EMPTY*/
5477                 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
5478         }
5479         return (rval);
5480 }
5481 
5482 /*
5483  * ql_els_prlo
5484  *      Issue a extended link service process logout request.
5485  *
5486  * Input:
5487  *      ha = adapter state pointer.
5488  *      pkt = pointer to fc_packet.
5489  *
5490  * Returns:
5491  *      FC_SUCCESS - the packet was accepted for transport.
5492  *      FC_TRANSPORT_ERROR - a transport error occurred.
5493  *
5494  * Context:
5495  *      Kernel context.
5496  */
5497 /* ARGSUSED */
5498 static int
5499 ql_els_prlo(ql_adapter_state_t *ha, fc_packet_t *pkt)
5500 {
5501         la_els_prli_t   acc;
5502         int             rval = FC_SUCCESS;
5503 
5504         QL_PRINT_3(CE_CONT, "(%d): started, d_id=%xh\n", ha->instance,
5505             pkt->pkt_cmd_fhdr.d_id);
5506 
5507         /* Build ACC. */
5508         ddi_rep_get8(pkt->pkt_cmd_acc, (uint8_t *)&acc,
5509             (uint8_t *)pkt->pkt_cmd, sizeof (acc), DDI_DEV_AUTOINCR);
5510 
5511         acc.ls_code = LA_ELS_ACC;
5512         acc.service_params[2] = 1;
5513 
5514         ddi_rep_put8(pkt->pkt_resp_acc, (uint8_t *)&acc,
5515             (uint8_t *)pkt->pkt_resp, sizeof (acc), DDI_DEV_AUTOINCR);
5516 
5517         pkt->pkt_state = FC_PKT_SUCCESS;
5518 
5519         if (rval != FC_SUCCESS) {
5520                 EL(ha, "failed, rval = %xh\n", rval);
5521         } else {
5522                 /*EMPTY*/
5523                 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
5524         }
5525         return (rval);
5526 }
5527 
5528 /*
5529  * ql_els_adisc
5530  *      Issue a extended link service address discovery request.
5531  *
5532  * Input:
5533  *      ha = adapter state pointer.
5534  *      pkt = pointer to fc_packet.
5535  *
5536  * Returns:
5537  *      FC_SUCCESS - the packet was accepted for transport.
5538  *      FC_TRANSPORT_ERROR - a transport error occurred.
5539  *
5540  * Context:
5541  *      Kernel context.
5542  */
5543 static int
5544 ql_els_adisc(ql_adapter_state_t *ha, fc_packet_t *pkt)
5545 {
5546         ql_dev_id_list_t        *list;
5547         uint32_t                list_size;
5548         ql_link_t               *link;
5549         ql_tgt_t                *tq;
5550         ql_lun_t                *lq;
5551         port_id_t               d_id;
5552         la_els_adisc_t          acc;
5553         uint16_t                index, loop_id;
5554         ql_mbx_data_t           mr;
5555         int                     rval = FC_SUCCESS;
5556 
5557         QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
5558 
5559         bzero(&acc, sizeof (acc));
5560         d_id.b24 = pkt->pkt_cmd_fhdr.d_id;
5561 
5562         /*
5563          * MBC_GET_PORT_DATABASE causes ADISC to go out to
5564          * the device from the firmware
5565          */
5566         index = ql_alpa_to_index[d_id.b.al_pa];
5567         tq = NULL;
5568         for (link = ha->dev[index].first; link != NULL; link = link->next) {
5569                 tq = link->base_address;
5570                 if (tq->d_id.b24 == d_id.b24) {
5571                         break;
5572                 } else {
5573                         tq = NULL;
5574                 }
5575         }
5576 
5577         if ((tq != NULL) && (!VALID_DEVICE_ID(ha, tq->loop_id))) {
5578                 list_size = sizeof (ql_dev_id_list_t) * DEVICE_LIST_ENTRIES;
5579                 list = (ql_dev_id_list_t *)kmem_zalloc(list_size, KM_SLEEP);
5580 
5581                 if (list != NULL &&
5582                     ql_get_id_list(ha, (caddr_t)list, list_size, &mr) ==
5583                     QL_SUCCESS) {
5584 
5585                         for (index = 0; index < mr.mb[1]; index++) {
5586                                 ql_dev_list(ha, list, index, &d_id, &loop_id);
5587 
5588                                 if (tq->d_id.b24 == d_id.b24) {
5589                                         tq->loop_id = loop_id;
5590                                         break;
5591                                 }
5592                         }
5593                 } else {
5594                         cmn_err(CE_WARN, "!%s(%d) didn't get list for %xh",
5595                             QL_NAME, ha->instance, d_id.b24);
5596                         tq = NULL;
5597                 }
5598                 if ((tq != NULL) && (!VALID_DEVICE_ID(ha, tq->loop_id))) {
5599                         cmn_err(CE_WARN, "!%s(%d) no loop_id for adisc %xh",
5600                             QL_NAME, ha->instance, tq->d_id.b24);
5601                         tq = NULL;
5602                 }
5603 
5604                 if (list != NULL) {
5605                         kmem_free(list, list_size);
5606                 }
5607         }
5608 
5609         if ((tq != NULL) && (VALID_DEVICE_ID(ha, tq->loop_id)) &&
5610             ql_get_port_database(ha, tq, PDF_ADISC) == QL_SUCCESS) {
5611 
5612                 /* Build ACC. */
5613 
5614                 DEVICE_QUEUE_LOCK(tq);
5615                 tq->flags &= ~TQF_NEED_AUTHENTICATION;
5616                 if (tq->prli_svc_param_word_3 & PRLI_W3_RETRY) {
5617                         for (link = tq->lun_queues.first; link != NULL;
5618                             link = link->next) {
5619                                 lq = link->base_address;
5620 
5621                                 if (lq->cmd.first != NULL) {
5622                                         ql_next(ha, lq);
5623                                         DEVICE_QUEUE_LOCK(tq);
5624                                 }
5625                         }
5626                 }
5627                 DEVICE_QUEUE_UNLOCK(tq);
5628 
5629                 acc.ls_code.ls_code = LA_ELS_ACC;
5630                 acc.hard_addr.hard_addr = tq->hard_addr.b24;
5631 
5632                 bcopy((void *)&tq->port_name[0],
5633                     (void *)&acc.port_wwn.raw_wwn[0], 8);
5634                 bcopy((void *)&tq->node_name[0],
5635                     (void *)&acc.node_wwn.raw_wwn[0], 8);
5636 
5637                 acc.nport_id.port_id = tq->d_id.b24;
5638 
5639                 pkt->pkt_state = FC_PKT_SUCCESS;
5640         } else {
5641                 /* Build RJT. */
5642                 acc.ls_code.ls_code = LA_ELS_RJT;
5643 
5644                 pkt->pkt_state = FC_PKT_TRAN_ERROR;
5645                 pkt->pkt_reason = FC_REASON_NO_CONNECTION;
5646                 EL(ha, "LA_ELS_RJT, FC_REASON_NO_CONNECTION\n");
5647         }
5648 
5649         ddi_rep_put8(pkt->pkt_resp_acc, (uint8_t *)&acc,
5650             (uint8_t *)pkt->pkt_resp, sizeof (acc), DDI_DEV_AUTOINCR);
5651 
5652         if (rval != FC_SUCCESS) {
5653                 EL(ha, "failed, rval = %xh\n", rval);
5654         } else {
5655                 /*EMPTY*/
5656                 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
5657         }
5658         return (rval);
5659 }
5660 
5661 /*
5662  * ql_els_linit
5663  *      Issue a extended link service loop initialize request.
5664  *
5665  * Input:
5666  *      ha = adapter state pointer.
5667  *      pkt = pointer to fc_packet.
5668  *
5669  * Returns:
5670  *      FC_SUCCESS - the packet was accepted for transport.
5671  *      FC_TRANSPORT_ERROR - a transport error occurred.
5672  *
5673  * Context:
5674  *      Kernel context.
5675  */
5676 static int
5677 ql_els_linit(ql_adapter_state_t *ha, fc_packet_t *pkt)
5678 {
5679         ddi_dma_cookie_t        *cp;
5680         uint32_t                cnt;
5681         conv_num_t              n;
5682         port_id_t               d_id;
5683         int                     rval = FC_SUCCESS;
5684 
5685         QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
5686 
5687         d_id.b24 = pkt->pkt_cmd_fhdr.d_id;
5688         if (ha->topology & QL_SNS_CONNECTION) {
5689                 fc_linit_req_t els;
5690                 lfa_cmd_t lfa;
5691 
5692                 ddi_rep_get8(pkt->pkt_cmd_acc, (uint8_t *)&els,
5693                     (uint8_t *)pkt->pkt_cmd, sizeof (els), DDI_DEV_AUTOINCR);
5694 
5695                 /* Setup LFA mailbox command data. */
5696                 bzero((void *)&lfa, sizeof (lfa_cmd_t));
5697 
5698                 lfa.resp_buffer_length[0] = 4;
5699 
5700                 cp = pkt->pkt_resp_cookie;
5701                 if (CFG_IST(ha, CFG_ENABLE_64BIT_ADDRESSING)) {
5702                         n.size64 = (uint64_t)cp->dmac_laddress;
5703                         LITTLE_ENDIAN_64(&n.size64);
5704                 } else {
5705                         n.size32[0] = LSD(cp->dmac_laddress);
5706                         LITTLE_ENDIAN_32(&n.size32[0]);
5707                         n.size32[1] = MSD(cp->dmac_laddress);
5708                         LITTLE_ENDIAN_32(&n.size32[1]);
5709                 }
5710 
5711                 /* Set buffer address. */
5712                 for (cnt = 0; cnt < 8; cnt++) {
5713                         lfa.resp_buffer_address[cnt] = n.size8[cnt];
5714                 }
5715 
5716                 lfa.subcommand_length[0] = 4;
5717                 n.size32[0] = d_id.b24;
5718                 LITTLE_ENDIAN_32(&n.size32[0]);
5719                 lfa.addr[0] = n.size8[0];
5720                 lfa.addr[1] = n.size8[1];
5721                 lfa.addr[2] = n.size8[2];
5722                 lfa.subcommand[1] = 0x70;
5723                 lfa.payload[2] = els.func;
5724                 lfa.payload[4] = els.lip_b3;
5725                 lfa.payload[5] = els.lip_b4;
5726 
5727                 if (ql_send_lfa(ha, &lfa) != QL_SUCCESS) {
5728                         pkt->pkt_state = FC_PKT_TRAN_ERROR;
5729                 } else {
5730                         pkt->pkt_state = FC_PKT_SUCCESS;
5731                 }
5732         } else {
5733                 fc_linit_resp_t rjt;
5734 
5735                 /* Build RJT. */
5736                 bzero(&rjt, sizeof (rjt));
5737                 rjt.ls_code.ls_code = LA_ELS_RJT;
5738 
5739                 ddi_rep_put8(pkt->pkt_resp_acc, (uint8_t *)&rjt,
5740                     (uint8_t *)pkt->pkt_resp, sizeof (rjt), DDI_DEV_AUTOINCR);
5741 
5742                 pkt->pkt_state = FC_PKT_TRAN_ERROR;
5743                 pkt->pkt_reason = FC_REASON_NO_CONNECTION;
5744                 EL(ha, "LA_ELS_RJT, FC_REASON_NO_CONNECTION\n");
5745         }
5746 
5747         if (rval != FC_SUCCESS) {
5748                 EL(ha, "failed, rval = %xh\n", rval);
5749         } else {
5750                 /*EMPTY*/
5751                 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
5752         }
5753         return (rval);
5754 }
5755 
5756 /*
5757  * ql_els_lpc
5758  *      Issue a extended link service loop control request.
5759  *
5760  * Input:
5761  *      ha = adapter state pointer.
5762  *      pkt = pointer to fc_packet.
5763  *
5764  * Returns:
5765  *      FC_SUCCESS - the packet was accepted for transport.
5766  *      FC_TRANSPORT_ERROR - a transport error occurred.
5767  *
5768  * Context:
5769  *      Kernel context.
5770  */
5771 static int
5772 ql_els_lpc(ql_adapter_state_t *ha, fc_packet_t *pkt)
5773 {
5774         ddi_dma_cookie_t        *cp;
5775         uint32_t                cnt;
5776         conv_num_t              n;
5777         port_id_t               d_id;
5778         int                     rval = FC_SUCCESS;
5779 
5780         QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
5781 
5782         d_id.b24 = pkt->pkt_cmd_fhdr.d_id;
5783         if (ha->topology & QL_SNS_CONNECTION) {
5784                 ql_lpc_t els;
5785                 lfa_cmd_t lfa;
5786 
5787                 ddi_rep_get8(pkt->pkt_cmd_acc, (uint8_t *)&els,
5788                     (uint8_t *)pkt->pkt_cmd, sizeof (els), DDI_DEV_AUTOINCR);
5789 
5790                 /* Setup LFA mailbox command data. */
5791                 bzero((void *)&lfa, sizeof (lfa_cmd_t));
5792 
5793                 lfa.resp_buffer_length[0] = 4;
5794 
5795                 cp = pkt->pkt_resp_cookie;
5796                 if (CFG_IST(ha, CFG_ENABLE_64BIT_ADDRESSING)) {
5797                         n.size64 = (uint64_t)(cp->dmac_laddress);
5798                         LITTLE_ENDIAN_64(&n.size64);
5799                 } else {
5800                         n.size32[0] = cp->dmac_address;
5801                         LITTLE_ENDIAN_32(&n.size32[0]);
5802                         n.size32[1] = 0;
5803                 }
5804 
5805                 /* Set buffer address. */
5806                 for (cnt = 0; cnt < 8; cnt++) {
5807                         lfa.resp_buffer_address[cnt] = n.size8[cnt];
5808                 }
5809 
5810                 lfa.subcommand_length[0] = 20;
5811                 n.size32[0] = d_id.b24;
5812                 LITTLE_ENDIAN_32(&n.size32[0]);
5813                 lfa.addr[0] = n.size8[0];
5814                 lfa.addr[1] = n.size8[1];
5815                 lfa.addr[2] = n.size8[2];
5816                 lfa.subcommand[1] = 0x71;
5817                 lfa.payload[4] = els.port_control;
5818                 bcopy((void *)&els.lpb[0], (void *)&lfa.payload[6], 32);
5819 
5820                 if (ql_send_lfa(ha, &lfa) != QL_SUCCESS) {
5821                         pkt->pkt_state = FC_PKT_TRAN_ERROR;
5822                 } else {
5823                         pkt->pkt_state = FC_PKT_SUCCESS;
5824                 }
5825         } else {
5826                 ql_lpc_resp_t rjt;
5827 
5828                 /* Build RJT. */
5829                 bzero(&rjt, sizeof (rjt));
5830                 rjt.ls_code.ls_code = LA_ELS_RJT;
5831 
5832                 ddi_rep_put8(pkt->pkt_resp_acc, (uint8_t *)&rjt,
5833                     (uint8_t *)pkt->pkt_resp, sizeof (rjt), DDI_DEV_AUTOINCR);
5834 
5835                 pkt->pkt_state = FC_PKT_TRAN_ERROR;
5836                 pkt->pkt_reason = FC_REASON_NO_CONNECTION;
5837                 EL(ha, "LA_ELS_RJT, FC_REASON_NO_CONNECTION\n");
5838         }
5839 
5840         if (rval != FC_SUCCESS) {
5841                 EL(ha, "failed, rval = %xh\n", rval);
5842         } else {
5843                 /*EMPTY*/
5844                 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
5845         }
5846         return (rval);
5847 }
5848 
5849 /*
5850  * ql_els_lsts
5851  *      Issue a extended link service loop status request.
5852  *
5853  * Input:
5854  *      ha = adapter state pointer.
5855  *      pkt = pointer to fc_packet.
5856  *
5857  * Returns:
5858  *      FC_SUCCESS - the packet was accepted for transport.
5859  *      FC_TRANSPORT_ERROR - a transport error occurred.
5860  *
5861  * Context:
5862  *      Kernel context.
5863  */
5864 static int
5865 ql_els_lsts(ql_adapter_state_t *ha, fc_packet_t *pkt)
5866 {
5867         ddi_dma_cookie_t        *cp;
5868         uint32_t                cnt;
5869         conv_num_t              n;
5870         port_id_t               d_id;
5871         int                     rval = FC_SUCCESS;
5872 
5873         QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
5874 
5875         d_id.b24 = pkt->pkt_cmd_fhdr.d_id;
5876         if (ha->topology & QL_SNS_CONNECTION) {
5877                 fc_lsts_req_t els;
5878                 lfa_cmd_t lfa;
5879 
5880                 ddi_rep_get8(pkt->pkt_cmd_acc, (uint8_t *)&els,
5881                     (uint8_t *)pkt->pkt_cmd, sizeof (els), DDI_DEV_AUTOINCR);
5882 
5883                 /* Setup LFA mailbox command data. */
5884                 bzero((void *)&lfa, sizeof (lfa_cmd_t));
5885 
5886                 lfa.resp_buffer_length[0] = 84;
5887 
5888                 cp = pkt->pkt_resp_cookie;
5889                 if (CFG_IST(ha, CFG_ENABLE_64BIT_ADDRESSING)) {
5890                         n.size64 = cp->dmac_laddress;
5891                         LITTLE_ENDIAN_64(&n.size64);
5892                 } else {
5893                         n.size32[0] = cp->dmac_address;
5894                         LITTLE_ENDIAN_32(&n.size32[0]);
5895                         n.size32[1] = 0;
5896                 }
5897 
5898                 /* Set buffer address. */
5899                 for (cnt = 0; cnt < 8; cnt++) {
5900                         lfa.resp_buffer_address[cnt] = n.size8[cnt];
5901                 }
5902 
5903                 lfa.subcommand_length[0] = 2;
5904                 n.size32[0] = d_id.b24;
5905                 LITTLE_ENDIAN_32(&n.size32[0]);
5906                 lfa.addr[0] = n.size8[0];
5907                 lfa.addr[1] = n.size8[1];
5908                 lfa.addr[2] = n.size8[2];
5909                 lfa.subcommand[1] = 0x72;
5910 
5911                 if (ql_send_lfa(ha, &lfa) != QL_SUCCESS) {
5912                         pkt->pkt_state = FC_PKT_TRAN_ERROR;
5913                 } else {
5914                         pkt->pkt_state = FC_PKT_SUCCESS;
5915                 }
5916         } else {
5917                 fc_lsts_resp_t rjt;
5918 
5919                 /* Build RJT. */
5920                 bzero(&rjt, sizeof (rjt));
5921                 rjt.lsts_ls_code.ls_code = LA_ELS_RJT;
5922 
5923                 ddi_rep_put8(pkt->pkt_resp_acc, (uint8_t *)&rjt,
5924                     (uint8_t *)pkt->pkt_resp, sizeof (rjt), DDI_DEV_AUTOINCR);
5925 
5926                 pkt->pkt_state = FC_PKT_TRAN_ERROR;
5927                 pkt->pkt_reason = FC_REASON_NO_CONNECTION;
5928                 EL(ha, "LA_ELS_RJT, FC_REASON_NO_CONNECTION\n");
5929         }
5930 
5931         if (rval != FC_SUCCESS) {
5932                 EL(ha, "failed=%xh\n", rval);
5933         } else {
5934                 /*EMPTY*/
5935                 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
5936         }
5937         return (rval);
5938 }
5939 
5940 /*
5941  * ql_els_scr
5942  *      Issue a extended link service state change registration request.
5943  *
5944  * Input:
5945  *      ha = adapter state pointer.
5946  *      pkt = pointer to fc_packet.
5947  *
5948  * Returns:
5949  *      FC_SUCCESS - the packet was accepted for transport.
5950  *      FC_TRANSPORT_ERROR - a transport error occurred.
5951  *
5952  * Context:
5953  *      Kernel context.
5954  */
5955 static int
5956 ql_els_scr(ql_adapter_state_t *ha, fc_packet_t *pkt)
5957 {
5958         fc_scr_resp_t   acc;
5959         int             rval = FC_SUCCESS;
5960 
5961         QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
5962 
5963         bzero(&acc, sizeof (acc));
5964         if (ha->topology & QL_SNS_CONNECTION) {
5965                 fc_scr_req_t els;
5966 
5967                 ddi_rep_get8(pkt->pkt_cmd_acc, (uint8_t *)&els,
5968                     (uint8_t *)pkt->pkt_cmd, sizeof (els), DDI_DEV_AUTOINCR);
5969 
5970                 if (ql_send_change_request(ha, els.scr_func) ==
5971                     QL_SUCCESS) {
5972                         /* Build ACC. */
5973                         acc.scr_acc = LA_ELS_ACC;
5974 
5975                         pkt->pkt_state = FC_PKT_SUCCESS;
5976                 } else {
5977                         /* Build RJT. */
5978                         acc.scr_acc = LA_ELS_RJT;
5979 
5980                         pkt->pkt_state = FC_PKT_TRAN_ERROR;
5981                         pkt->pkt_reason = FC_REASON_HW_ERROR;
5982                         EL(ha, "LA_ELS_RJT, FC_REASON_HW_ERROR\n");
5983                 }
5984         } else {
5985                 /* Build RJT. */
5986                 acc.scr_acc = LA_ELS_RJT;
5987 
5988                 pkt->pkt_state = FC_PKT_TRAN_ERROR;
5989                 pkt->pkt_reason = FC_REASON_NO_CONNECTION;
5990                 EL(ha, "LA_ELS_RJT, FC_REASON_NO_CONNECTION\n");
5991         }
5992 
5993         ddi_rep_put8(pkt->pkt_resp_acc, (uint8_t *)&acc,
5994             (uint8_t *)pkt->pkt_resp, sizeof (acc), DDI_DEV_AUTOINCR);
5995 
5996         if (rval != FC_SUCCESS) {
5997                 EL(ha, "failed, rval = %xh\n", rval);
5998         } else {
5999                 /*EMPTY*/
6000                 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
6001         }
6002         return (rval);
6003 }
6004 
6005 /*
6006  * ql_els_rscn
6007  *      Issue a extended link service register state
6008  *      change notification request.
6009  *
6010  * Input:
6011  *      ha = adapter state pointer.
6012  *      pkt = pointer to fc_packet.
6013  *
6014  * Returns:
6015  *      FC_SUCCESS - the packet was accepted for transport.
6016  *      FC_TRANSPORT_ERROR - a transport error occurred.
6017  *
6018  * Context:
6019  *      Kernel context.
6020  */
6021 static int
6022 ql_els_rscn(ql_adapter_state_t *ha, fc_packet_t *pkt)
6023 {
6024         ql_rscn_resp_t  acc;
6025         int             rval = FC_SUCCESS;
6026 
6027         QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
6028 
6029         bzero(&acc, sizeof (acc));
6030         if (ha->topology & QL_SNS_CONNECTION) {
6031                 /* Build ACC. */
6032                 acc.scr_acc = LA_ELS_ACC;
6033 
6034                 pkt->pkt_state = FC_PKT_SUCCESS;
6035         } else {
6036                 /* Build RJT. */
6037                 acc.scr_acc = LA_ELS_RJT;
6038 
6039                 pkt->pkt_state = FC_PKT_TRAN_ERROR;
6040                 pkt->pkt_reason = FC_REASON_NO_CONNECTION;
6041                 EL(ha, "LA_ELS_RJT, FC_REASON_NO_CONNECTION\n");
6042         }
6043 
6044         ddi_rep_put8(pkt->pkt_resp_acc, (uint8_t *)&acc,
6045             (uint8_t *)pkt->pkt_resp, sizeof (acc), DDI_DEV_AUTOINCR);
6046 
6047         if (rval != FC_SUCCESS) {
6048                 EL(ha, "failed, rval = %xh\n", rval);
6049         } else {
6050                 /*EMPTY*/
6051                 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
6052         }
6053         return (rval);
6054 }
6055 
6056 /*
6057  * ql_els_farp_req
6058  *      Issue FC Address Resolution Protocol (FARP)
6059  *      extended link service request.
6060  *
6061  *      Note: not supported.
6062  *
6063  * Input:
6064  *      ha = adapter state pointer.
6065  *      pkt = pointer to fc_packet.
6066  *
6067  * Returns:
6068  *      FC_SUCCESS - the packet was accepted for transport.
6069  *      FC_TRANSPORT_ERROR - a transport error occurred.
6070  *
6071  * Context:
6072  *      Kernel context.
6073  */
6074 static int
6075 ql_els_farp_req(ql_adapter_state_t *ha, fc_packet_t *pkt)
6076 {
6077         ql_acc_rjt_t    acc;
6078         int             rval = FC_SUCCESS;
6079 
6080         QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
6081 
6082         bzero(&acc, sizeof (acc));
6083 
6084         /* Build ACC. */
6085         acc.ls_code.ls_code = LA_ELS_ACC;
6086 
6087         pkt->pkt_state = FC_PKT_SUCCESS;
6088 
6089         ddi_rep_put8(pkt->pkt_resp_acc, (uint8_t *)&acc,
6090             (uint8_t *)pkt->pkt_resp, sizeof (acc), DDI_DEV_AUTOINCR);
6091 
6092         if (rval != FC_SUCCESS) {
6093                 EL(ha, "failed, rval = %xh\n", rval);
6094         } else {
6095                 /*EMPTY*/
6096                 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
6097         }
6098         return (rval);
6099 }
6100 
6101 /*
6102  * ql_els_farp_reply
6103  *      Issue FC Address Resolution Protocol (FARP)
6104  *      extended link service reply.
6105  *
6106  *      Note: not supported.
6107  *
6108  * Input:
6109  *      ha = adapter state pointer.
6110  *      pkt = pointer to fc_packet.
6111  *
6112  * Returns:
6113  *      FC_SUCCESS - the packet was accepted for transport.
6114  *      FC_TRANSPORT_ERROR - a transport error occurred.
6115  *
6116  * Context:
6117  *      Kernel context.
6118  */
6119 /* ARGSUSED */
6120 static int
6121 ql_els_farp_reply(ql_adapter_state_t *ha, fc_packet_t *pkt)
6122 {
6123         ql_acc_rjt_t    acc;
6124         int             rval = FC_SUCCESS;
6125 
6126         QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
6127 
6128         bzero(&acc, sizeof (acc));
6129 
6130         /* Build ACC. */
6131         acc.ls_code.ls_code = LA_ELS_ACC;
6132 
6133         pkt->pkt_state = FC_PKT_SUCCESS;
6134 
6135         ddi_rep_put8(pkt->pkt_resp_acc, (uint8_t *)&acc,
6136             (uint8_t *)pkt->pkt_resp, sizeof (acc), DDI_DEV_AUTOINCR);
6137 
6138         QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
6139 
6140         return (rval);
6141 }
6142 
6143 static int
6144 ql_els_rnid(ql_adapter_state_t *ha, fc_packet_t *pkt)
6145 {
6146         uchar_t                 *rnid_acc;
6147         port_id_t               d_id;
6148         ql_link_t               *link;
6149         ql_tgt_t                *tq;
6150         uint16_t                index;
6151         la_els_rnid_acc_t       acc;
6152         la_els_rnid_t           *req;
6153         size_t                  req_len;
6154 
6155         QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
6156 
6157         req_len =  FCIO_RNID_MAX_DATA_LEN + sizeof (fc_rnid_hdr_t);
6158         d_id.b24 = pkt->pkt_cmd_fhdr.d_id;
6159         index = ql_alpa_to_index[d_id.b.al_pa];
6160 
6161         tq = NULL;
6162         for (link = ha->dev[index].first; link != NULL; link = link->next) {
6163                 tq = link->base_address;
6164                 if (tq->d_id.b24 == d_id.b24) {
6165                         break;
6166                 } else {
6167                         tq = NULL;
6168                 }
6169         }
6170 
6171         /* Allocate memory for rnid status block */
6172         rnid_acc = kmem_zalloc(req_len, KM_SLEEP);
6173 
6174         bzero(&acc, sizeof (acc));
6175 
6176         req = (la_els_rnid_t *)pkt->pkt_cmd;
6177         if ((tq == NULL) || (!VALID_DEVICE_ID(ha, tq->loop_id)) ||
6178             (ql_send_rnid_els(ha, tq->loop_id, req->data_format, req_len,
6179             (caddr_t)rnid_acc) != QL_SUCCESS)) {
6180 
6181                 kmem_free(rnid_acc, req_len);
6182                 acc.ls_code.ls_code = LA_ELS_RJT;
6183 
6184                 ddi_rep_put8(pkt->pkt_resp_acc, (uint8_t *)&acc,
6185                     (uint8_t *)pkt->pkt_resp, sizeof (acc), DDI_DEV_AUTOINCR);
6186 
6187                 pkt->pkt_state = FC_PKT_TRAN_ERROR;
6188                 pkt->pkt_reason = FC_REASON_NO_CONNECTION;
6189                 EL(ha, "LA_ELS_RJT, FC_REASON_NO_CONNECTION\n");
6190 
6191                 return (FC_FAILURE);
6192         }
6193 
6194         acc.ls_code.ls_code = LA_ELS_ACC;
6195         bcopy(rnid_acc, &acc.hdr, req_len);
6196         ddi_rep_put8(pkt->pkt_resp_acc, (uint8_t *)&acc,
6197             (uint8_t *)pkt->pkt_resp, sizeof (acc), DDI_DEV_AUTOINCR);
6198 
6199         kmem_free(rnid_acc, req_len);
6200         pkt->pkt_state = FC_PKT_SUCCESS;
6201 
6202         QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
6203 
6204         return (FC_SUCCESS);
6205 }
6206 
6207 static int
6208 ql_els_rls(ql_adapter_state_t *ha, fc_packet_t *pkt)
6209 {
6210         fc_rls_acc_t            *rls_acc;
6211         port_id_t               d_id;
6212         ql_link_t               *link;
6213         ql_tgt_t                *tq;
6214         uint16_t                index;
6215         la_els_rls_acc_t        acc;
6216 
6217         QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
6218 
6219         d_id.b24 = pkt->pkt_cmd_fhdr.d_id;
6220         index = ql_alpa_to_index[d_id.b.al_pa];
6221 
6222         tq = NULL;
6223         for (link = ha->dev[index].first; link != NULL; link = link->next) {
6224                 tq = link->base_address;
6225                 if (tq->d_id.b24 == d_id.b24) {
6226                         break;
6227                 } else {
6228                         tq = NULL;
6229                 }
6230         }
6231 
6232         /* Allocate memory for link error status block */
6233         rls_acc = kmem_zalloc(sizeof (*rls_acc), KM_SLEEP);
6234 
6235         bzero(&acc, sizeof (la_els_rls_acc_t));
6236 
6237         if ((tq == NULL) || (!VALID_DEVICE_ID(ha, tq->loop_id)) ||
6238             (ql_get_link_status(ha, tq->loop_id, sizeof (*rls_acc),
6239             (caddr_t)rls_acc, 0) != QL_SUCCESS)) {
6240 
6241                 kmem_free(rls_acc, sizeof (*rls_acc));
6242                 acc.ls_code.ls_code = LA_ELS_RJT;
6243 
6244                 ddi_rep_put8(pkt->pkt_resp_acc, (uint8_t *)&acc,
6245                     (uint8_t *)pkt->pkt_resp, sizeof (acc), DDI_DEV_AUTOINCR);
6246 
6247                 pkt->pkt_state = FC_PKT_TRAN_ERROR;
6248                 pkt->pkt_reason = FC_REASON_NO_CONNECTION;
6249                 EL(ha, "LA_ELS_RJT, FC_REASON_NO_CONNECTION\n");
6250 
6251                 return (FC_FAILURE);
6252         }
6253 
6254         LITTLE_ENDIAN_32(&rls_acc->rls_link_fail);
6255         LITTLE_ENDIAN_32(&rls_acc->rls_sync_loss);
6256         LITTLE_ENDIAN_32(&rls_acc->rls_sig_loss);
6257         LITTLE_ENDIAN_32(&rls_acc->rls_invalid_word);
6258         LITTLE_ENDIAN_32(&rls_acc->rls_invalid_crc);
6259 
6260         acc.ls_code.ls_code = LA_ELS_ACC;
6261         acc.rls_link_params.rls_link_fail = rls_acc->rls_link_fail;
6262         acc.rls_link_params.rls_sync_loss = rls_acc->rls_sync_loss;
6263         acc.rls_link_params.rls_sig_loss  = rls_acc->rls_sig_loss;
6264         acc.rls_link_params.rls_invalid_word = rls_acc->rls_invalid_word;
6265         acc.rls_link_params.rls_invalid_crc = rls_acc->rls_invalid_crc;
6266         ddi_rep_put8(pkt->pkt_resp_acc, (uint8_t *)&acc,
6267             (uint8_t *)pkt->pkt_resp, sizeof (acc), DDI_DEV_AUTOINCR);
6268 
6269         kmem_free(rls_acc, sizeof (*rls_acc));
6270         pkt->pkt_state = FC_PKT_SUCCESS;
6271 
6272         QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
6273 
6274         return (FC_SUCCESS);
6275 }
6276 
6277 static int
6278 ql_busy_plogi(ql_adapter_state_t *ha, fc_packet_t *pkt, ql_tgt_t *tq)
6279 {
6280         port_id_t       d_id;
6281         ql_srb_t        *sp;
6282         fc_unsol_buf_t  *ubp;
6283         ql_link_t       *link, *next_link;
6284         int             rval = FC_SUCCESS;
6285         int             cnt = 5;
6286 
6287         QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
6288 
6289         /*
6290          * we need to ensure that q->outcnt == 0, otherwise
6291          * any cmd completed with PKT_PORT_OFFLINE after PLOGI
6292          * will confuse ulps.
6293          */
6294 
6295         DEVICE_QUEUE_LOCK(tq);
6296         do {
6297                 /*
6298                  * wait for the cmds to get drained. If they
6299                  * don't get drained then the transport will
6300                  * retry PLOGI after few secs.
6301                  */
6302                 if (tq->outcnt != 0) {
6303                         rval = FC_TRAN_BUSY;
6304                         DEVICE_QUEUE_UNLOCK(tq);
6305                         ql_delay(ha, 10000);
6306                         DEVICE_QUEUE_LOCK(tq);
6307                         cnt--;
6308                         if (!cnt) {
6309                                 cmn_err(CE_NOTE, "!%s(%d) Plogi busy"
6310                                     " for %xh outcount %xh", QL_NAME,
6311                                     ha->instance, tq->d_id.b24, tq->outcnt);
6312                         }
6313                 } else {
6314                         rval = FC_SUCCESS;
6315                         break;
6316                 }
6317         } while (cnt > 0);
6318         DEVICE_QUEUE_UNLOCK(tq);
6319 
6320         /*
6321          * return, if busy or if the plogi was asynchronous.
6322          */
6323         if ((rval != FC_SUCCESS) ||
6324             (!(pkt->pkt_tran_flags & FC_TRAN_NO_INTR) &&
6325             pkt->pkt_comp)) {
6326                 QL_PRINT_3(CE_CONT, "(%d): done, busy or async\n",
6327                     ha->instance);
6328                 return (rval);
6329         }
6330 
6331         /*
6332          * Let us give daemon sufficient time and hopefully
6333          * when transport retries PLOGI, it would have flushed
6334          * callback queue.
6335          */
6336         TASK_DAEMON_LOCK(ha);
6337         for (link = ha->callback_queue.first; link != NULL;
6338             link = next_link) {
6339                 next_link = link->next;
6340                 sp = link->base_address;
6341                 if (sp->flags & SRB_UB_CALLBACK) {
6342                         ubp = ha->ub_array[sp->handle];
6343                         d_id.b24 = ubp->ub_frame.s_id;
6344                 } else {
6345                         d_id.b24 = sp->pkt->pkt_cmd_fhdr.d_id;
6346                 }
6347                 if (tq->d_id.b24 == d_id.b24) {
6348                         cmn_err(CE_NOTE, "!%s(%d) Plogi busy for %xh", QL_NAME,
6349                             ha->instance, tq->d_id.b24);
6350                         rval = FC_TRAN_BUSY;
6351                         break;
6352                 }
6353         }
6354         TASK_DAEMON_UNLOCK(ha);
6355 
6356         QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
6357 
6358         return (rval);
6359 }
6360 
6361 /*
6362  * ql_login_port
6363  *      Logs in a device if not already logged in.
6364  *
6365  * Input:
6366  *      ha = adapter state pointer.
6367  *      d_id = 24 bit port ID.
6368  *      DEVICE_QUEUE_LOCK must be released.
6369  *
6370  * Returns:
6371  *      QL local function return status code.
6372  *
6373  * Context:
6374  *      Kernel context.
6375  */
6376 static int
6377 ql_login_port(ql_adapter_state_t *ha, port_id_t d_id)
6378 {
6379         ql_adapter_state_t      *vha;
6380         ql_link_t               *link;
6381         uint16_t                index;
6382         ql_tgt_t                *tq, *tq2;
6383         uint16_t                loop_id, first_loop_id, last_loop_id;
6384         int                     rval = QL_SUCCESS;
6385 
6386         QL_PRINT_3(CE_CONT, "(%d): started, d_id=%xh\n", ha->instance,
6387             d_id.b24);
6388 
6389         /* Get head queue index. */
6390         index = ql_alpa_to_index[d_id.b.al_pa];
6391 
6392         /* Check for device already has a queue. */
6393         tq = NULL;
6394         for (link = ha->dev[index].first; link != NULL; link = link->next) {
6395                 tq = link->base_address;
6396                 if (tq->d_id.b24 == d_id.b24) {
6397                         loop_id = tq->loop_id;
6398                         break;
6399                 } else {
6400                         tq = NULL;
6401                 }
6402         }
6403 
6404         /* Let's stop issuing any IO and unsolicited logo */
6405         if ((tq != NULL) && (!(ddi_in_panic()))) {
6406                 DEVICE_QUEUE_LOCK(tq);
6407                 tq->flags |= (TQF_QUEUE_SUSPENDED | TQF_PLOGI_PROGRS);
6408                 tq->flags &= ~TQF_RSCN_RCVD;
6409                 DEVICE_QUEUE_UNLOCK(tq);
6410         }
6411         if ((tq != NULL) && (tq->loop_id & PORT_LOST_ID) &&
6412             !(tq->flags & TQF_FABRIC_DEVICE)) {
6413                 loop_id = (uint16_t)(tq->loop_id & ~PORT_LOST_ID);
6414         }
6415 
6416         /* Special case for Nameserver */
6417         if (d_id.b24 == 0xFFFFFC) {
6418                 loop_id = (uint16_t)(CFG_IST(ha, CFG_CTRL_24258081) ?
6419                     SNS_24XX_HDL : SIMPLE_NAME_SERVER_LOOP_ID);
6420                 if (tq == NULL) {
6421                         ADAPTER_STATE_LOCK(ha);
6422                         tq = ql_dev_init(ha, d_id, loop_id);
6423                         ADAPTER_STATE_UNLOCK(ha);
6424                         if (tq == NULL) {
6425                                 EL(ha, "failed=%xh, d_id=%xh\n",
6426                                     QL_FUNCTION_FAILED, d_id.b24);
6427                                 return (QL_FUNCTION_FAILED);
6428                         }
6429                 }
6430                 if (!(CFG_IST(ha, CFG_CTRL_8021))) {
6431                         rval = ql_login_fabric_port(ha, tq, loop_id);
6432                         if (rval == QL_SUCCESS) {
6433                                 tq->loop_id = loop_id;
6434                                 tq->flags |= TQF_FABRIC_DEVICE;
6435                                 (void) ql_get_port_database(ha, tq, PDF_NONE);
6436                         }
6437                 } else {
6438                         ha->topology = (uint8_t)
6439                             (ha->topology | QL_SNS_CONNECTION);
6440                 }
6441         /* Check for device already logged in. */
6442         } else if (tq != NULL && VALID_DEVICE_ID(ha, loop_id)) {
6443                 if (tq->flags & TQF_FABRIC_DEVICE) {
6444                         rval = ql_login_fabric_port(ha, tq, loop_id);
6445                         if (rval == QL_PORT_ID_USED) {
6446                                 rval = QL_SUCCESS;
6447                         }
6448                 } else if (LOCAL_LOOP_ID(loop_id)) {
6449                         rval = ql_login_lport(ha, tq, loop_id, (uint16_t)
6450                             (tq->flags & TQF_INITIATOR_DEVICE ?
6451                             LLF_NONE : LLF_PLOGI));
6452                         if (rval == QL_SUCCESS) {
6453                                 DEVICE_QUEUE_LOCK(tq);
6454                                 tq->loop_id = loop_id;
6455                                 DEVICE_QUEUE_UNLOCK(tq);
6456                         }
6457                 }
6458         } else if (ha->topology & QL_SNS_CONNECTION) {
6459                 /* Locate unused loop ID. */
6460                 if (CFG_IST(ha, CFG_CTRL_24258081)) {
6461                         first_loop_id = 0;
6462                         last_loop_id = LAST_N_PORT_HDL;
6463                 } else if (ha->topology & QL_F_PORT) {
6464                         first_loop_id = 0;
6465                         last_loop_id = SNS_LAST_LOOP_ID;
6466                 } else {
6467                         first_loop_id = SNS_FIRST_LOOP_ID;
6468                         last_loop_id = SNS_LAST_LOOP_ID;
6469                 }
6470 
6471                 /* Acquire adapter state lock. */
6472                 ADAPTER_STATE_LOCK(ha);
6473 
6474                 tq = ql_dev_init(ha, d_id, PORT_NO_LOOP_ID);
6475                 if (tq == NULL) {
6476                         EL(ha, "failed=%xh, d_id=%xh\n", QL_FUNCTION_FAILED,
6477                             d_id.b24);
6478 
6479                         ADAPTER_STATE_UNLOCK(ha);
6480 
6481                         return (QL_FUNCTION_FAILED);
6482                 }
6483 
6484                 rval = QL_FUNCTION_FAILED;
6485                 loop_id = ha->pha->free_loop_id++;
6486                 for (index = (uint16_t)(last_loop_id - first_loop_id); index;
6487                     index--) {
6488                         if (loop_id < first_loop_id ||
6489                             loop_id > last_loop_id) {
6490                                 loop_id = first_loop_id;
6491                                 ha->pha->free_loop_id = (uint16_t)
6492                                     (loop_id + 1);
6493                         }
6494 
6495                         /* Bypass if loop ID used. */
6496                         for (vha = ha->pha; vha != NULL; vha = vha->vp_next) {
6497                                 tq2 = ql_loop_id_to_queue(vha, loop_id);
6498                                 if (tq2 != NULL && tq2 != tq) {
6499                                         break;
6500                                 }
6501                         }
6502                         if (vha != NULL || RESERVED_LOOP_ID(ha, loop_id) ||
6503                             loop_id == ha->loop_id) {
6504                                 loop_id = ha->pha->free_loop_id++;
6505                                 continue;
6506                         }
6507 
6508                         ADAPTER_STATE_UNLOCK(ha);
6509                         rval = ql_login_fabric_port(ha, tq, loop_id);
6510 
6511                         /*
6512                          * If PORT_ID_USED is returned
6513                          * the login_fabric_port() updates
6514                          * with the correct loop ID
6515                          */
6516                         switch (rval) {
6517                         case QL_PORT_ID_USED:
6518                                 /*
6519                                  * use f/w handle and try to
6520                                  * login again.
6521                                  */
6522                                 ADAPTER_STATE_LOCK(ha);
6523                                 ha->pha->free_loop_id--;
6524                                 ADAPTER_STATE_UNLOCK(ha);
6525                                 loop_id = tq->loop_id;
6526                                 break;
6527 
6528                         case QL_SUCCESS:
6529                                 tq->flags |= TQF_FABRIC_DEVICE;
6530                                 (void) ql_get_port_database(ha,
6531                                     tq, PDF_NONE);
6532                                 index = 1;
6533                                 break;
6534 
6535                         case QL_LOOP_ID_USED:
6536                                 tq->loop_id = PORT_NO_LOOP_ID;
6537                                 loop_id = ha->pha->free_loop_id++;
6538                                 break;
6539 
6540                         case QL_ALL_IDS_IN_USE:
6541                                 tq->loop_id = PORT_NO_LOOP_ID;
6542                                 index = 1;
6543                                 break;
6544 
6545                         default:
6546                                 tq->loop_id = PORT_NO_LOOP_ID;
6547                                 index = 1;
6548                                 break;
6549                         }
6550 
6551                         ADAPTER_STATE_LOCK(ha);
6552                 }
6553 
6554                 ADAPTER_STATE_UNLOCK(ha);
6555         } else {
6556                 rval = QL_FUNCTION_FAILED;
6557         }
6558 
6559         if (rval != QL_SUCCESS) {
6560                 EL(ha, "failed=%xh, d_id=%xh\n", rval, d_id.b24);
6561         } else {
6562                 EL(ha, "d_id=%xh, loop_id=%xh, "
6563                     "wwpn=%02x%02x%02x%02x%02x%02x%02x%02xh\n", tq->d_id.b24,
6564                     tq->loop_id, tq->port_name[0], tq->port_name[1],
6565                     tq->port_name[2], tq->port_name[3], tq->port_name[4],
6566                     tq->port_name[5], tq->port_name[6], tq->port_name[7]);
6567         }
6568         return (rval);
6569 }
6570 
6571 /*
6572  * ql_login_fabric_port
6573  *      Issue login fabric port mailbox command.
6574  *
6575  * Input:
6576  *      ha:             adapter state pointer.
6577  *      tq:             target queue pointer.
6578  *      loop_id:        FC Loop ID.
6579  *
6580  * Returns:
6581  *      ql local function return status code.
6582  *
6583  * Context:
6584  *      Kernel context.
6585  */
6586 static int
6587 ql_login_fabric_port(ql_adapter_state_t *ha, ql_tgt_t *tq, uint16_t loop_id)
6588 {
6589         int             rval;
6590         int             index;
6591         int             retry = 0;
6592         port_id_t       d_id;
6593         ql_tgt_t        *newq;
6594         ql_mbx_data_t   mr;
6595 
6596         QL_PRINT_3(CE_CONT, "(%d): started, d_id=%xh\n", ha->instance,
6597             tq->d_id.b24);
6598 
6599         /*
6600          * QL_PARAMETER_ERROR also means the firmware is
6601          * not able to allocate PCB entry due to resource
6602          * issues, or collision.
6603          */
6604         do {
6605                 rval = ql_login_fport(ha, tq, loop_id, LFF_NONE, &mr);
6606                 if ((rval == QL_PARAMETER_ERROR) ||
6607                     ((rval == QL_COMMAND_ERROR) && (mr.mb[1] == 2 ||
6608                     mr.mb[1] == 3 || mr.mb[1] == 7 || mr.mb[1] == 0xd))) {
6609                         retry++;
6610                         drv_usecwait(10 * MILLISEC);
6611                 } else {
6612                         break;
6613                 }
6614         } while (retry < 5);
6615 
6616         switch (rval) {
6617         case QL_SUCCESS:
6618                 tq->loop_id = loop_id;
6619                 break;
6620 
6621         case QL_PORT_ID_USED:
6622                 /*
6623                  * This Loop ID should NOT be in use in drivers
6624                  */
6625                 newq = ql_loop_id_to_queue(ha, mr.mb[1]);
6626 
6627                 if (newq != NULL && newq != tq && tq->logout_sent == 0) {
6628                         cmn_err(CE_WARN, "ql_login_fabric_port(%d): logout of "
6629                             "dup loop_id=%xh, d_id=%xh", ha->instance,
6630                             newq->loop_id, newq->d_id.b24);
6631                         ql_send_logo(ha, newq, NULL);
6632                 }
6633 
6634                 tq->loop_id = mr.mb[1];
6635                 break;
6636 
6637         case QL_LOOP_ID_USED:
6638                 d_id.b.al_pa = LSB(mr.mb[2]);
6639                 d_id.b.area = MSB(mr.mb[2]);
6640                 d_id.b.domain = LSB(mr.mb[1]);
6641 
6642                 newq = ql_d_id_to_queue(ha, d_id);
6643                 if (newq && (newq->loop_id != loop_id)) {
6644                         /*
6645                          * This should NEVER ever happen; but this
6646                          * code is needed to bail out when the worst
6647                          * case happens - or as used to happen before
6648                          */
6649                         QL_PRINT_2(CE_CONT, "(%d,%d): Loop ID is now "
6650                             "reassigned; old pairs: [%xh, %xh] and [%xh, %xh];"
6651                             "new pairs: [%xh, unknown] and [%xh, %xh]\n",
6652                             ha->instance, ha->vp_index, tq->d_id.b24, loop_id,
6653                             newq->d_id.b24, newq->loop_id, tq->d_id.b24,
6654                             newq->d_id.b24, loop_id);
6655 
6656                         if ((newq->d_id.b24 & 0xff) != (d_id.b24 & 0xff)) {
6657                                 ADAPTER_STATE_LOCK(ha);
6658 
6659                                 index = ql_alpa_to_index[newq->d_id.b.al_pa];
6660                                 ql_add_link_b(&ha->dev[index], &newq->device);
6661 
6662                                 newq->d_id.b24 = d_id.b24;
6663 
6664                                 index = ql_alpa_to_index[d_id.b.al_pa];
6665                                 ql_add_link_b(&ha->dev[index], &newq->device);
6666 
6667                                 ADAPTER_STATE_UNLOCK(ha);
6668                         }
6669 
6670                         (void) ql_get_port_database(ha, newq, PDF_NONE);
6671 
6672                 }
6673 
6674                 /*
6675                  * Invalidate the loop ID for the
6676                  * us to obtain a new one.
6677                  */
6678                 tq->loop_id = PORT_NO_LOOP_ID;
6679                 break;
6680 
6681         case QL_ALL_IDS_IN_USE:
6682                 rval = QL_FUNCTION_FAILED;
6683                 EL(ha, "no loop id's available\n");
6684                 break;
6685 
6686         default:
6687                 if (rval == QL_COMMAND_ERROR) {
6688                         switch (mr.mb[1]) {
6689                         case 2:
6690                         case 3:
6691                                 rval = QL_MEMORY_ALLOC_FAILED;
6692                                 break;
6693 
6694                         case 4:
6695                                 rval = QL_FUNCTION_TIMEOUT;
6696                                 break;
6697                         case 7:
6698                                 rval = QL_FABRIC_NOT_INITIALIZED;
6699                                 break;
6700                         default:
6701                                 EL(ha, "cmd rtn; mb1=%xh\n", mr.mb[1]);
6702                                 break;
6703                         }
6704                 } else {
6705                         cmn_err(CE_WARN, "%s(%d): login fabric port failed"
6706                             " D_ID=%xh, rval=%xh, mb1=%xh", QL_NAME,
6707                             ha->instance, tq->d_id.b24, rval, mr.mb[1]);
6708                 }
6709                 break;
6710         }
6711 
6712         if (rval != QL_SUCCESS && rval != QL_PORT_ID_USED &&
6713             rval != QL_LOOP_ID_USED) {
6714                 EL(ha, "failed=%xh\n", rval);
6715         } else {
6716                 /*EMPTY*/
6717                 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
6718         }
6719         return (rval);
6720 }
6721 
6722 /*
6723  * ql_logout_port
6724  *      Logs out a device if possible.
6725  *
6726  * Input:
6727  *      ha:     adapter state pointer.
6728  *      d_id:   24 bit port ID.
6729  *
6730  * Returns:
6731  *      QL local function return status code.
6732  *
6733  * Context:
6734  *      Kernel context.
6735  */
6736 static int
6737 ql_logout_port(ql_adapter_state_t *ha, port_id_t d_id)
6738 {
6739         ql_link_t       *link;
6740         ql_tgt_t        *tq;
6741         uint16_t        index;
6742 
6743         QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
6744 
6745         /* Get head queue index. */
6746         index = ql_alpa_to_index[d_id.b.al_pa];
6747 
6748         /* Get device queue. */
6749         tq = NULL;
6750         for (link = ha->dev[index].first; link != NULL; link = link->next) {
6751                 tq = link->base_address;
6752                 if (tq->d_id.b24 == d_id.b24) {
6753                         break;
6754                 } else {
6755                         tq = NULL;
6756                 }
6757         }
6758 
6759         if (tq != NULL && tq->flags & TQF_FABRIC_DEVICE) {
6760                 (void) ql_logout_fabric_port(ha, tq);
6761                 tq->loop_id = PORT_NO_LOOP_ID;
6762         }
6763 
6764         QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
6765 
6766         return (QL_SUCCESS);
6767 }
6768 
6769 /*
6770  * ql_dev_init
6771  *      Initialize/allocate device queue.
6772  *
6773  * Input:
6774  *      ha:             adapter state pointer.
6775  *      d_id:           device destination ID
6776  *      loop_id:        device loop ID
6777  *      ADAPTER_STATE_LOCK must be already obtained.
6778  *
6779  * Returns:
6780  *      NULL = failure
6781  *
6782  * Context:
6783  *      Kernel context.
6784  */
6785 ql_tgt_t *
6786 ql_dev_init(ql_adapter_state_t *ha, port_id_t d_id, uint16_t loop_id)
6787 {
6788         ql_link_t       *link;
6789         uint16_t        index;
6790         ql_tgt_t        *tq;
6791 
6792         QL_PRINT_3(CE_CONT, "(%d): started, d_id=%xh, loop_id=%xh\n",
6793             ha->instance, d_id.b24, loop_id);
6794 
6795         index = ql_alpa_to_index[d_id.b.al_pa];
6796 
6797         /* If device queue exists, set proper loop ID. */
6798         tq = NULL;
6799         for (link = ha->dev[index].first; link != NULL; link = link->next) {
6800                 tq = link->base_address;
6801                 if (tq->d_id.b24 == d_id.b24) {
6802                         tq->loop_id = loop_id;
6803 
6804                         /* Reset port down retry count. */
6805                         tq->port_down_retry_count = ha->port_down_retry_count;
6806                         tq->qfull_retry_count = ha->qfull_retry_count;
6807 
6808                         break;
6809                 } else {
6810                         tq = NULL;
6811                 }
6812         }
6813 
6814         /* If device does not have queue. */
6815         if (tq == NULL) {
6816                 tq = (ql_tgt_t *)kmem_zalloc(sizeof (ql_tgt_t), KM_SLEEP);
6817                 if (tq != NULL) {
6818                         /*
6819                          * mutex to protect the device queue,
6820                          * does not block interrupts.
6821                          */
6822                         mutex_init(&tq->mutex, NULL, MUTEX_DRIVER,
6823                             (ha->iflags & IFLG_INTR_AIF) ?
6824                             (void *)(uintptr_t)ha->intr_pri :
6825                             (void *)(uintptr_t)ha->iblock_cookie);
6826 
6827                         tq->d_id.b24 = d_id.b24;
6828                         tq->loop_id = loop_id;
6829                         tq->device.base_address = tq;
6830                         tq->iidma_rate = IIDMA_RATE_INIT;
6831 
6832                         /* Reset port down retry count. */
6833                         tq->port_down_retry_count = ha->port_down_retry_count;
6834                         tq->qfull_retry_count = ha->qfull_retry_count;
6835 
6836                         /* Add device to device queue. */
6837                         ql_add_link_b(&ha->dev[index], &tq->device);
6838                 }
6839         }
6840 
6841         if (tq == NULL) {
6842                 EL(ha, "failed, d_id=%xh, loop_id=%xh\n", d_id.b24, loop_id);
6843         } else {
6844                 /*EMPTY*/
6845                 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
6846         }
6847         return (tq);
6848 }
6849 
6850 /*
6851  * ql_dev_free
6852  *      Remove queue from device list and frees resources used by queue.
6853  *
6854  * Input:
6855  *      ha:     adapter state pointer.
6856  *      tq:     target queue pointer.
6857  *      ADAPTER_STATE_LOCK must be already obtained.
6858  *
6859  * Context:
6860  *      Kernel context.
6861  */
6862 void
6863 ql_dev_free(ql_adapter_state_t *ha, ql_tgt_t *tq)
6864 {
6865         ql_link_t       *link;
6866         uint16_t        index;
6867         ql_lun_t        *lq;
6868 
6869         QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
6870 
6871         for (link = tq->lun_queues.first; link != NULL; link = link->next) {
6872                 lq = link->base_address;
6873                 if (lq->cmd.first != NULL) {
6874                         return;
6875                 }
6876         }
6877 
6878         if (tq->outcnt == 0) {
6879                 /* Get head queue index. */
6880                 index = ql_alpa_to_index[tq->d_id.b.al_pa];
6881                 for (link = ha->dev[index].first; link != NULL;
6882                     link = link->next) {
6883                         if (link->base_address == tq) {
6884                                 ql_remove_link(&ha->dev[index], link);
6885 
6886                                 link = tq->lun_queues.first;
6887                                 while (link != NULL) {
6888                                         lq = link->base_address;
6889                                         link = link->next;
6890 
6891                                         ql_remove_link(&tq->lun_queues,
6892                                             &lq->link);
6893                                         kmem_free(lq, sizeof (ql_lun_t));
6894                                 }
6895 
6896                                 mutex_destroy(&tq->mutex);
6897                                 kmem_free(tq, sizeof (ql_tgt_t));
6898                                 break;
6899                         }
6900                 }
6901         }
6902 
6903         QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
6904 }
6905 
6906 /*
6907  * ql_lun_queue
6908  *      Allocate LUN queue if does not exists.
6909  *
6910  * Input:
6911  *      ha:     adapter state pointer.
6912  *      tq:     target queue.
6913  *      lun:    LUN number.
6914  *
6915  * Returns:
6916  *      NULL = failure
6917  *
6918  * Context:
6919  *      Kernel context.
6920  */
6921 static ql_lun_t *
6922 ql_lun_queue(ql_adapter_state_t *ha, ql_tgt_t *tq, uint16_t lun)
6923 {
6924         ql_lun_t        *lq;
6925         ql_link_t       *link;
6926 
6927         QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
6928 
6929         /* Fast path. */
6930         if (tq->last_lun_queue != NULL && tq->last_lun_queue->lun_no == lun) {
6931                 QL_PRINT_3(CE_CONT, "(%d): fast done\n", ha->instance);
6932                 return (tq->last_lun_queue);
6933         }
6934 
6935         if (lun >= MAX_LUNS) {
6936                 EL(ha, "Exceeded MAX_LUN=%d, lun=%d\n", MAX_LUNS, lun);
6937                 return (NULL);
6938         }
6939         /* If device queue exists, set proper loop ID. */
6940         lq = NULL;
6941         for (link = tq->lun_queues.first; link != NULL; link = link->next) {
6942                 lq = link->base_address;
6943                 if (lq->lun_no == lun) {
6944                         QL_PRINT_3(CE_CONT, "(%d): found done\n", ha->instance);
6945                         tq->last_lun_queue = lq;
6946                         return (lq);
6947                 }
6948         }
6949 
6950         /* If queue does exist. */
6951         lq = (ql_lun_t *)kmem_zalloc(sizeof (ql_lun_t), KM_SLEEP);
6952 
6953         /* Initialize LUN queue. */
6954         if (lq != NULL) {
6955                 lq->link.base_address = lq;
6956 
6957                 lq->lun_no = lun;
6958                 lq->target_queue = tq;
6959 
6960                 DEVICE_QUEUE_LOCK(tq);
6961                 ql_add_link_b(&tq->lun_queues, &lq->link);
6962                 DEVICE_QUEUE_UNLOCK(tq);
6963                 tq->last_lun_queue = lq;
6964         }
6965 
6966         QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
6967 
6968         return (lq);
6969 }
6970 
6971 /*
6972  * ql_fcp_scsi_cmd
6973  *      Process fibre channel (FCP) SCSI protocol commands.
6974  *
6975  * Input:
6976  *      ha = adapter state pointer.
6977  *      pkt = pointer to fc_packet.
6978  *      sp = srb pointer.
6979  *
6980  * Returns:
6981  *      FC_SUCCESS - the packet was accepted for transport.
6982  *      FC_TRANSPORT_ERROR - a transport error occurred.
6983  *
6984  * Context:
6985  *      Kernel context.
6986  */
6987 static int
6988 ql_fcp_scsi_cmd(ql_adapter_state_t *ha, fc_packet_t *pkt, ql_srb_t *sp)
6989 {
6990         port_id_t       d_id;
6991         ql_tgt_t        *tq;
6992         uint64_t        *ptr;
6993         uint16_t        lun;
6994 
6995         QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
6996 
6997         tq = (ql_tgt_t *)pkt->pkt_fca_device;
6998         if (tq == NULL) {
6999                 d_id.r.rsvd_1 = 0;
7000                 d_id.b24 = pkt->pkt_cmd_fhdr.d_id;
7001                 tq = ql_d_id_to_queue(ha, d_id);
7002         }
7003 
7004         sp->fcp = (struct fcp_cmd *)pkt->pkt_cmd;
7005         lun = CHAR_TO_SHORT(lobyte(sp->fcp->fcp_ent_addr.ent_addr_0),
7006             hibyte(sp->fcp->fcp_ent_addr.ent_addr_0));
7007 
7008         if (tq != NULL &&
7009             (sp->lun_queue = ql_lun_queue(ha, tq, lun)) != NULL) {
7010 
7011                 /*
7012                  * zero out FCP response; 24 Bytes
7013                  */
7014                 ptr = (uint64_t *)pkt->pkt_resp;
7015                 *ptr++ = 0; *ptr++ = 0; *ptr++ = 0;
7016 
7017                 /* Handle task management function. */
7018                 if ((sp->fcp->fcp_cntl.cntl_kill_tsk |
7019                     sp->fcp->fcp_cntl.cntl_clr_aca |
7020                     sp->fcp->fcp_cntl.cntl_reset_tgt |
7021                     sp->fcp->fcp_cntl.cntl_reset_lun |
7022                     sp->fcp->fcp_cntl.cntl_clr_tsk |
7023                     sp->fcp->fcp_cntl.cntl_abort_tsk) != 0) {
7024                         ql_task_mgmt(ha, tq, pkt, sp);
7025                 } else {
7026                         ha->pha->xioctl->IosRequested++;
7027                         ha->pha->xioctl->BytesRequested += (uint32_t)
7028                             sp->fcp->fcp_data_len;
7029 
7030                         /*
7031                          * Setup for commands with data transfer
7032                          */
7033                         sp->iocb = ha->fcp_cmd;
7034                         sp->req_cnt = 1;
7035                         if (sp->fcp->fcp_data_len != 0) {
7036                                 /*
7037                                  * FCP data is bound to pkt_data_dma
7038                                  */
7039                                 if (sp->fcp->fcp_cntl.cntl_write_data) {
7040                                         (void) ddi_dma_sync(pkt->pkt_data_dma,
7041                                             0, 0, DDI_DMA_SYNC_FORDEV);
7042                                 }
7043 
7044                                 /* Setup IOCB count. */
7045                                 if (pkt->pkt_data_cookie_cnt > ha->cmd_segs &&
7046                                     (!CFG_IST(ha, CFG_CTRL_8021) ||
7047                                     sp->sg_dma.dma_handle == NULL)) {
7048                                         uint32_t        cnt;
7049 
7050                                         cnt = pkt->pkt_data_cookie_cnt -
7051                                             ha->cmd_segs;
7052                                         sp->req_cnt = (uint16_t)
7053                                             (cnt / ha->cmd_cont_segs);
7054                                         if (cnt % ha->cmd_cont_segs) {
7055                                                 sp->req_cnt = (uint16_t)
7056                                                     (sp->req_cnt + 2);
7057                                         } else {
7058                                                 sp->req_cnt++;
7059                                         }
7060                                 }
7061                         }
7062                         QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
7063 
7064                         return (ql_start_cmd(ha, tq, pkt, sp));
7065                 }
7066         } else {
7067                 pkt->pkt_state = FC_PKT_LOCAL_RJT;
7068                 pkt->pkt_reason = FC_REASON_NO_CONNECTION;
7069 
7070                 if (!(pkt->pkt_tran_flags & FC_TRAN_NO_INTR) && pkt->pkt_comp)
7071                         ql_awaken_task_daemon(ha, sp, 0, 0);
7072         }
7073 
7074         QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
7075 
7076         return (FC_SUCCESS);
7077 }
7078 
7079 /*
7080  * ql_task_mgmt
7081  *      Task management function processor.
7082  *
7083  * Input:
7084  *      ha:     adapter state pointer.
7085  *      tq:     target queue pointer.
7086  *      pkt:    pointer to fc_packet.
7087  *      sp:     SRB pointer.
7088  *
7089  * Context:
7090  *      Kernel context.
7091  */
7092 static void
7093 ql_task_mgmt(ql_adapter_state_t *ha, ql_tgt_t *tq, fc_packet_t *pkt,
7094     ql_srb_t *sp)
7095 {
7096         fcp_rsp_t               *fcpr;
7097         struct fcp_rsp_info     *rsp;
7098         uint16_t                lun;
7099 
7100         QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
7101 
7102         fcpr = (fcp_rsp_t *)pkt->pkt_resp;
7103         rsp = (struct fcp_rsp_info *)pkt->pkt_resp + sizeof (fcp_rsp_t);
7104 
7105         bzero(fcpr, pkt->pkt_rsplen);
7106 
7107         fcpr->fcp_u.fcp_status.rsp_len_set = 1;
7108         fcpr->fcp_response_len = 8;
7109         lun = CHAR_TO_SHORT(lobyte(sp->fcp->fcp_ent_addr.ent_addr_0),
7110             hibyte(sp->fcp->fcp_ent_addr.ent_addr_0));
7111 
7112         if (sp->fcp->fcp_cntl.cntl_clr_aca) {
7113                 if (ql_clear_aca(ha, tq, lun) != QL_SUCCESS) {
7114                         rsp->rsp_code = FCP_TASK_MGMT_FAILED;
7115                 }
7116         } else if (sp->fcp->fcp_cntl.cntl_reset_lun) {
7117                 if (ql_lun_reset(ha, tq, lun) != QL_SUCCESS) {
7118                         rsp->rsp_code = FCP_TASK_MGMT_FAILED;
7119                 }
7120         } else if (sp->fcp->fcp_cntl.cntl_reset_tgt) {
7121                 if (ql_target_reset(ha, tq, ha->loop_reset_delay) !=
7122                     QL_SUCCESS) {
7123                         rsp->rsp_code = FCP_TASK_MGMT_FAILED;
7124                 }
7125         } else if (sp->fcp->fcp_cntl.cntl_clr_tsk) {
7126                 if (ql_clear_task_set(ha, tq, lun) != QL_SUCCESS) {
7127                         rsp->rsp_code = FCP_TASK_MGMT_FAILED;
7128                 }
7129         } else if (sp->fcp->fcp_cntl.cntl_abort_tsk) {
7130                 if (ql_abort_task_set(ha, tq, lun) != QL_SUCCESS) {
7131                         rsp->rsp_code = FCP_TASK_MGMT_FAILED;
7132                 }
7133         } else {
7134                 rsp->rsp_code = FCP_TASK_MGMT_NOT_SUPPTD;
7135         }
7136 
7137         pkt->pkt_state = FC_PKT_SUCCESS;
7138 
7139         /* Do command callback. */
7140         if (!(pkt->pkt_tran_flags & FC_TRAN_NO_INTR) && pkt->pkt_comp) {
7141                 ql_awaken_task_daemon(ha, sp, 0, 0);
7142         }
7143 
7144         QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
7145 }
7146 
7147 /*
7148  * ql_fcp_ip_cmd
7149  *      Process fibre channel (FCP) Internet (IP) protocols commands.
7150  *
7151  * Input:
7152  *      ha:     adapter state pointer.
7153  *      pkt:    pointer to fc_packet.
7154  *      sp:     SRB pointer.
7155  *
7156  * Returns:
7157  *      FC_SUCCESS - the packet was accepted for transport.
7158  *      FC_TRANSPORT_ERROR - a transport error occurred.
7159  *
7160  * Context:
7161  *      Kernel context.
7162  */
7163 static int
7164 ql_fcp_ip_cmd(ql_adapter_state_t *ha, fc_packet_t *pkt, ql_srb_t *sp)
7165 {
7166         port_id_t       d_id;
7167         ql_tgt_t        *tq;
7168 
7169         QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
7170 
7171         tq = (ql_tgt_t *)pkt->pkt_fca_device;
7172         if (tq == NULL) {
7173                 d_id.r.rsvd_1 = 0;
7174                 d_id.b24 = pkt->pkt_cmd_fhdr.d_id;
7175                 tq = ql_d_id_to_queue(ha, d_id);
7176         }
7177 
7178         if (tq != NULL && (sp->lun_queue = ql_lun_queue(ha, tq, 0)) != NULL) {
7179                 /*
7180                  * IP data is bound to pkt_cmd_dma
7181                  */
7182                 (void) ddi_dma_sync(pkt->pkt_cmd_dma,
7183                     0, 0, DDI_DMA_SYNC_FORDEV);
7184 
7185                 /* Setup IOCB count. */
7186                 sp->iocb = ha->ip_cmd;
7187                 if (pkt->pkt_cmd_cookie_cnt > ha->cmd_segs) {
7188                         uint32_t        cnt;
7189 
7190                         cnt = pkt->pkt_cmd_cookie_cnt - ha->cmd_segs;
7191                         sp->req_cnt = (uint16_t)(cnt / ha->cmd_cont_segs);
7192                         if (cnt % ha->cmd_cont_segs) {
7193                                 sp->req_cnt = (uint16_t)(sp->req_cnt + 2);
7194                         } else {
7195                                 sp->req_cnt++;
7196                         }
7197                 } else {
7198                         sp->req_cnt = 1;
7199                 }
7200                 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
7201 
7202                 return (ql_start_cmd(ha, tq, pkt, sp));
7203         } else {
7204                 pkt->pkt_state = FC_PKT_LOCAL_RJT;
7205                 pkt->pkt_reason = FC_REASON_NO_CONNECTION;
7206 
7207                 if (!(pkt->pkt_tran_flags & FC_TRAN_NO_INTR) && pkt->pkt_comp)
7208                         ql_awaken_task_daemon(ha, sp, 0, 0);
7209         }
7210 
7211         QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
7212 
7213         return (FC_SUCCESS);
7214 }
7215 
7216 /*
7217  * ql_fc_services
7218  *      Process fibre channel services (name server).
7219  *
7220  * Input:
7221  *      ha:     adapter state pointer.
7222  *      pkt:    pointer to fc_packet.
7223  *
7224  * Returns:
7225  *      FC_SUCCESS - the packet was accepted for transport.
7226  *      FC_TRANSPORT_ERROR - a transport error occurred.
7227  *
7228  * Context:
7229  *      Kernel context.
7230  */
7231 static int
7232 ql_fc_services(ql_adapter_state_t *ha, fc_packet_t *pkt)
7233 {
7234         uint32_t        cnt;
7235         fc_ct_header_t  hdr;
7236         la_els_rjt_t    rjt;
7237         port_id_t       d_id;
7238         ql_tgt_t        *tq;
7239         ql_srb_t        *sp;
7240         int             rval;
7241 
7242         QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
7243 
7244         ddi_rep_get8(pkt->pkt_cmd_acc, (uint8_t *)&hdr,
7245             (uint8_t *)pkt->pkt_cmd, sizeof (hdr), DDI_DEV_AUTOINCR);
7246 
7247         bzero(&rjt, sizeof (rjt));
7248 
7249         /* Do some sanity checks */
7250         cnt = (uint32_t)((uint32_t)(hdr.ct_aiusize * 4) +
7251             sizeof (fc_ct_header_t));
7252         if (cnt > (uint32_t)pkt->pkt_rsplen) {
7253                 EL(ha, "FC_ELS_MALFORMED, cnt=%xh, size=%xh\n", cnt,
7254                     pkt->pkt_rsplen);
7255                 return (FC_ELS_MALFORMED);
7256         }
7257 
7258         switch (hdr.ct_fcstype) {
7259         case FCSTYPE_DIRECTORY:
7260         case FCSTYPE_MGMTSERVICE:
7261                 /* An FCA must make sure that the header is in big endian */
7262                 ql_cthdr_endian(pkt->pkt_cmd_acc, pkt->pkt_cmd, B_FALSE);
7263 
7264                 d_id.b24 = pkt->pkt_cmd_fhdr.d_id;
7265                 tq = ql_d_id_to_queue(ha, d_id);
7266                 sp = (ql_srb_t *)pkt->pkt_fca_private;
7267                 if (tq == NULL ||
7268                     (sp->lun_queue = ql_lun_queue(ha, tq, 0)) == NULL) {
7269                         pkt->pkt_state = FC_PKT_LOCAL_RJT;
7270                         pkt->pkt_reason = FC_REASON_NO_CONNECTION;
7271                         rval = QL_SUCCESS;
7272                         break;
7273                 }
7274 
7275                 /*
7276                  * Services data is bound to pkt_cmd_dma
7277                  */
7278                 (void) ddi_dma_sync(pkt->pkt_cmd_dma, 0, 0,
7279                     DDI_DMA_SYNC_FORDEV);
7280 
7281                 sp->flags |= SRB_MS_PKT;
7282                 sp->retry_count = 32;
7283 
7284                 /* Setup IOCB count. */
7285                 sp->iocb = ha->ms_cmd;
7286                 if (pkt->pkt_resp_cookie_cnt > MS_DATA_SEGMENTS) {
7287                         cnt = pkt->pkt_resp_cookie_cnt - MS_DATA_SEGMENTS;
7288                         sp->req_cnt =
7289                             (uint16_t)(cnt / CONT_TYPE_1_DATA_SEGMENTS);
7290                         if (cnt % CONT_TYPE_1_DATA_SEGMENTS) {
7291                                 sp->req_cnt = (uint16_t)(sp->req_cnt + 2);
7292                         } else {
7293                                 sp->req_cnt++;
7294                         }
7295                 } else {
7296                         sp->req_cnt = 1;
7297                 }
7298                 rval = ql_start_cmd(ha, tq, pkt, sp);
7299 
7300                 QL_PRINT_3(CE_CONT, "(%d): done, ql_start_cmd=%xh\n",
7301                     ha->instance, rval);
7302 
7303                 return (rval);
7304 
7305         default:
7306                 EL(ha, "unknown fcstype=%xh\n", hdr.ct_fcstype);
7307                 rval = QL_FUNCTION_PARAMETER_ERROR;
7308                 break;
7309         }
7310 
7311         if (rval != QL_SUCCESS) {
7312                 /* Build RJT. */
7313                 rjt.ls_code.ls_code = LA_ELS_RJT;
7314                 rjt.reason = FC_REASON_CMD_UNSUPPORTED;
7315 
7316                 ddi_rep_put8(pkt->pkt_resp_acc, (uint8_t *)&rjt,
7317                     (uint8_t *)pkt->pkt_resp, sizeof (rjt), DDI_DEV_AUTOINCR);
7318 
7319                 pkt->pkt_state = FC_PKT_LOCAL_RJT;
7320                 pkt->pkt_reason = FC_REASON_UNSUPPORTED;
7321                 EL(ha, "LA_ELS_RJT, FC_REASON_UNSUPPORTED\n");
7322         }
7323 
7324         /* Do command callback. */
7325         if (!(pkt->pkt_tran_flags & FC_TRAN_NO_INTR) && pkt->pkt_comp) {
7326                 ql_awaken_task_daemon(ha, (ql_srb_t *)pkt->pkt_fca_private,
7327                     0, 0);
7328         }
7329 
7330         QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
7331 
7332         return (FC_SUCCESS);
7333 }
7334 
7335 /*
7336  * ql_cthdr_endian
7337  *      Change endianess of ct passthrough header and payload.
7338  *
7339  * Input:
7340  *      acc_handle:     DMA buffer access handle.
7341  *      ct_hdr:         Pointer to header.
7342  *      restore:        Restore first flag.
7343  *
7344  * Context:
7345  *      Interrupt or Kernel context, no mailbox commands allowed.
7346  */
7347 void
7348 ql_cthdr_endian(ddi_acc_handle_t acc_handle, caddr_t ct_hdr,
7349     boolean_t restore)
7350 {
7351         uint8_t         i, *bp;
7352         fc_ct_header_t  hdr;
7353         uint32_t        *hdrp = (uint32_t *)&hdr;
7354 
7355         ddi_rep_get8(acc_handle, (uint8_t *)&hdr,
7356             (uint8_t *)ct_hdr, sizeof (hdr), DDI_DEV_AUTOINCR);
7357 
7358         if (restore) {
7359                 for (i = 0; i < ((sizeof (hdr)) / (sizeof (uint32_t))); i++) {
7360                         *hdrp = BE_32(*hdrp);
7361                         hdrp++;
7362                 }
7363         }
7364 
7365         if (hdr.ct_fcstype == FCSTYPE_DIRECTORY) {
7366                 bp = (uint8_t *)ct_hdr + sizeof (fc_ct_header_t);
7367 
7368                 switch (hdr.ct_cmdrsp) {
7369                 case NS_GA_NXT:
7370                 case NS_GPN_ID:
7371                 case NS_GNN_ID:
7372                 case NS_GCS_ID:
7373                 case NS_GFT_ID:
7374                 case NS_GSPN_ID:
7375                 case NS_GPT_ID:
7376                 case NS_GID_FT:
7377                 case NS_GID_PT:
7378                 case NS_RPN_ID:
7379                 case NS_RNN_ID:
7380                 case NS_RSPN_ID:
7381                 case NS_DA_ID:
7382                         BIG_ENDIAN_32(bp);
7383                         break;
7384                 case NS_RFT_ID:
7385                 case NS_RCS_ID:
7386                 case NS_RPT_ID:
7387                         BIG_ENDIAN_32(bp);
7388                         bp += 4;
7389                         BIG_ENDIAN_32(bp);
7390                         break;
7391                 case NS_GNN_IP:
7392                 case NS_GIPA_IP:
7393                         BIG_ENDIAN(bp, 16);
7394                         break;
7395                 case NS_RIP_NN:
7396                         bp += 8;
7397                         BIG_ENDIAN(bp, 16);
7398                         break;
7399                 case NS_RIPA_NN:
7400                         bp += 8;
7401                         BIG_ENDIAN_64(bp);
7402                         break;
7403                 default:
7404                         break;
7405                 }
7406         }
7407 
7408         if (restore == B_FALSE) {
7409                 for (i = 0; i < ((sizeof (hdr)) / (sizeof (uint32_t))); i++) {
7410                         *hdrp = BE_32(*hdrp);
7411                         hdrp++;
7412                 }
7413         }
7414 
7415         ddi_rep_put8(acc_handle, (uint8_t *)&hdr,
7416             (uint8_t *)ct_hdr, sizeof (hdr), DDI_DEV_AUTOINCR);
7417 }
7418 
7419 /*
7420  * ql_start_cmd
7421  *      Finishes starting fibre channel protocol (FCP) command.
7422  *
7423  * Input:
7424  *      ha:     adapter state pointer.
7425  *      tq:     target queue pointer.
7426  *      pkt:    pointer to fc_packet.
7427  *      sp:     SRB pointer.
7428  *
7429  * Context:
7430  *      Kernel context.
7431  */
7432 static int
7433 ql_start_cmd(ql_adapter_state_t *ha, ql_tgt_t *tq, fc_packet_t *pkt,
7434     ql_srb_t *sp)
7435 {
7436         int             rval = FC_SUCCESS;
7437         time_t          poll_wait = 0;
7438         ql_lun_t        *lq = sp->lun_queue;
7439 
7440         QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
7441 
7442         sp->handle = 0;
7443 
7444         /* Set poll for finish. */
7445         if (pkt->pkt_tran_flags & FC_TRAN_NO_INTR) {
7446                 sp->flags |= SRB_POLL;
7447                 if (pkt->pkt_timeout == 0) {
7448                         pkt->pkt_timeout = SCSI_POLL_TIMEOUT;
7449                 }
7450         }
7451 
7452         /* Acquire device queue lock. */
7453         DEVICE_QUEUE_LOCK(tq);
7454 
7455         /*
7456          * If we need authentication, report device busy to
7457          * upper layers to retry later
7458          */
7459         if (tq->flags & (TQF_RSCN_RCVD | TQF_NEED_AUTHENTICATION)) {
7460                 DEVICE_QUEUE_UNLOCK(tq);
7461                 EL(ha, "failed, FC_DEVICE_BUSY=%xh, d_id=%xh\n", tq->flags,
7462                     tq->d_id.b24);
7463                 return (FC_DEVICE_BUSY);
7464         }
7465 
7466         /* Insert command onto watchdog queue. */
7467         if (!(pkt->pkt_tran_flags & FC_TRAN_DUMPING)) {
7468                 ql_timeout_insert(ha, tq, sp);
7469         } else {
7470                 /*
7471                  * Run dump requests in polled mode as kernel threads
7472                  * and interrupts may have been disabled.
7473                  */
7474                 sp->flags |= SRB_POLL;
7475                 sp->init_wdg_q_time = 0;
7476                 sp->isp_timeout = 0;
7477         }
7478 
7479         /* If a polling command setup wait time. */
7480         if (sp->flags & SRB_POLL) {
7481                 if (sp->flags & SRB_WATCHDOG_ENABLED) {
7482                         poll_wait = (sp->wdg_q_time + 2) * WATCHDOG_TIME;
7483                 } else {
7484                         poll_wait = pkt->pkt_timeout;
7485                 }
7486         }
7487 
7488         if (ha->pha->flags & ABORT_CMDS_LOOP_DOWN_TMO &&
7489             (CFG_IST(ha, CFG_ENABLE_LINK_DOWN_REPORTING))) {
7490                 /* Set ending status. */
7491                 sp->pkt->pkt_reason = CS_PORT_UNAVAILABLE;
7492 
7493                 /* Call done routine to handle completions. */
7494                 sp->cmd.next = NULL;
7495                 DEVICE_QUEUE_UNLOCK(tq);
7496                 ql_done(&sp->cmd);
7497         } else {
7498                 if (ddi_in_panic() && (sp->flags & SRB_POLL)) {
7499                         int do_lip = 0;
7500 
7501                         DEVICE_QUEUE_UNLOCK(tq);
7502 
7503                         ADAPTER_STATE_LOCK(ha);
7504                         if ((do_lip = ha->pha->lip_on_panic) == 0) {
7505                                 ha->pha->lip_on_panic++;
7506                         }
7507                         ADAPTER_STATE_UNLOCK(ha);
7508 
7509                         if (!do_lip) {
7510 
7511                                 /*
7512                                  * That Qlogic F/W performs PLOGI, PRLI, etc
7513                                  * is helpful here. If a PLOGI fails for some
7514                                  * reason, you would get CS_PORT_LOGGED_OUT
7515                                  * or some such error; and we should get a
7516                                  * careful polled mode login kicked off inside
7517                                  * of this driver itself. You don't have FC
7518                                  * transport's services as all threads are
7519                                  * suspended, interrupts disabled, and so
7520                                  * on. Right now we do re-login if the packet
7521                                  * state isn't FC_PKT_SUCCESS.
7522                                  */
7523                                 (void) ql_abort_isp(ha);
7524                         }
7525 
7526                         ql_start_iocb(ha, sp);
7527                 } else {
7528                         /* Add the command to the device queue */
7529                         if (pkt->pkt_tran_flags & FC_TRAN_HI_PRIORITY) {
7530                                 ql_add_link_t(&lq->cmd, &sp->cmd);
7531                         } else {
7532                                 ql_add_link_b(&lq->cmd, &sp->cmd);
7533                         }
7534 
7535                         sp->flags |= SRB_IN_DEVICE_QUEUE;
7536 
7537                         /* Check whether next message can be processed */
7538                         ql_next(ha, lq);
7539                 }
7540         }
7541 
7542         /* If polling, wait for finish. */
7543         if (poll_wait) {
7544                 if (ql_poll_cmd(ha, sp, poll_wait) != QL_SUCCESS) {
7545                         int     res;
7546 
7547                         res = ql_abort((opaque_t)ha, pkt, 0);
7548                         if (res != FC_SUCCESS && res != FC_ABORTED) {
7549                                 DEVICE_QUEUE_LOCK(tq);
7550                                 ql_remove_link(&lq->cmd, &sp->cmd);
7551                                 sp->flags &= ~SRB_IN_DEVICE_QUEUE;
7552                                 DEVICE_QUEUE_UNLOCK(tq);
7553                         }
7554                 }
7555 
7556                 if (pkt->pkt_state != FC_PKT_SUCCESS) {
7557                         EL(ha, "failed, FC_TRANSPORT_ERROR\n");
7558                         rval = FC_TRANSPORT_ERROR;
7559                 }
7560 
7561                 if (ddi_in_panic()) {
7562                         if (pkt->pkt_state != FC_PKT_SUCCESS) {
7563                                 port_id_t d_id;
7564 
7565                                 /*
7566                                  * successful LOGIN implies by design
7567                                  * that PRLI also succeeded for disks
7568                                  * Note also that there is no special
7569                                  * mailbox command to send PRLI.
7570                                  */
7571                                 d_id.b24 = pkt->pkt_cmd_fhdr.d_id;
7572                                 (void) ql_login_port(ha, d_id);
7573                         }
7574                 }
7575 
7576                 /*
7577                  * This should only happen during CPR dumping
7578                  */
7579                 if (!(pkt->pkt_tran_flags & FC_TRAN_NO_INTR) &&
7580                     pkt->pkt_comp) {
7581                         sp->flags &= ~SRB_POLL;
7582                         (*pkt->pkt_comp)(pkt);
7583                 }
7584         }
7585 
7586         QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
7587 
7588         return (rval);
7589 }
7590 
7591 /*
7592  * ql_poll_cmd
7593  *      Polls commands for completion.
7594  *
7595  * Input:
7596  *      ha = adapter state pointer.
7597  *      sp = SRB command pointer.
7598  *      poll_wait = poll wait time in seconds.
7599  *
7600  * Returns:
7601  *      QL local function return status code.
7602  *
7603  * Context:
7604  *      Kernel context.
7605  */
7606 static int
7607 ql_poll_cmd(ql_adapter_state_t *vha, ql_srb_t *sp, time_t poll_wait)
7608 {
7609         int                     rval = QL_SUCCESS;
7610         time_t                  msecs_left = poll_wait * 100;   /* 10ms inc */
7611         ql_adapter_state_t      *ha = vha->pha;
7612 
7613         QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
7614 
7615         while (sp->flags & SRB_POLL) {
7616 
7617                 if ((ha->flags & INTERRUPTS_ENABLED) == 0 ||
7618                     ha->idle_timer >= 15 || ddi_in_panic()) {
7619 
7620                         /* If waiting for restart, do it now. */
7621                         if (ha->port_retry_timer != 0) {
7622                                 ADAPTER_STATE_LOCK(ha);
7623                                 ha->port_retry_timer = 0;
7624                                 ADAPTER_STATE_UNLOCK(ha);
7625 
7626                                 TASK_DAEMON_LOCK(ha);
7627                                 ha->task_daemon_flags |= PORT_RETRY_NEEDED;
7628                                 TASK_DAEMON_UNLOCK(ha);
7629                         }
7630 
7631                         if (INTERRUPT_PENDING(ha)) {
7632                                 (void) ql_isr((caddr_t)ha);
7633                                 INTR_LOCK(ha);
7634                                 ha->intr_claimed = TRUE;
7635                                 INTR_UNLOCK(ha);
7636                         }
7637 
7638                         /*
7639                          * Call task thread function in case the
7640                          * daemon is not running.
7641                          */
7642                         TASK_DAEMON_LOCK(ha);
7643 
7644                         if (!ddi_in_panic() && QL_DAEMON_NOT_ACTIVE(ha) &&
7645                             QL_TASK_PENDING(ha)) {
7646                                 ha->task_daemon_flags |= TASK_THREAD_CALLED;
7647                                 ql_task_thread(ha);
7648                                 ha->task_daemon_flags &= ~TASK_THREAD_CALLED;
7649                         }
7650 
7651                         TASK_DAEMON_UNLOCK(ha);
7652                 }
7653 
7654                 if (msecs_left < 10) {
7655                         rval = QL_FUNCTION_TIMEOUT;
7656                         break;
7657                 }
7658 
7659                 /*
7660                  * Polling interval is 10 milli seconds; Increasing
7661                  * the polling interval to seconds since disk IO
7662                  * timeout values are ~60 seconds is tempting enough,
7663                  * but CPR dump time increases, and so will the crash
7664                  * dump time; Don't toy with the settings without due
7665                  * consideration for all the scenarios that will be
7666                  * impacted.
7667                  */
7668                 ql_delay(ha, 10000);
7669                 msecs_left -= 10;
7670         }
7671 
7672         QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
7673 
7674         return (rval);
7675 }
7676 
7677 /*
7678  * ql_next
7679  *      Retrieve and process next job in the device queue.
7680  *
7681  * Input:
7682  *      ha:     adapter state pointer.
7683  *      lq:     LUN queue pointer.
7684  *      DEVICE_QUEUE_LOCK must be already obtained.
7685  *
7686  * Output:
7687  *      Releases DEVICE_QUEUE_LOCK upon exit.
7688  *
7689  * Context:
7690  *      Interrupt or Kernel context, no mailbox commands allowed.
7691  */
7692 void
7693 ql_next(ql_adapter_state_t *vha, ql_lun_t *lq)
7694 {
7695         ql_srb_t                *sp;
7696         ql_link_t               *link;
7697         ql_tgt_t                *tq = lq->target_queue;
7698         ql_adapter_state_t      *ha = vha->pha;
7699 
7700         QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
7701 
7702         if (ddi_in_panic()) {
7703                 DEVICE_QUEUE_UNLOCK(tq);
7704                 QL_PRINT_3(CE_CONT, "(%d): panic/active exit\n",
7705                     ha->instance);
7706                 return;
7707         }
7708 
7709         while ((link = lq->cmd.first) != NULL) {
7710                 sp = link->base_address;
7711 
7712                 /* Exit if can not start commands. */
7713                 if (DRIVER_SUSPENDED(ha) ||
7714                     (ha->flags & ONLINE) == 0 ||
7715                     !VALID_DEVICE_ID(ha, tq->loop_id) ||
7716                     sp->flags & SRB_ABORT ||
7717                     tq->flags & (TQF_RSCN_RCVD | TQF_NEED_AUTHENTICATION |
7718                     TQF_QUEUE_SUSPENDED)) {
7719                         EL(vha, "break, d_id=%xh, tdf=%xh, tqf=%xh, spf=%xh, "
7720                             "haf=%xh, loop_id=%xh\n", tq->d_id.b24,
7721                             ha->task_daemon_flags, tq->flags, sp->flags,
7722                             ha->flags, tq->loop_id);
7723                         break;
7724                 }
7725 
7726                 /*
7727                  * Find out the LUN number for untagged command use.
7728                  * If there is an untagged command pending for the LUN,
7729                  * we would not submit another untagged command
7730                  * or if reached LUN execution throttle.
7731                  */
7732                 if (sp->flags & SRB_FCP_CMD_PKT) {
7733                         if (lq->flags & LQF_UNTAGGED_PENDING ||
7734                             lq->lun_outcnt >= ha->execution_throttle) {
7735                                 QL_PRINT_8(CE_CONT, "(%d): break, d_id=%xh, "
7736                                     "lf=%xh, lun_outcnt=%xh\n", ha->instance,
7737                                     tq->d_id.b24, lq->flags, lq->lun_outcnt);
7738                                 break;
7739                         }
7740                         if (sp->fcp->fcp_cntl.cntl_qtype ==
7741                             FCP_QTYPE_UNTAGGED) {
7742                                 /*
7743                                  * Set the untagged-flag for the LUN
7744                                  * so that no more untagged commands
7745                                  * can be submitted for this LUN.
7746                                  */
7747                                 lq->flags |= LQF_UNTAGGED_PENDING;
7748                         }
7749 
7750                         /* Count command as sent. */
7751                         lq->lun_outcnt++;
7752                 }
7753 
7754                 /* Remove srb from device queue. */
7755                 ql_remove_link(&lq->cmd, &sp->cmd);
7756                 sp->flags &= ~SRB_IN_DEVICE_QUEUE;
7757 
7758                 tq->outcnt++;
7759 
7760                 ql_start_iocb(vha, sp);
7761         }
7762 
7763         /* Release device queue lock. */
7764         DEVICE_QUEUE_UNLOCK(tq);
7765 
7766         QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
7767 }
7768 
7769 /*
7770  * ql_done
7771  *      Process completed commands.
7772  *
7773  * Input:
7774  *      link:   first command link in chain.
7775  *
7776  * Context:
7777  *      Interrupt or Kernel context, no mailbox commands allowed.
7778  */
7779 void
7780 ql_done(ql_link_t *link)
7781 {
7782         ql_adapter_state_t      *ha;
7783         ql_link_t               *next_link;
7784         ql_srb_t                *sp;
7785         ql_tgt_t                *tq;
7786         ql_lun_t                *lq;
7787 
7788         QL_PRINT_3(CE_CONT, "started\n");
7789 
7790         for (; link != NULL; link = next_link) {
7791                 next_link = link->next;
7792                 sp = link->base_address;
7793                 ha = sp->ha;
7794 
7795                 if (sp->flags & SRB_UB_CALLBACK) {
7796                         QL_UB_LOCK(ha);
7797                         if (sp->flags & SRB_UB_IN_ISP) {
7798                                 if (ha->ub_outcnt != 0) {
7799                                         ha->ub_outcnt--;
7800                                 }
7801                                 QL_UB_UNLOCK(ha);
7802                                 ql_isp_rcvbuf(ha);
7803                                 QL_UB_LOCK(ha);
7804                         }
7805                         QL_UB_UNLOCK(ha);
7806                         ql_awaken_task_daemon(ha, sp, 0, 0);
7807                 } else {
7808                         /* Free outstanding command slot. */
7809                         if (sp->handle != 0) {
7810                                 ha->outstanding_cmds[
7811                                     sp->handle & OSC_INDEX_MASK] = NULL;
7812                                 sp->handle = 0;
7813                                 sp->flags &= ~SRB_IN_TOKEN_ARRAY;
7814                         }
7815 
7816                         /* Acquire device queue lock. */
7817                         lq = sp->lun_queue;
7818                         tq = lq->target_queue;
7819                         DEVICE_QUEUE_LOCK(tq);
7820 
7821                         /* Decrement outstanding commands on device. */
7822                         if (tq->outcnt != 0) {
7823                                 tq->outcnt--;
7824                         }
7825 
7826                         if (sp->flags & SRB_FCP_CMD_PKT) {
7827                                 if (sp->fcp->fcp_cntl.cntl_qtype ==
7828                                     FCP_QTYPE_UNTAGGED) {
7829                                         /*
7830                                          * Clear the flag for this LUN so that
7831                                          * untagged commands can be submitted
7832                                          * for it.
7833                                          */
7834                                         lq->flags &= ~LQF_UNTAGGED_PENDING;
7835                                 }
7836 
7837                                 if (lq->lun_outcnt != 0) {
7838                                         lq->lun_outcnt--;
7839                                 }
7840                         }
7841 
7842                         /* Reset port down retry count on good completion. */
7843                         if (sp->pkt->pkt_reason == CS_COMPLETE) {
7844                                 tq->port_down_retry_count =
7845                                     ha->port_down_retry_count;
7846                                 tq->qfull_retry_count = ha->qfull_retry_count;
7847                         }
7848 
7849 
7850                         /* Alter aborted status for fast timeout feature */
7851                         if (CFG_IST(ha, CFG_FAST_TIMEOUT) &&
7852                             (sp->flags & (SRB_MS_PKT | SRB_ELS_PKT) ||
7853                             !(tq->flags & TQF_NEED_AUTHENTICATION)) &&
7854                             sp->flags & SRB_RETRY &&
7855                             (sp->flags & SRB_WATCHDOG_ENABLED &&
7856                             sp->wdg_q_time > 1)) {
7857                                 EL(ha, "fast abort modify change\n");
7858                                 sp->flags &= ~(SRB_RETRY);
7859                                 sp->pkt->pkt_reason = CS_TIMEOUT;
7860                         }
7861 
7862                         /* Place request back on top of target command queue */
7863                         if ((sp->flags & (SRB_MS_PKT | SRB_ELS_PKT) ||
7864                             !(tq->flags & TQF_NEED_AUTHENTICATION)) &&
7865                             sp->flags & SRB_RETRY &&
7866                             (sp->flags & SRB_WATCHDOG_ENABLED &&
7867                             sp->wdg_q_time > 1)) {
7868                                 sp->flags &= ~(SRB_ISP_STARTED |
7869                                     SRB_ISP_COMPLETED | SRB_RETRY);
7870 
7871                                 /* Reset watchdog timer */
7872                                 sp->wdg_q_time = sp->init_wdg_q_time;
7873 
7874                                 /* Issue marker command on reset status. */
7875                                 if (!(ha->task_daemon_flags & LOOP_DOWN) &&
7876                                     (sp->pkt->pkt_reason == CS_RESET ||
7877                                     (CFG_IST(ha, CFG_CTRL_24258081) &&
7878                                     sp->pkt->pkt_reason == CS_ABORTED))) {
7879                                         (void) ql_marker(ha, tq->loop_id, 0,
7880                                             MK_SYNC_ID);
7881                                 }
7882 
7883                                 ql_add_link_t(&lq->cmd, &sp->cmd);
7884                                 sp->flags |= SRB_IN_DEVICE_QUEUE;
7885                                 ql_next(ha, lq);
7886                         } else {
7887                                 /* Remove command from watchdog queue. */
7888                                 if (sp->flags & SRB_WATCHDOG_ENABLED) {
7889                                         ql_remove_link(&tq->wdg, &sp->wdg);
7890                                         sp->flags &= ~SRB_WATCHDOG_ENABLED;
7891                                 }
7892 
7893                                 if (lq->cmd.first != NULL) {
7894                                         ql_next(ha, lq);
7895                                 } else {
7896                                         /* Release LU queue specific lock. */
7897                                         DEVICE_QUEUE_UNLOCK(tq);
7898                                         if (ha->pha->pending_cmds.first !=
7899                                             NULL) {
7900                                                 ql_start_iocb(ha, NULL);
7901                                         }
7902                                 }
7903 
7904                                 /* Sync buffers if required.  */
7905                                 if (sp->flags & (SRB_MS_PKT | SRB_ELS_PKT)) {
7906                                         (void) ddi_dma_sync(
7907                                             sp->pkt->pkt_resp_dma,
7908                                             0, 0, DDI_DMA_SYNC_FORCPU);
7909                                 }
7910 
7911                                 /* Map ISP completion codes. */
7912                                 sp->pkt->pkt_expln = FC_EXPLN_NONE;
7913                                 sp->pkt->pkt_action = FC_ACTION_RETRYABLE;
7914                                 switch (sp->pkt->pkt_reason) {
7915                                 case CS_COMPLETE:
7916                                         sp->pkt->pkt_state = FC_PKT_SUCCESS;
7917                                         break;
7918                                 case CS_RESET:
7919                                         /* Issue marker command. */
7920                                         if (!(ha->task_daemon_flags &
7921                                             LOOP_DOWN)) {
7922                                                 (void) ql_marker(ha,
7923                                                     tq->loop_id, 0,
7924                                                     MK_SYNC_ID);
7925                                         }
7926                                         sp->pkt->pkt_state =
7927                                             FC_PKT_PORT_OFFLINE;
7928                                         sp->pkt->pkt_reason =
7929                                             FC_REASON_ABORTED;
7930                                         break;
7931                                 case CS_RESOUCE_UNAVAILABLE:
7932                                         sp->pkt->pkt_state = FC_PKT_LOCAL_BSY;
7933                                         sp->pkt->pkt_reason =
7934                                             FC_REASON_PKT_BUSY;
7935                                         break;
7936 
7937                                 case CS_TIMEOUT:
7938                                         sp->pkt->pkt_state = FC_PKT_TIMEOUT;
7939                                         sp->pkt->pkt_reason =
7940                                             FC_REASON_HW_ERROR;
7941                                         break;
7942                                 case CS_DATA_OVERRUN:
7943                                         sp->pkt->pkt_state = FC_PKT_LOCAL_RJT;
7944                                         sp->pkt->pkt_reason =
7945                                             FC_REASON_OVERRUN;
7946                                         break;
7947                                 case CS_PORT_UNAVAILABLE:
7948                                 case CS_PORT_LOGGED_OUT:
7949                                         sp->pkt->pkt_state =
7950                                             FC_PKT_PORT_OFFLINE;
7951                                         sp->pkt->pkt_reason =
7952                                             FC_REASON_LOGIN_REQUIRED;
7953                                         ql_send_logo(ha, tq, NULL);
7954                                         break;
7955                                 case CS_PORT_CONFIG_CHG:
7956                                         sp->pkt->pkt_state =
7957                                             FC_PKT_PORT_OFFLINE;
7958                                         sp->pkt->pkt_reason =
7959                                             FC_REASON_OFFLINE;
7960                                         break;
7961                                 case CS_QUEUE_FULL:
7962                                         sp->pkt->pkt_state = FC_PKT_LOCAL_RJT;
7963                                         sp->pkt->pkt_reason = FC_REASON_QFULL;
7964                                         break;
7965 
7966                                 case CS_ABORTED:
7967                                         DEVICE_QUEUE_LOCK(tq);
7968                                         if (tq->flags & (TQF_RSCN_RCVD |
7969                                             TQF_NEED_AUTHENTICATION)) {
7970                                                 sp->pkt->pkt_state =
7971                                                     FC_PKT_PORT_OFFLINE;
7972                                                 sp->pkt->pkt_reason =
7973                                                     FC_REASON_LOGIN_REQUIRED;
7974                                         } else {
7975                                                 sp->pkt->pkt_state =
7976                                                     FC_PKT_LOCAL_RJT;
7977                                                 sp->pkt->pkt_reason =
7978                                                     FC_REASON_ABORTED;
7979                                         }
7980                                         DEVICE_QUEUE_UNLOCK(tq);
7981                                         break;
7982 
7983                                 case CS_TRANSPORT:
7984                                         sp->pkt->pkt_state = FC_PKT_LOCAL_RJT;
7985                                         sp->pkt->pkt_reason =
7986                                             FC_PKT_TRAN_ERROR;
7987                                         break;
7988 
7989                                 case CS_DATA_UNDERRUN:
7990                                         sp->pkt->pkt_state = FC_PKT_LOCAL_RJT;
7991                                         sp->pkt->pkt_reason =
7992                                             FC_REASON_UNDERRUN;
7993                                         break;
7994                                 case CS_DMA_ERROR:
7995                                 case CS_BAD_PAYLOAD:
7996                                 case CS_UNKNOWN:
7997                                 case CS_CMD_FAILED:
7998                                 default:
7999                                         sp->pkt->pkt_state = FC_PKT_LOCAL_RJT;
8000                                         sp->pkt->pkt_reason =
8001                                             FC_REASON_HW_ERROR;
8002                                         break;
8003                                 }
8004 
8005                                 /* Now call the pkt completion callback */
8006                                 if (sp->flags & SRB_POLL) {
8007                                         sp->flags &= ~SRB_POLL;
8008                                 } else if (sp->pkt->pkt_comp) {
8009                                         if (sp->pkt->pkt_tran_flags &
8010                                             FC_TRAN_IMMEDIATE_CB) {
8011                                                 (*sp->pkt->pkt_comp)(sp->pkt);
8012                                         } else {
8013                                                 ql_awaken_task_daemon(ha, sp,
8014                                                     0, 0);
8015                                         }
8016                                 }
8017                         }
8018                 }
8019         }
8020 
8021         QL_PRINT_3(CE_CONT, "done\n");
8022 }
8023 
8024 /*
8025  * ql_awaken_task_daemon
8026  *      Adds command completion callback to callback queue and/or
8027  *      awakens task daemon thread.
8028  *
8029  * Input:
8030  *      ha:             adapter state pointer.
8031  *      sp:             srb pointer.
8032  *      set_flags:      task daemon flags to set.
8033  *      reset_flags:    task daemon flags to reset.
8034  *
8035  * Context:
8036  *      Interrupt or Kernel context, no mailbox commands allowed.
8037  */
8038 void
8039 ql_awaken_task_daemon(ql_adapter_state_t *vha, ql_srb_t *sp,
8040     uint32_t set_flags, uint32_t reset_flags)
8041 {
8042         ql_adapter_state_t      *ha = vha->pha;
8043 
8044         QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
8045 
8046         /* Acquire task daemon lock. */
8047         TASK_DAEMON_LOCK(ha);
8048 
8049         if (set_flags & ISP_ABORT_NEEDED) {
8050                 if (ha->task_daemon_flags & ABORT_ISP_ACTIVE) {
8051                         set_flags &= ~ISP_ABORT_NEEDED;
8052                 }
8053         }
8054 
8055         ha->task_daemon_flags |= set_flags;
8056         ha->task_daemon_flags &= ~reset_flags;
8057 
8058         if (QL_DAEMON_SUSPENDED(ha)) {
8059                 if (sp != NULL) {
8060                         TASK_DAEMON_UNLOCK(ha);
8061 
8062                         /* Do callback. */
8063                         if (sp->flags & SRB_UB_CALLBACK) {
8064                                 ql_unsol_callback(sp);
8065                         } else {
8066                                 (*sp->pkt->pkt_comp)(sp->pkt);
8067                         }
8068                 } else {
8069                         if (!(curthread->t_flag & T_INTR_THREAD) &&
8070                             !(ha->task_daemon_flags & TASK_THREAD_CALLED)) {
8071                                 ha->task_daemon_flags |= TASK_THREAD_CALLED;
8072                                 ql_task_thread(ha);
8073                                 ha->task_daemon_flags &= ~TASK_THREAD_CALLED;
8074                         }
8075 
8076                         TASK_DAEMON_UNLOCK(ha);
8077                 }
8078         } else {
8079                 if (sp != NULL) {
8080                         ql_add_link_b(&ha->callback_queue, &sp->cmd);
8081                 }
8082 
8083                 if (ha->task_daemon_flags & TASK_DAEMON_SLEEPING_FLG) {
8084                         cv_broadcast(&ha->cv_task_daemon);
8085                 }
8086                 TASK_DAEMON_UNLOCK(ha);
8087         }
8088 
8089         QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
8090 }
8091 
8092 /*
8093  * ql_task_daemon
8094  *      Thread that is awaken by the driver when a
8095  *      background needs to be done.
8096  *
8097  * Input:
8098  *      arg = adapter state pointer.
8099  *
8100  * Context:
8101  *      Kernel context.
8102  */
8103 static void
8104 ql_task_daemon(void *arg)
8105 {
8106         ql_adapter_state_t      *ha = (void *)arg;
8107 
8108         QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
8109 
8110         CALLB_CPR_INIT(&ha->cprinfo, &ha->task_daemon_mutex, callb_generic_cpr,
8111             "ql_task_daemon");
8112 
8113         /* Acquire task daemon lock. */
8114         TASK_DAEMON_LOCK(ha);
8115 
8116         ha->task_daemon_flags |= TASK_DAEMON_ALIVE_FLG;
8117 
8118         while ((ha->task_daemon_flags & TASK_DAEMON_STOP_FLG) == 0) {
8119                 ql_task_thread(ha);
8120 
8121                 QL_PRINT_3(CE_CONT, "(%d): Going to sleep\n", ha->instance);
8122 
8123                 /*
8124                  * Before we wait on the conditional variable, we
8125                  * need to check if STOP_FLG is set for us to terminate
8126                  */
8127                 if (ha->task_daemon_flags & TASK_DAEMON_STOP_FLG) {
8128                         break;
8129                 }
8130 
8131                 /*LINTED [Solaris CALLB_CPR_SAFE_BEGIN Lint error]*/
8132                 CALLB_CPR_SAFE_BEGIN(&ha->cprinfo);
8133 
8134                 ha->task_daemon_flags |= TASK_DAEMON_SLEEPING_FLG;
8135 
8136                 /* If killed, stop task daemon */
8137                 if (cv_wait_sig(&ha->cv_task_daemon,
8138                     &ha->task_daemon_mutex) == 0) {
8139                         ha->task_daemon_flags |= TASK_DAEMON_STOP_FLG;
8140                 }
8141 
8142                 ha->task_daemon_flags &= ~TASK_DAEMON_SLEEPING_FLG;
8143 
8144                 /*LINTED [Solaris CALLB_CPR_SAFE_END Lint error]*/
8145                 CALLB_CPR_SAFE_END(&ha->cprinfo, &ha->task_daemon_mutex);
8146 
8147                 QL_PRINT_3(CE_CONT, "(%d): Awakened\n", ha->instance);
8148         }
8149 
8150         ha->task_daemon_flags &= ~(TASK_DAEMON_STOP_FLG |
8151             TASK_DAEMON_ALIVE_FLG);
8152 
8153         /*LINTED [Solaris CALLB_CPR_EXIT Lint error]*/
8154         CALLB_CPR_EXIT(&ha->cprinfo);
8155 
8156         QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
8157 
8158         thread_exit();
8159 }
8160 
8161 /*
8162  * ql_task_thread
8163  *      Thread run by daemon.
8164  *
8165  * Input:
8166  *      ha = adapter state pointer.
8167  *      TASK_DAEMON_LOCK must be acquired prior to call.
8168  *
8169  * Context:
8170  *      Kernel context.
8171  */
8172 static void
8173 ql_task_thread(ql_adapter_state_t *ha)
8174 {
8175         int                     loop_again;
8176         ql_srb_t                *sp;
8177         ql_head_t               *head;
8178         ql_link_t               *link;
8179         caddr_t                 msg;
8180         ql_adapter_state_t      *vha;
8181 
8182         do {
8183                 QL_PRINT_3(CE_CONT, "(%d): task_daemon_flags=%xh\n",
8184                     ha->instance, ha->task_daemon_flags);
8185 
8186                 loop_again = FALSE;
8187 
8188                 QL_PM_LOCK(ha);
8189                 if (ha->power_level != PM_LEVEL_D0) {
8190                         QL_PM_UNLOCK(ha);
8191                         ha->task_daemon_flags |= TASK_DAEMON_STALLED_FLG;
8192                         break;
8193                 }
8194                 QL_PM_UNLOCK(ha);
8195 
8196                 /* IDC event. */
8197                 if (ha->task_daemon_flags & IDC_EVENT) {
8198                         ha->task_daemon_flags &= ~IDC_EVENT;
8199                         TASK_DAEMON_UNLOCK(ha);
8200                         ql_process_idc_event(ha);
8201                         TASK_DAEMON_LOCK(ha);
8202                         loop_again = TRUE;
8203                 }
8204 
8205                 if (ha->flags & ADAPTER_SUSPENDED || ha->task_daemon_flags &
8206                     (TASK_DAEMON_STOP_FLG | DRIVER_STALL) ||
8207                     (ha->flags & ONLINE) == 0) {
8208                         ha->task_daemon_flags |= TASK_DAEMON_STALLED_FLG;
8209                         break;
8210                 }
8211                 ha->task_daemon_flags &= ~TASK_DAEMON_STALLED_FLG;
8212 
8213                 if (ha->task_daemon_flags & ISP_ABORT_NEEDED) {
8214                         TASK_DAEMON_UNLOCK(ha);
8215                         if (ha->log_parity_pause == B_TRUE) {
8216                                 (void) ql_flash_errlog(ha,
8217                                     FLASH_ERRLOG_PARITY_ERR, 0,
8218                                     MSW(ha->parity_stat_err),
8219                                     LSW(ha->parity_stat_err));
8220                                 ha->log_parity_pause = B_FALSE;
8221                         }
8222                         ql_port_state(ha, FC_STATE_OFFLINE, FC_STATE_CHANGE);
8223                         TASK_DAEMON_LOCK(ha);
8224                         loop_again = TRUE;
8225                 }
8226 
8227                 /* Idle Check. */
8228                 if (ha->task_daemon_flags & TASK_DAEMON_IDLE_CHK_FLG) {
8229                         ha->task_daemon_flags &= ~TASK_DAEMON_IDLE_CHK_FLG;
8230                         if (!(ha->task_daemon_flags & QL_SUSPENDED)) {
8231                                 TASK_DAEMON_UNLOCK(ha);
8232                                 ql_idle_check(ha);
8233                                 TASK_DAEMON_LOCK(ha);
8234                                 loop_again = TRUE;
8235                         }
8236                 }
8237 
8238                 /* Crystal+ port#0 bypass transition */
8239                 if (ha->task_daemon_flags & HANDLE_PORT_BYPASS_CHANGE) {
8240                         ha->task_daemon_flags &= ~HANDLE_PORT_BYPASS_CHANGE;
8241                         TASK_DAEMON_UNLOCK(ha);
8242                         (void) ql_initiate_lip(ha);
8243                         TASK_DAEMON_LOCK(ha);
8244                         loop_again = TRUE;
8245                 }
8246 
8247                 /* Abort queues needed. */
8248                 if (ha->task_daemon_flags & ABORT_QUEUES_NEEDED) {
8249                         ha->task_daemon_flags &= ~ABORT_QUEUES_NEEDED;
8250                         TASK_DAEMON_UNLOCK(ha);
8251                         ql_abort_queues(ha);
8252                         TASK_DAEMON_LOCK(ha);
8253                 }
8254 
8255                 /* Not suspended, awaken waiting routines. */
8256                 if (!(ha->task_daemon_flags & QL_SUSPENDED) &&
8257                     ha->task_daemon_flags & SUSPENDED_WAKEUP_FLG) {
8258                         ha->task_daemon_flags &= ~SUSPENDED_WAKEUP_FLG;
8259                         cv_broadcast(&ha->cv_dr_suspended);
8260                         loop_again = TRUE;
8261                 }
8262 
8263                 /* Handle RSCN changes. */
8264                 for (vha = ha; vha != NULL; vha = vha->vp_next) {
8265                         if (vha->task_daemon_flags & RSCN_UPDATE_NEEDED) {
8266                                 vha->task_daemon_flags &= ~RSCN_UPDATE_NEEDED;
8267                                 TASK_DAEMON_UNLOCK(ha);
8268                                 (void) ql_handle_rscn_update(vha);
8269                                 TASK_DAEMON_LOCK(ha);
8270                                 loop_again = TRUE;
8271                         }
8272                 }
8273 
8274                 /* Handle state changes. */
8275                 for (vha = ha; vha != NULL; vha = vha->vp_next) {
8276                         if (vha->task_daemon_flags & FC_STATE_CHANGE &&
8277                             !(ha->task_daemon_flags &
8278                             TASK_DAEMON_POWERING_DOWN)) {
8279                                 /* Report state change. */
8280                                 EL(vha, "state change = %xh\n", vha->state);
8281                                 vha->task_daemon_flags &= ~FC_STATE_CHANGE;
8282 
8283                                 if (vha->task_daemon_flags &
8284                                     COMMAND_WAIT_NEEDED) {
8285                                         vha->task_daemon_flags &=
8286                                             ~COMMAND_WAIT_NEEDED;
8287                                         if (!(ha->task_daemon_flags &
8288                                             COMMAND_WAIT_ACTIVE)) {
8289                                                 ha->task_daemon_flags |=
8290                                                     COMMAND_WAIT_ACTIVE;
8291                                                 TASK_DAEMON_UNLOCK(ha);
8292                                                 ql_cmd_wait(ha);
8293                                                 TASK_DAEMON_LOCK(ha);
8294                                                 ha->task_daemon_flags &=
8295                                                     ~COMMAND_WAIT_ACTIVE;
8296                                         }
8297                                 }
8298 
8299                                 msg = NULL;
8300                                 if (FC_PORT_STATE_MASK(vha->state) ==
8301                                     FC_STATE_OFFLINE) {
8302                                         if (vha->task_daemon_flags &
8303                                             STATE_ONLINE) {
8304                                                 if (ha->topology &
8305                                                     QL_LOOP_CONNECTION) {
8306                                                         msg = "Loop OFFLINE";
8307                                                 } else {
8308                                                         msg = "Link OFFLINE";
8309                                                 }
8310                                         }
8311                                         vha->task_daemon_flags &=
8312                                             ~STATE_ONLINE;
8313                                 } else if (FC_PORT_STATE_MASK(vha->state) ==
8314                                     FC_STATE_LOOP) {
8315                                         if (!(vha->task_daemon_flags &
8316                                             STATE_ONLINE)) {
8317                                                 msg = "Loop ONLINE";
8318                                         }
8319                                         vha->task_daemon_flags |= STATE_ONLINE;
8320                                 } else if (FC_PORT_STATE_MASK(vha->state) ==
8321                                     FC_STATE_ONLINE) {
8322                                         if (!(vha->task_daemon_flags &
8323                                             STATE_ONLINE)) {
8324                                                 msg = "Link ONLINE";
8325                                         }
8326                                         vha->task_daemon_flags |= STATE_ONLINE;
8327                                 } else {
8328                                         msg = "Unknown Link state";
8329                                 }
8330 
8331                                 if (msg != NULL) {
8332                                         cmn_err(CE_NOTE, "!Qlogic %s(%d,%d): "
8333                                             "%s", QL_NAME, ha->instance,
8334                                             vha->vp_index, msg);
8335                                 }
8336 
8337                                 if (vha->flags & FCA_BOUND) {
8338                                         QL_PRINT_10(CE_CONT, "(%d,%d): statec_"
8339                                             "cb state=%xh\n", ha->instance,
8340                                             vha->vp_index, vha->state);
8341                                         TASK_DAEMON_UNLOCK(ha);
8342                                         (vha->bind_info.port_statec_cb)
8343                                             (vha->bind_info.port_handle,
8344                                             vha->state);
8345                                         TASK_DAEMON_LOCK(ha);
8346                                 }
8347                                 loop_again = TRUE;
8348                         }
8349                 }
8350 
8351                 if (ha->task_daemon_flags & LIP_RESET_PENDING &&
8352                     !(ha->task_daemon_flags & TASK_DAEMON_POWERING_DOWN)) {
8353                         EL(ha, "processing LIP reset\n");
8354                         ha->task_daemon_flags &= ~LIP_RESET_PENDING;
8355                         TASK_DAEMON_UNLOCK(ha);
8356                         for (vha = ha; vha != NULL; vha = vha->vp_next) {
8357                                 if (vha->flags & FCA_BOUND) {
8358                                         QL_PRINT_10(CE_CONT, "(%d,%d): statec_"
8359                                             "cb reset\n", ha->instance,
8360                                             vha->vp_index);
8361                                         (vha->bind_info.port_statec_cb)
8362                                             (vha->bind_info.port_handle,
8363                                             FC_STATE_TARGET_PORT_RESET);
8364                                 }
8365                         }
8366                         TASK_DAEMON_LOCK(ha);
8367                         loop_again = TRUE;
8368                 }
8369 
8370                 if (QL_IS_SET(ha->task_daemon_flags, NEED_UNSOLICITED_BUFFERS |
8371                     FIRMWARE_UP)) {
8372                         /*
8373                          * The firmware needs more unsolicited
8374                          * buffers. We cannot allocate any new
8375                          * buffers unless the ULP module requests
8376                          * for new buffers. All we can do here is
8377                          * to give received buffers from the pool
8378                          * that is already allocated
8379                          */
8380                         ha->task_daemon_flags &= ~NEED_UNSOLICITED_BUFFERS;
8381                         TASK_DAEMON_UNLOCK(ha);
8382                         ql_isp_rcvbuf(ha);
8383                         TASK_DAEMON_LOCK(ha);
8384                         loop_again = TRUE;
8385                 }
8386 
8387                 if (ha->task_daemon_flags & ISP_ABORT_NEEDED) {
8388                         TASK_DAEMON_UNLOCK(ha);
8389                         (void) ql_abort_isp(ha);
8390                         TASK_DAEMON_LOCK(ha);
8391                         loop_again = TRUE;
8392                 }
8393 
8394                 if (!(ha->task_daemon_flags & (LOOP_DOWN | DRIVER_STALL |
8395                     COMMAND_WAIT_NEEDED))) {
8396                         if (QL_IS_SET(ha->task_daemon_flags,
8397                             RESET_MARKER_NEEDED | FIRMWARE_UP)) {
8398                                 ha->task_daemon_flags &= ~RESET_MARKER_NEEDED;
8399                                 if (!(ha->task_daemon_flags & RESET_ACTIVE)) {
8400                                         ha->task_daemon_flags |= RESET_ACTIVE;
8401                                         TASK_DAEMON_UNLOCK(ha);
8402                                         for (vha = ha; vha != NULL;
8403                                             vha = vha->vp_next) {
8404                                                 ql_rst_aen(vha);
8405                                         }
8406                                         TASK_DAEMON_LOCK(ha);
8407                                         ha->task_daemon_flags &= ~RESET_ACTIVE;
8408                                         loop_again = TRUE;
8409                                 }
8410                         }
8411 
8412                         if (QL_IS_SET(ha->task_daemon_flags,
8413                             LOOP_RESYNC_NEEDED | FIRMWARE_UP)) {
8414                                 if (!(ha->task_daemon_flags &
8415                                     LOOP_RESYNC_ACTIVE)) {
8416                                         ha->task_daemon_flags |=
8417                                             LOOP_RESYNC_ACTIVE;
8418                                         TASK_DAEMON_UNLOCK(ha);
8419                                         (void) ql_loop_resync(ha);
8420                                         TASK_DAEMON_LOCK(ha);
8421                                         loop_again = TRUE;
8422                                 }
8423                         }
8424                 }
8425 
8426                 /* Port retry needed. */
8427                 if (ha->task_daemon_flags & PORT_RETRY_NEEDED) {
8428                         ha->task_daemon_flags &= ~PORT_RETRY_NEEDED;
8429                         ADAPTER_STATE_LOCK(ha);
8430                         ha->port_retry_timer = 0;
8431                         ADAPTER_STATE_UNLOCK(ha);
8432 
8433                         TASK_DAEMON_UNLOCK(ha);
8434                         ql_restart_queues(ha);
8435                         TASK_DAEMON_LOCK(ha);
8436                         loop_again = B_TRUE;
8437                 }
8438 
8439                 /* iiDMA setting needed? */
8440                 if (ha->task_daemon_flags & TD_IIDMA_NEEDED) {
8441                         ha->task_daemon_flags &= ~TD_IIDMA_NEEDED;
8442 
8443                         TASK_DAEMON_UNLOCK(ha);
8444                         ql_iidma(ha);
8445                         TASK_DAEMON_LOCK(ha);
8446                         loop_again = B_TRUE;
8447                 }
8448 
8449                 if (ha->task_daemon_flags & SEND_PLOGI) {
8450                         ha->task_daemon_flags &= ~SEND_PLOGI;
8451                         TASK_DAEMON_UNLOCK(ha);
8452                         (void) ql_n_port_plogi(ha);
8453                         TASK_DAEMON_LOCK(ha);
8454                 }
8455 
8456                 head = &ha->callback_queue;
8457                 if (head->first != NULL) {
8458                         sp = head->first->base_address;
8459                         link = &sp->cmd;
8460 
8461                         /* Dequeue command. */
8462                         ql_remove_link(head, link);
8463 
8464                         /* Release task daemon lock. */
8465                         TASK_DAEMON_UNLOCK(ha);
8466 
8467                         /* Do callback. */
8468                         if (sp->flags & SRB_UB_CALLBACK) {
8469                                 ql_unsol_callback(sp);
8470                         } else {
8471                                 (*sp->pkt->pkt_comp)(sp->pkt);
8472                         }
8473 
8474                         /* Acquire task daemon lock. */
8475                         TASK_DAEMON_LOCK(ha);
8476 
8477                         loop_again = TRUE;
8478                 }
8479 
8480         } while (loop_again);
8481 }
8482 
8483 /*
8484  * ql_idle_check
8485  *      Test for adapter is alive and well.
8486  *
8487  * Input:
8488  *      ha:     adapter state pointer.
8489  *
8490  * Context:
8491  *      Kernel context.
8492  */
8493 static void
8494 ql_idle_check(ql_adapter_state_t *ha)
8495 {
8496         ddi_devstate_t  state;
8497         int             rval;
8498         ql_mbx_data_t   mr;
8499 
8500         QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
8501 
8502         /* Firmware Ready Test. */
8503         rval = ql_get_firmware_state(ha, &mr);
8504         if (!(ha->task_daemon_flags & QL_SUSPENDED) &&
8505             (rval != QL_SUCCESS || mr.mb[1] != FSTATE_READY)) {
8506                 EL(ha, "failed, Firmware Ready Test = %xh\n", rval);
8507                 state = ddi_get_devstate(ha->dip);
8508                 if (state == DDI_DEVSTATE_UP) {
8509                         /*EMPTY*/
8510                         ddi_dev_report_fault(ha->dip, DDI_SERVICE_DEGRADED,
8511                             DDI_DEVICE_FAULT, "Firmware Ready Test failed");
8512                 }
8513                 TASK_DAEMON_LOCK(ha);
8514                 if (!(ha->task_daemon_flags & ABORT_ISP_ACTIVE)) {
8515                         EL(ha, "fstate_ready, isp_abort_needed\n");
8516                         ha->task_daemon_flags |= ISP_ABORT_NEEDED;
8517                 }
8518                 TASK_DAEMON_UNLOCK(ha);
8519         }
8520 
8521         QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
8522 }
8523 
8524 /*
8525  * ql_unsol_callback
8526  *      Handle unsolicited buffer callbacks.
8527  *
8528  * Input:
8529  *      ha = adapter state pointer.
8530  *      sp = srb pointer.
8531  *
8532  * Context:
8533  *      Kernel context.
8534  */
8535 static void
8536 ql_unsol_callback(ql_srb_t *sp)
8537 {
8538         fc_affected_id_t        *af;
8539         fc_unsol_buf_t          *ubp;
8540         uchar_t                 r_ctl;
8541         uchar_t                 ls_code;
8542         ql_tgt_t                *tq;
8543         ql_adapter_state_t      *ha = sp->ha, *pha = sp->ha->pha;
8544 
8545         QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
8546 
8547         ubp = ha->ub_array[sp->handle];
8548         r_ctl = ubp->ub_frame.r_ctl;
8549         ls_code = ubp->ub_buffer[0];
8550 
8551         if (sp->lun_queue == NULL) {
8552                 tq = NULL;
8553         } else {
8554                 tq = sp->lun_queue->target_queue;
8555         }
8556 
8557         QL_UB_LOCK(ha);
8558         if (sp->flags & SRB_UB_FREE_REQUESTED ||
8559             pha->task_daemon_flags & TASK_DAEMON_POWERING_DOWN) {
8560                 sp->flags &= ~(SRB_UB_IN_ISP | SRB_UB_CALLBACK |
8561                     SRB_UB_RSCN | SRB_UB_FCP | SRB_UB_ACQUIRED);
8562                 sp->flags |= SRB_UB_IN_FCA;
8563                 QL_UB_UNLOCK(ha);
8564                 return;
8565         }
8566 
8567         /* Process RSCN */
8568         if (sp->flags & SRB_UB_RSCN) {
8569                 int sendup = 1;
8570 
8571                 /*
8572                  * Defer RSCN posting until commands return
8573                  */
8574                 QL_UB_UNLOCK(ha);
8575 
8576                 af = (fc_affected_id_t *)((caddr_t)ubp->ub_buffer + 4);
8577 
8578                 /* Abort outstanding commands */
8579                 sendup = ql_process_rscn(ha, af);
8580                 if (sendup == 0) {
8581 
8582                         TASK_DAEMON_LOCK(ha);
8583                         ql_add_link_b(&pha->callback_queue, &sp->cmd);
8584                         TASK_DAEMON_UNLOCK(ha);
8585 
8586                         /*
8587                          * Wait for commands to drain in F/W (doesn't take
8588                          * more than a few milliseconds)
8589                          */
8590                         ql_delay(ha, 10000);
8591 
8592                         QL_PRINT_2(CE_CONT, "(%d,%d): done rscn_sendup=0, "
8593                             "fmt=%xh, d_id=%xh\n", ha->instance, ha->vp_index,
8594                             af->aff_format, af->aff_d_id);
8595                         return;
8596                 }
8597 
8598                 QL_UB_LOCK(ha);
8599 
8600                 EL(ha, "sending unsol rscn, fmt=%xh, d_id=%xh to transport\n",
8601                     af->aff_format, af->aff_d_id);
8602         }
8603 
8604         /* Process UNSOL LOGO */
8605         if ((r_ctl == R_CTL_ELS_REQ) && (ls_code == LA_ELS_LOGO)) {
8606                 QL_UB_UNLOCK(ha);
8607 
8608                 if (tq && (ql_process_logo_for_device(ha, tq) == 0)) {
8609                         TASK_DAEMON_LOCK(ha);
8610                         ql_add_link_b(&pha->callback_queue, &sp->cmd);
8611                         TASK_DAEMON_UNLOCK(ha);
8612                         QL_PRINT_2(CE_CONT, "(%d,%d): logo_sendup=0, d_id=%xh"
8613                             "\n", ha->instance, ha->vp_index, tq->d_id.b24);
8614                         return;
8615                 }
8616 
8617                 QL_UB_LOCK(ha);
8618                 EL(ha, "sending unsol logout for %xh to transport\n",
8619                     ubp->ub_frame.s_id);
8620         }
8621 
8622         sp->flags &= ~(SRB_UB_IN_FCA | SRB_UB_IN_ISP | SRB_UB_RSCN |
8623             SRB_UB_FCP);
8624 
8625         if (sp->ub_type == FC_TYPE_IS8802_SNAP) {
8626                 (void) ddi_dma_sync(sp->ub_buffer.dma_handle, 0,
8627                     ubp->ub_bufsize, DDI_DMA_SYNC_FORCPU);
8628         }
8629         QL_UB_UNLOCK(ha);
8630 
8631         (ha->bind_info.port_unsol_cb)(ha->bind_info.port_handle,
8632             ubp, sp->ub_type);
8633 
8634         QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
8635 }
8636 
8637 /*
8638  * ql_send_logo
8639  *
8640  * Input:
8641  *      ha:     adapter state pointer.
8642  *      tq:     target queue pointer.
8643  *      done_q: done queue pointer.
8644  *
8645  * Context:
8646  *      Interrupt or Kernel context, no mailbox commands allowed.
8647  */
8648 void
8649 ql_send_logo(ql_adapter_state_t *vha, ql_tgt_t *tq, ql_head_t *done_q)
8650 {
8651         fc_unsol_buf_t          *ubp;
8652         ql_srb_t                *sp;
8653         la_els_logo_t           *payload;
8654         ql_adapter_state_t      *ha = vha->pha;
8655 
8656         QL_PRINT_3(CE_CONT, "(%d): started, d_id=%xh\n", ha->instance,
8657             tq->d_id.b24);
8658 
8659         if ((tq->d_id.b24 == 0) || (tq->d_id.b24 == 0xffffff)) {
8660                 EL(ha, "no device, d_id=%xh\n", tq->d_id.b24);
8661                 return;
8662         }
8663 
8664         if ((tq->flags & (TQF_RSCN_RCVD | TQF_PLOGI_PROGRS)) == 0 &&
8665             tq->logout_sent == 0 && (ha->task_daemon_flags & LOOP_DOWN) == 0) {
8666 
8667                 /* Locate a buffer to use. */
8668                 ubp = ql_get_unsolicited_buffer(vha, FC_TYPE_EXTENDED_LS);
8669                 if (ubp == NULL) {
8670                         EL(vha, "Failed, get_unsolicited_buffer\n");
8671                         return;
8672                 }
8673 
8674                 DEVICE_QUEUE_LOCK(tq);
8675                 tq->flags |= TQF_NEED_AUTHENTICATION;
8676                 tq->logout_sent++;
8677                 DEVICE_QUEUE_UNLOCK(tq);
8678 
8679                 EL(vha, "Received LOGO from = %xh\n", tq->d_id.b24);
8680 
8681                 sp = ubp->ub_fca_private;
8682 
8683                 /* Set header. */
8684                 ubp->ub_frame.d_id = vha->d_id.b24;
8685                 ubp->ub_frame.r_ctl = R_CTL_ELS_REQ;
8686                 ubp->ub_frame.s_id = tq->d_id.b24;
8687                 ubp->ub_frame.rsvd = 0;
8688                 ubp->ub_frame.f_ctl = F_CTL_FIRST_SEQ | F_CTL_END_SEQ |
8689                     F_CTL_SEQ_INITIATIVE;
8690                 ubp->ub_frame.type = FC_TYPE_EXTENDED_LS;
8691                 ubp->ub_frame.seq_cnt = 0;
8692                 ubp->ub_frame.df_ctl = 0;
8693                 ubp->ub_frame.seq_id = 0;
8694                 ubp->ub_frame.rx_id = 0xffff;
8695                 ubp->ub_frame.ox_id = 0xffff;
8696 
8697                 /* set payload. */
8698                 payload = (la_els_logo_t *)ubp->ub_buffer;
8699                 bzero(payload, sizeof (la_els_logo_t));
8700                 /* Make sure ls_code in payload is always big endian */
8701                 ubp->ub_buffer[0] = LA_ELS_LOGO;
8702                 ubp->ub_buffer[1] = 0;
8703                 ubp->ub_buffer[2] = 0;
8704                 ubp->ub_buffer[3] = 0;
8705                 bcopy(&vha->loginparams.node_ww_name.raw_wwn[0],
8706                     &payload->nport_ww_name.raw_wwn[0], 8);
8707                 payload->nport_id.port_id = tq->d_id.b24;
8708 
8709                 QL_UB_LOCK(ha);
8710                 sp->flags |= SRB_UB_CALLBACK;
8711                 QL_UB_UNLOCK(ha);
8712                 if (tq->lun_queues.first != NULL) {
8713                         sp->lun_queue = (tq->lun_queues.first)->base_address;
8714                 } else {
8715                         sp->lun_queue = ql_lun_queue(vha, tq, 0);
8716                 }
8717                 if (done_q) {
8718                         ql_add_link_b(done_q, &sp->cmd);
8719                 } else {
8720                         ql_awaken_task_daemon(ha, sp, 0, 0);
8721                 }
8722         }
8723 
8724         QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
8725 }
8726 
8727 static int
8728 ql_process_logo_for_device(ql_adapter_state_t *ha, ql_tgt_t *tq)
8729 {
8730         port_id_t       d_id;
8731         ql_srb_t        *sp;
8732         ql_link_t       *link;
8733         int             sendup = 1;
8734 
8735         QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
8736 
8737         DEVICE_QUEUE_LOCK(tq);
8738         if (tq->outcnt) {
8739                 DEVICE_QUEUE_UNLOCK(tq);
8740                 sendup = 0;
8741                 (void) ql_abort_device(ha, tq, 1);
8742                 ql_delay(ha, 10000);
8743         } else {
8744                 DEVICE_QUEUE_UNLOCK(tq);
8745                 TASK_DAEMON_LOCK(ha);
8746 
8747                 for (link = ha->pha->callback_queue.first; link != NULL;
8748                     link = link->next) {
8749                         sp = link->base_address;
8750                         if (sp->flags & SRB_UB_CALLBACK) {
8751                                 continue;
8752                         }
8753                         d_id.b24 = sp->pkt->pkt_cmd_fhdr.d_id;
8754 
8755                         if (tq->d_id.b24 == d_id.b24) {
8756                                 sendup = 0;
8757                                 break;
8758                         }
8759                 }
8760 
8761                 TASK_DAEMON_UNLOCK(ha);
8762         }
8763 
8764         QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
8765 
8766         return (sendup);
8767 }
8768 
8769 static int
8770 ql_send_plogi(ql_adapter_state_t *ha, ql_tgt_t *tq, ql_head_t *done_q)
8771 {
8772         fc_unsol_buf_t          *ubp;
8773         ql_srb_t                *sp;
8774         la_els_logi_t           *payload;
8775         class_svc_param_t       *class3_param;
8776 
8777         QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
8778 
8779         if ((tq->flags & TQF_RSCN_RCVD) || (ha->task_daemon_flags &
8780             LOOP_DOWN)) {
8781                 EL(ha, "Failed, tqf=%xh\n", tq->flags);
8782                 return (QL_FUNCTION_FAILED);
8783         }
8784 
8785         /* Locate a buffer to use. */
8786         ubp = ql_get_unsolicited_buffer(ha, FC_TYPE_EXTENDED_LS);
8787         if (ubp == NULL) {
8788                 EL(ha, "Failed\n");
8789                 return (QL_FUNCTION_FAILED);
8790         }
8791 
8792         QL_PRINT_3(CE_CONT, "(%d): Received LOGO from = %xh\n",
8793             ha->instance, tq->d_id.b24);
8794 
8795         EL(ha, "Emulate PLOGI from = %xh tq = %x\n", tq->d_id.b24, tq);
8796 
8797         sp = ubp->ub_fca_private;
8798 
8799         /* Set header. */
8800         ubp->ub_frame.d_id = ha->d_id.b24;
8801         ubp->ub_frame.r_ctl = R_CTL_ELS_REQ;
8802         ubp->ub_frame.s_id = tq->d_id.b24;
8803         ubp->ub_frame.rsvd = 0;
8804         ubp->ub_frame.f_ctl = F_CTL_FIRST_SEQ | F_CTL_END_SEQ |
8805             F_CTL_SEQ_INITIATIVE;
8806         ubp->ub_frame.type = FC_TYPE_EXTENDED_LS;
8807         ubp->ub_frame.seq_cnt = 0;
8808         ubp->ub_frame.df_ctl = 0;
8809         ubp->ub_frame.seq_id = 0;
8810         ubp->ub_frame.rx_id = 0xffff;
8811         ubp->ub_frame.ox_id = 0xffff;
8812 
8813         /* set payload. */
8814         payload = (la_els_logi_t *)ubp->ub_buffer;
8815         bzero(payload, sizeof (payload));
8816 
8817         payload->ls_code.ls_code = LA_ELS_PLOGI;
8818         payload->common_service.fcph_version = 0x2006;
8819         payload->common_service.cmn_features = 0x8800;
8820 
8821         CFG_IST(ha, CFG_CTRL_24258081) ?
8822             (payload->common_service.rx_bufsize = CHAR_TO_SHORT(
8823             ha->init_ctrl_blk.cb24.max_frame_length[0],
8824             ha->init_ctrl_blk.cb24.max_frame_length[1])) :
8825             (payload->common_service.rx_bufsize = CHAR_TO_SHORT(
8826             ha->init_ctrl_blk.cb.max_frame_length[0],
8827             ha->init_ctrl_blk.cb.max_frame_length[1]));
8828 
8829         payload->common_service.conc_sequences = 0xff;
8830         payload->common_service.relative_offset = 0x03;
8831         payload->common_service.e_d_tov = 0x7d0;
8832 
8833         bcopy((void *)&tq->port_name[0],
8834             (void *)&payload->nport_ww_name.raw_wwn[0], 8);
8835 
8836         bcopy((void *)&tq->node_name[0],
8837             (void *)&payload->node_ww_name.raw_wwn[0], 8);
8838 
8839         class3_param = (class_svc_param_t *)&payload->class_3;
8840         class3_param->class_valid_svc_opt = 0x8000;
8841         class3_param->recipient_ctl = tq->class3_recipient_ctl;
8842         class3_param->rcv_data_size = tq->class3_rcv_data_size;
8843         class3_param->conc_sequences = tq->class3_conc_sequences;
8844         class3_param->open_sequences_per_exch =
8845             tq->class3_open_sequences_per_exch;
8846 
8847         QL_UB_LOCK(ha);
8848         sp->flags |= SRB_UB_CALLBACK;
8849         QL_UB_UNLOCK(ha);
8850 
8851         ql_isp_els_handle_endian(ha, (uint8_t *)payload, LA_ELS_PLOGI);
8852 
8853         if (done_q) {
8854                 ql_add_link_b(done_q, &sp->cmd);
8855         } else {
8856                 ql_awaken_task_daemon(ha, sp, 0, 0);
8857         }
8858 
8859         QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
8860 
8861         return (QL_SUCCESS);
8862 }
8863 
8864 /*
8865  * Abort outstanding commands in the Firmware, clear internally
8866  * queued commands in the driver, Synchronize the target with
8867  * the Firmware
8868  */
8869 int
8870 ql_abort_device(ql_adapter_state_t *ha, ql_tgt_t *tq, int drain)
8871 {
8872         ql_link_t       *link, *link2;
8873         ql_lun_t        *lq;
8874         int             rval = QL_SUCCESS;
8875         ql_srb_t        *sp;
8876         ql_head_t       done_q = { NULL, NULL };
8877 
8878         QL_PRINT_10(CE_CONT, "(%d,%d): started\n", ha->instance, ha->vp_index);
8879 
8880         /*
8881          * First clear, internally queued commands
8882          */
8883         DEVICE_QUEUE_LOCK(tq);
8884         for (link = tq->lun_queues.first; link != NULL; link = link->next) {
8885                 lq = link->base_address;
8886 
8887                 link2 = lq->cmd.first;
8888                 while (link2 != NULL) {
8889                         sp = link2->base_address;
8890                         link2 = link2->next;
8891 
8892                         if (sp->flags & SRB_ABORT) {
8893                                 continue;
8894                         }
8895 
8896                         /* Remove srb from device command queue. */
8897                         ql_remove_link(&lq->cmd, &sp->cmd);
8898                         sp->flags &= ~SRB_IN_DEVICE_QUEUE;
8899 
8900                         /* Set ending status. */
8901                         sp->pkt->pkt_reason = CS_ABORTED;
8902 
8903                         /* Call done routine to handle completions. */
8904                         ql_add_link_b(&done_q, &sp->cmd);
8905                 }
8906         }
8907         DEVICE_QUEUE_UNLOCK(tq);
8908 
8909         if (done_q.first != NULL) {
8910                 ql_done(done_q.first);
8911         }
8912 
8913         if (drain && VALID_TARGET_ID(ha, tq->loop_id) && PD_PORT_LOGIN(tq)) {
8914                 rval = ql_abort_target(ha, tq, 0);
8915         }
8916 
8917         if (rval != QL_SUCCESS) {
8918                 EL(ha, "failed=%xh, d_id=%xh\n", rval, tq->d_id.b24);
8919         } else {
8920                 /*EMPTY*/
8921                 QL_PRINT_10(CE_CONT, "(%d,%d): done\n", ha->instance,
8922                     ha->vp_index);
8923         }
8924 
8925         return (rval);
8926 }
8927 
8928 /*
8929  * ql_rcv_rscn_els
8930  *      Processes received RSCN extended link service.
8931  *
8932  * Input:
8933  *      ha:     adapter state pointer.
8934  *      mb:     array containing input mailbox registers.
8935  *      done_q: done queue pointer.
8936  *
8937  * Context:
8938  *      Interrupt or Kernel context, no mailbox commands allowed.
8939  */
8940 void
8941 ql_rcv_rscn_els(ql_adapter_state_t *ha, uint16_t *mb, ql_head_t *done_q)
8942 {
8943         fc_unsol_buf_t          *ubp;
8944         ql_srb_t                *sp;
8945         fc_rscn_t               *rn;
8946         fc_affected_id_t        *af;
8947         port_id_t               d_id;
8948 
8949         QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
8950 
8951         /* Locate a buffer to use. */
8952         ubp = ql_get_unsolicited_buffer(ha, FC_TYPE_EXTENDED_LS);
8953         if (ubp != NULL) {
8954                 sp = ubp->ub_fca_private;
8955 
8956                 /* Set header. */
8957                 ubp->ub_frame.d_id = ha->d_id.b24;
8958                 ubp->ub_frame.r_ctl = R_CTL_ELS_REQ;
8959                 ubp->ub_frame.s_id = FS_FABRIC_CONTROLLER;
8960                 ubp->ub_frame.rsvd = 0;
8961                 ubp->ub_frame.f_ctl = F_CTL_FIRST_SEQ | F_CTL_END_SEQ |
8962                     F_CTL_SEQ_INITIATIVE;
8963                 ubp->ub_frame.type = FC_TYPE_EXTENDED_LS;
8964                 ubp->ub_frame.seq_cnt = 0;
8965                 ubp->ub_frame.df_ctl = 0;
8966                 ubp->ub_frame.seq_id = 0;
8967                 ubp->ub_frame.rx_id = 0xffff;
8968                 ubp->ub_frame.ox_id = 0xffff;
8969 
8970                 /* set payload. */
8971                 rn = (fc_rscn_t *)ubp->ub_buffer;
8972                 af = (fc_affected_id_t *)((caddr_t)ubp->ub_buffer + 4);
8973 
8974                 rn->rscn_code = LA_ELS_RSCN;
8975                 rn->rscn_len = 4;
8976                 rn->rscn_payload_len = 8;
8977                 d_id.b.al_pa = LSB(mb[2]);
8978                 d_id.b.area = MSB(mb[2]);
8979                 d_id.b.domain = LSB(mb[1]);
8980                 af->aff_d_id = d_id.b24;
8981                 af->aff_format = MSB(mb[1]);
8982 
8983                 EL(ha, "LA_ELS_RSCN fmt=%xh, d_id=%xh\n", af->aff_format,
8984                     af->aff_d_id);
8985 
8986                 ql_update_rscn(ha, af);
8987 
8988                 QL_UB_LOCK(ha);
8989                 sp->flags |= SRB_UB_CALLBACK | SRB_UB_RSCN;
8990                 QL_UB_UNLOCK(ha);
8991                 ql_add_link_b(done_q, &sp->cmd);
8992         }
8993 
8994         if (ubp == NULL) {
8995                 EL(ha, "Failed, get_unsolicited_buffer\n");
8996         } else {
8997                 /*EMPTY*/
8998                 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
8999         }
9000 }
9001 
9002 /*
9003  * ql_update_rscn
9004  *      Update devices from received RSCN.
9005  *
9006  * Input:
9007  *      ha:     adapter state pointer.
9008  *      af:     pointer to RSCN data.
9009  *
9010  * Context:
9011  *      Interrupt or Kernel context, no mailbox commands allowed.
9012  */
9013 static void
9014 ql_update_rscn(ql_adapter_state_t *ha, fc_affected_id_t *af)
9015 {
9016         ql_link_t       *link;
9017         uint16_t        index;
9018         ql_tgt_t        *tq;
9019 
9020         QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
9021 
9022         if (af->aff_format == FC_RSCN_PORT_ADDRESS) {
9023                 port_id_t d_id;
9024 
9025                 d_id.r.rsvd_1 = 0;
9026                 d_id.b24 = af->aff_d_id;
9027 
9028                 tq = ql_d_id_to_queue(ha, d_id);
9029                 if (tq) {
9030                         EL(ha, "SD_RSCN_RCVD %xh RPA\n", d_id.b24);
9031                         DEVICE_QUEUE_LOCK(tq);
9032                         tq->flags |= TQF_RSCN_RCVD;
9033                         DEVICE_QUEUE_UNLOCK(tq);
9034                 }
9035                 QL_PRINT_3(CE_CONT, "(%d): FC_RSCN_PORT_ADDRESS done\n",
9036                     ha->instance);
9037 
9038                 return;
9039         }
9040 
9041         for (index = 0; index < DEVICE_HEAD_LIST_SIZE; index++) {
9042                 for (link = ha->dev[index].first; link != NULL;
9043                     link = link->next) {
9044                         tq = link->base_address;
9045 
9046                         switch (af->aff_format) {
9047                         case FC_RSCN_FABRIC_ADDRESS:
9048                                 if (!RESERVED_LOOP_ID(ha, tq->loop_id)) {
9049                                         EL(ha, "SD_RSCN_RCVD %xh RFA\n",
9050                                             tq->d_id.b24);
9051                                         DEVICE_QUEUE_LOCK(tq);
9052                                         tq->flags |= TQF_RSCN_RCVD;
9053                                         DEVICE_QUEUE_UNLOCK(tq);
9054                                 }
9055                                 break;
9056 
9057                         case FC_RSCN_AREA_ADDRESS:
9058                                 if ((tq->d_id.b24 & 0xffff00) == af->aff_d_id) {
9059                                         EL(ha, "SD_RSCN_RCVD %xh RAA\n",
9060                                             tq->d_id.b24);
9061                                         DEVICE_QUEUE_LOCK(tq);
9062                                         tq->flags |= TQF_RSCN_RCVD;
9063                                         DEVICE_QUEUE_UNLOCK(tq);
9064                                 }
9065                                 break;
9066 
9067                         case FC_RSCN_DOMAIN_ADDRESS:
9068                                 if ((tq->d_id.b24 & 0xff0000) == af->aff_d_id) {
9069                                         EL(ha, "SD_RSCN_RCVD %xh RDA\n",
9070                                             tq->d_id.b24);
9071                                         DEVICE_QUEUE_LOCK(tq);
9072                                         tq->flags |= TQF_RSCN_RCVD;
9073                                         DEVICE_QUEUE_UNLOCK(tq);
9074                                 }
9075                                 break;
9076 
9077                         default:
9078                                 break;
9079                         }
9080                 }
9081         }
9082         QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
9083 }
9084 
9085 /*
9086  * ql_process_rscn
9087  *
9088  * Input:
9089  *      ha:     adapter state pointer.
9090  *      af:     RSCN payload pointer.
9091  *
9092  * Context:
9093  *      Kernel context.
9094  */
9095 static int
9096 ql_process_rscn(ql_adapter_state_t *ha, fc_affected_id_t *af)
9097 {
9098         int             sendit;
9099         int             sendup = 1;
9100         ql_link_t       *link;
9101         uint16_t        index;
9102         ql_tgt_t        *tq;
9103 
9104         QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
9105 
9106         if (af->aff_format == FC_RSCN_PORT_ADDRESS) {
9107                 port_id_t d_id;
9108 
9109                 d_id.r.rsvd_1 = 0;
9110                 d_id.b24 = af->aff_d_id;
9111 
9112                 tq = ql_d_id_to_queue(ha, d_id);
9113                 if (tq) {
9114                         sendup = ql_process_rscn_for_device(ha, tq);
9115                 }
9116 
9117                 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
9118 
9119                 return (sendup);
9120         }
9121 
9122         for (index = 0; index < DEVICE_HEAD_LIST_SIZE; index++) {
9123                 for (link = ha->dev[index].first; link != NULL;
9124                     link = link->next) {
9125 
9126                         tq = link->base_address;
9127                         if (tq == NULL) {
9128                                 continue;
9129                         }
9130 
9131                         switch (af->aff_format) {
9132                         case FC_RSCN_FABRIC_ADDRESS:
9133                                 if (!RESERVED_LOOP_ID(ha, tq->loop_id)) {
9134                                         sendit = ql_process_rscn_for_device(
9135                                             ha, tq);
9136                                         if (sendup) {
9137                                                 sendup = sendit;
9138                                         }
9139                                 }
9140                                 break;
9141 
9142                         case FC_RSCN_AREA_ADDRESS:
9143                                 if ((tq->d_id.b24 & 0xffff00) ==
9144                                     af->aff_d_id) {
9145                                         sendit = ql_process_rscn_for_device(
9146                                             ha, tq);
9147 
9148                                         if (sendup) {
9149                                                 sendup = sendit;
9150                                         }
9151                                 }
9152                                 break;
9153 
9154                         case FC_RSCN_DOMAIN_ADDRESS:
9155                                 if ((tq->d_id.b24 & 0xff0000) ==
9156                                     af->aff_d_id) {
9157                                         sendit = ql_process_rscn_for_device(
9158                                             ha, tq);
9159 
9160                                         if (sendup) {
9161                                                 sendup = sendit;
9162                                         }
9163                                 }
9164                                 break;
9165 
9166                         default:
9167                                 break;
9168                         }
9169                 }
9170         }
9171 
9172         QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
9173 
9174         return (sendup);
9175 }
9176 
9177 /*
9178  * ql_process_rscn_for_device
9179  *
9180  * Input:
9181  *      ha:     adapter state pointer.
9182  *      tq:     target queue pointer.
9183  *
9184  * Context:
9185  *      Kernel context.
9186  */
9187 static int
9188 ql_process_rscn_for_device(ql_adapter_state_t *ha, ql_tgt_t *tq)
9189 {
9190         int sendup = 1;
9191 
9192         QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
9193 
9194         DEVICE_QUEUE_LOCK(tq);
9195 
9196         /*
9197          * Let FCP-2 compliant devices continue I/Os
9198          * with their low level recoveries.
9199          */
9200         if (((tq->flags & TQF_INITIATOR_DEVICE) == 0) &&
9201             (tq->prli_svc_param_word_3 & PRLI_W3_RETRY)) {
9202                 /*
9203                  * Cause ADISC to go out
9204                  */
9205                 DEVICE_QUEUE_UNLOCK(tq);
9206 
9207                 (void) ql_get_port_database(ha, tq, PDF_NONE);
9208 
9209                 DEVICE_QUEUE_LOCK(tq);
9210                 tq->flags &= ~TQF_RSCN_RCVD;
9211 
9212         } else if (tq->loop_id != PORT_NO_LOOP_ID) {
9213                 if (tq->d_id.b24 != BROADCAST_ADDR) {
9214                         tq->flags |= TQF_NEED_AUTHENTICATION;
9215                 }
9216 
9217                 DEVICE_QUEUE_UNLOCK(tq);
9218 
9219                 (void) ql_abort_device(ha, tq, 1);
9220 
9221                 DEVICE_QUEUE_LOCK(tq);
9222 
9223                 if (tq->outcnt) {
9224                         sendup = 0;
9225                 } else {
9226                         tq->flags &= ~TQF_RSCN_RCVD;
9227                 }
9228         } else {
9229                 tq->flags &= ~TQF_RSCN_RCVD;
9230         }
9231 
9232         if (sendup) {
9233                 if (tq->d_id.b24 != BROADCAST_ADDR) {
9234                         tq->flags |= TQF_NEED_AUTHENTICATION;
9235                 }
9236         }
9237 
9238         DEVICE_QUEUE_UNLOCK(tq);
9239 
9240         QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
9241 
9242         return (sendup);
9243 }
9244 
9245 static int
9246 ql_handle_rscn_update(ql_adapter_state_t *ha)
9247 {
9248         int                     rval;
9249         ql_tgt_t                *tq;
9250         uint16_t                index, loop_id;
9251         ql_dev_id_list_t        *list;
9252         uint32_t                list_size;
9253         port_id_t               d_id;
9254         ql_mbx_data_t           mr;
9255         ql_head_t               done_q = { NULL, NULL };
9256 
9257         QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
9258 
9259         list_size = sizeof (ql_dev_id_list_t) * DEVICE_LIST_ENTRIES;
9260         list = kmem_zalloc(list_size, KM_SLEEP);
9261         if (list == NULL) {
9262                 rval = QL_MEMORY_ALLOC_FAILED;
9263                 EL(ha, "kmem_zalloc failed=%xh\n", rval);
9264                 return (rval);
9265         }
9266 
9267         /*
9268          * Get data from RISC code d_id list to init each device queue.
9269          */
9270         rval = ql_get_id_list(ha, (caddr_t)list, list_size, &mr);
9271         if (rval != QL_SUCCESS) {
9272                 kmem_free(list, list_size);
9273                 EL(ha, "get_id_list failed=%xh\n", rval);
9274                 return (rval);
9275         }
9276 
9277         /* Acquire adapter state lock. */
9278         ADAPTER_STATE_LOCK(ha);
9279 
9280         /* Check for new devices */
9281         for (index = 0; index < mr.mb[1]; index++) {
9282                 ql_dev_list(ha, list, index, &d_id, &loop_id);
9283 
9284                 if (VALID_DEVICE_ID(ha, loop_id)) {
9285                         d_id.r.rsvd_1 = 0;
9286 
9287                         tq = ql_d_id_to_queue(ha, d_id);
9288                         if (tq != NULL) {
9289                                 continue;
9290                         }
9291 
9292                         tq = ql_dev_init(ha, d_id, loop_id);
9293 
9294                         /* Test for fabric device. */
9295                         if (d_id.b.domain != ha->d_id.b.domain ||
9296                             d_id.b.area != ha->d_id.b.area) {
9297                                 tq->flags |= TQF_FABRIC_DEVICE;
9298                         }
9299 
9300                         ADAPTER_STATE_UNLOCK(ha);
9301                         if (ql_get_port_database(ha, tq, PDF_NONE) !=
9302                             QL_SUCCESS) {
9303                                 tq->loop_id = PORT_NO_LOOP_ID;
9304                         }
9305                         ADAPTER_STATE_LOCK(ha);
9306 
9307                         /*
9308                          * Send up a PLOGI about the new device
9309                          */
9310                         if (VALID_DEVICE_ID(ha, tq->loop_id)) {
9311                                 (void) ql_send_plogi(ha, tq, &done_q);
9312                         }
9313                 }
9314         }
9315 
9316         /* Release adapter state lock. */
9317         ADAPTER_STATE_UNLOCK(ha);
9318 
9319         if (done_q.first != NULL) {
9320                 ql_done(done_q.first);
9321         }
9322 
9323         kmem_free(list, list_size);
9324 
9325         if (rval != QL_SUCCESS) {
9326                 EL(ha, "failed=%xh\n", rval);
9327         } else {
9328                 /*EMPTY*/
9329                 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
9330         }
9331 
9332         return (rval);
9333 }
9334 
9335 /*
9336  * ql_free_unsolicited_buffer
9337  *      Frees allocated buffer.
9338  *
9339  * Input:
9340  *      ha = adapter state pointer.
9341  *      index = buffer array index.
9342  *      ADAPTER_STATE_LOCK must be already obtained.
9343  *
9344  * Context:
9345  *      Kernel context.
9346  */
9347 static void
9348 ql_free_unsolicited_buffer(ql_adapter_state_t *ha, fc_unsol_buf_t *ubp)
9349 {
9350         ql_srb_t        *sp;
9351         int             status;
9352 
9353         QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
9354 
9355         sp = ubp->ub_fca_private;
9356         if (sp->ub_type == FC_TYPE_IS8802_SNAP) {
9357                 /* Disconnect IP from system buffers. */
9358                 if (ha->flags & IP_INITIALIZED) {
9359                         ADAPTER_STATE_UNLOCK(ha);
9360                         status = ql_shutdown_ip(ha);
9361                         ADAPTER_STATE_LOCK(ha);
9362                         if (status != QL_SUCCESS) {
9363                                 cmn_err(CE_WARN,
9364                                     "!Qlogic %s(%d): Failed to shutdown IP",
9365                                     QL_NAME, ha->instance);
9366                                 return;
9367                         }
9368 
9369                         ha->flags &= ~IP_ENABLED;
9370                 }
9371 
9372                 ql_free_phys(ha, &sp->ub_buffer);
9373         } else {
9374                 kmem_free(ubp->ub_buffer, ubp->ub_bufsize);
9375         }
9376 
9377         kmem_free(sp, sizeof (ql_srb_t));
9378         kmem_free(ubp, sizeof (fc_unsol_buf_t));
9379 
9380         if (ha->ub_allocated != 0) {
9381                 ha->ub_allocated--;
9382         }
9383 
9384         QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
9385 }
9386 
9387 /*
9388  * ql_get_unsolicited_buffer
9389  *      Locates a free unsolicited buffer.
9390  *
9391  * Input:
9392  *      ha = adapter state pointer.
9393  *      type = buffer type.
9394  *
9395  * Returns:
9396  *      Unsolicited buffer pointer.
9397  *
9398  * Context:
9399  *      Interrupt or Kernel context, no mailbox commands allowed.
9400  */
9401 fc_unsol_buf_t *
9402 ql_get_unsolicited_buffer(ql_adapter_state_t *ha, uint32_t type)
9403 {
9404         fc_unsol_buf_t  *ubp;
9405         ql_srb_t        *sp;
9406         uint16_t        index;
9407 
9408         QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
9409 
9410         /* Locate a buffer to use. */
9411         ubp = NULL;
9412 
9413         QL_UB_LOCK(ha);
9414         for (index = 0; index < QL_UB_LIMIT; index++) {
9415                 ubp = ha->ub_array[index];
9416                 if (ubp != NULL) {
9417                         sp = ubp->ub_fca_private;
9418                         if ((sp->ub_type == type) &&
9419                             (sp->flags & SRB_UB_IN_FCA) &&
9420                             (!(sp->flags & (SRB_UB_CALLBACK |
9421                             SRB_UB_FREE_REQUESTED | SRB_UB_ACQUIRED)))) {
9422                                 sp->flags |= SRB_UB_ACQUIRED;
9423                                 ubp->ub_resp_flags = 0;
9424                                 break;
9425                         }
9426                         ubp = NULL;
9427                 }
9428         }
9429         QL_UB_UNLOCK(ha);
9430 
9431         if (ubp) {
9432                 ubp->ub_resp_token = NULL;
9433                 ubp->ub_class = FC_TRAN_CLASS3;
9434         }
9435 
9436         QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
9437 
9438         return (ubp);
9439 }
9440 
9441 /*
9442  * ql_ub_frame_hdr
9443  *      Processes received unsolicited buffers from ISP.
9444  *
9445  * Input:
9446  *      ha:     adapter state pointer.
9447  *      tq:     target queue pointer.
9448  *      index:  unsolicited buffer array index.
9449  *      done_q: done queue pointer.
9450  *
9451  * Returns:
9452  *      ql local function return status code.
9453  *
9454  * Context:
9455  *      Interrupt or Kernel context, no mailbox commands allowed.
9456  */
9457 int
9458 ql_ub_frame_hdr(ql_adapter_state_t *ha, ql_tgt_t *tq, uint16_t index,
9459     ql_head_t *done_q)
9460 {
9461         fc_unsol_buf_t  *ubp;
9462         ql_srb_t        *sp;
9463         uint16_t        loop_id;
9464         int             rval = QL_FUNCTION_FAILED;
9465 
9466         QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
9467 
9468         QL_UB_LOCK(ha);
9469         if (index >= QL_UB_LIMIT || (ubp = ha->ub_array[index]) == NULL) {
9470                 EL(ha, "Invalid buffer index=%xh\n", index);
9471                 QL_UB_UNLOCK(ha);
9472                 return (rval);
9473         }
9474 
9475         sp = ubp->ub_fca_private;
9476         if (sp->flags & SRB_UB_FREE_REQUESTED) {
9477                 EL(ha, "buffer freed index=%xh\n", index);
9478                 sp->flags &= ~(SRB_UB_IN_ISP | SRB_UB_CALLBACK |
9479                     SRB_UB_RSCN | SRB_UB_FCP | SRB_UB_ACQUIRED);
9480 
9481                 sp->flags |= SRB_UB_IN_FCA;
9482 
9483                 QL_UB_UNLOCK(ha);
9484                 return (rval);
9485         }
9486 
9487         if ((sp->handle == index) &&
9488             (sp->flags & SRB_UB_IN_ISP) &&
9489             (sp->ub_type == FC_TYPE_IS8802_SNAP) &&
9490             (!(sp->flags & SRB_UB_ACQUIRED))) {
9491                 /* set broadcast D_ID */
9492                 loop_id = (uint16_t)(CFG_IST(ha, CFG_CTRL_24258081) ?
9493                     BROADCAST_24XX_HDL : IP_BROADCAST_LOOP_ID);
9494                 if (tq->ub_loop_id == loop_id) {
9495                         if (ha->topology & QL_FL_PORT) {
9496                                 ubp->ub_frame.d_id = 0x000000;
9497                         } else {
9498                                 ubp->ub_frame.d_id = 0xffffff;
9499                         }
9500                 } else {
9501                         ubp->ub_frame.d_id = ha->d_id.b24;
9502                 }
9503                 ubp->ub_frame.r_ctl = R_CTL_UNSOL_DATA;
9504                 ubp->ub_frame.rsvd = 0;
9505                 ubp->ub_frame.s_id = tq->d_id.b24;
9506                 ubp->ub_frame.type = FC_TYPE_IS8802_SNAP;
9507                 ubp->ub_frame.seq_cnt = tq->ub_seq_cnt;
9508                 ubp->ub_frame.df_ctl = 0;
9509                 ubp->ub_frame.seq_id = tq->ub_seq_id;
9510                 ubp->ub_frame.rx_id = 0xffff;
9511                 ubp->ub_frame.ox_id = 0xffff;
9512                 ubp->ub_bufsize = sp->ub_size < tq->ub_sequence_length ?
9513                     sp->ub_size : tq->ub_sequence_length;
9514                 ubp->ub_frame.ro = tq->ub_frame_ro;
9515 
9516                 tq->ub_sequence_length = (uint16_t)
9517                     (tq->ub_sequence_length - ubp->ub_bufsize);
9518                 tq->ub_frame_ro += ubp->ub_bufsize;
9519                 tq->ub_seq_cnt++;
9520 
9521                 if (tq->ub_seq_cnt == tq->ub_total_seg_cnt) {
9522                         if (tq->ub_seq_cnt == 1) {
9523                                 ubp->ub_frame.f_ctl = F_CTL_RO_PRESENT |
9524                                     F_CTL_FIRST_SEQ | F_CTL_END_SEQ;
9525                         } else {
9526                                 ubp->ub_frame.f_ctl = F_CTL_RO_PRESENT |
9527                                     F_CTL_END_SEQ;
9528                         }
9529                         tq->ub_total_seg_cnt = 0;
9530                 } else if (tq->ub_seq_cnt == 1) {
9531                         ubp->ub_frame.f_ctl = F_CTL_RO_PRESENT |
9532                             F_CTL_FIRST_SEQ;
9533                         ubp->ub_frame.df_ctl = 0x20;
9534                 }
9535 
9536                 QL_PRINT_3(CE_CONT, "(%d): ub_frame.d_id=%xh\n",
9537                     ha->instance, ubp->ub_frame.d_id);
9538                 QL_PRINT_3(CE_CONT, "(%d): ub_frame.s_id=%xh\n",
9539                     ha->instance, ubp->ub_frame.s_id);
9540                 QL_PRINT_3(CE_CONT, "(%d): ub_frame.seq_cnt=%xh\n",
9541                     ha->instance, ubp->ub_frame.seq_cnt);
9542                 QL_PRINT_3(CE_CONT, "(%d): ub_frame.seq_id=%xh\n",
9543                     ha->instance, ubp->ub_frame.seq_id);
9544                 QL_PRINT_3(CE_CONT, "(%d): ub_frame.ro=%xh\n",
9545                     ha->instance, ubp->ub_frame.ro);
9546                 QL_PRINT_3(CE_CONT, "(%d): ub_frame.f_ctl=%xh\n",
9547                     ha->instance, ubp->ub_frame.f_ctl);
9548                 QL_PRINT_3(CE_CONT, "(%d): ub_bufsize=%xh\n",
9549                     ha->instance, ubp->ub_bufsize);
9550                 QL_DUMP_3(ubp->ub_buffer, 8,
9551                     ubp->ub_bufsize < 64 ? ubp->ub_bufsize : 64);
9552 
9553                 sp->flags |= SRB_UB_CALLBACK | SRB_UB_ACQUIRED;
9554                 ql_add_link_b(done_q, &sp->cmd);
9555                 rval = QL_SUCCESS;
9556         } else {
9557                 if (sp->handle != index) {
9558                         EL(ha, "Bad index=%xh, expect=%xh\n", index,
9559                             sp->handle);
9560                 }
9561                 if ((sp->flags & SRB_UB_IN_ISP) == 0) {
9562                         EL(ha, "buffer was already in driver, index=%xh\n",
9563                             index);
9564                 }
9565                 if ((sp->ub_type == FC_TYPE_IS8802_SNAP) == 0) {
9566                         EL(ha, "buffer was not an IP buffer, index=%xh\n",
9567                             index);
9568                 }
9569                 if (sp->flags & SRB_UB_ACQUIRED) {
9570                         EL(ha, "buffer was being used by driver, index=%xh\n",
9571                             index);
9572                 }
9573         }
9574         QL_UB_UNLOCK(ha);
9575 
9576         QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
9577 
9578         return (rval);
9579 }
9580 
9581 /*
9582  * ql_timer
9583  *      One second timer function.
9584  *
9585  * Input:
9586  *      ql_hba.first = first link in adapter list.
9587  *
9588  * Context:
9589  *      Interrupt context, no mailbox commands allowed.
9590  */
9591 static void
9592 ql_timer(void *arg)
9593 {
9594         ql_link_t               *link;
9595         uint32_t                set_flags;
9596         uint32_t                reset_flags;
9597         ql_adapter_state_t      *ha = NULL, *vha;
9598 
9599         QL_PRINT_6(CE_CONT, "started\n");
9600 
9601         /* Acquire global state lock. */
9602         GLOBAL_STATE_LOCK();
9603         if (ql_timer_timeout_id == NULL) {
9604                 /* Release global state lock. */
9605                 GLOBAL_STATE_UNLOCK();
9606                 return;
9607         }
9608 
9609         for (link = ql_hba.first; link != NULL; link = link->next) {
9610                 ha = link->base_address;
9611 
9612                 /* Skip adapter if suspended of stalled. */
9613                 ADAPTER_STATE_LOCK(ha);
9614                 if (ha->flags & ADAPTER_SUSPENDED ||
9615                     ha->task_daemon_flags & DRIVER_STALL) {
9616                         ADAPTER_STATE_UNLOCK(ha);
9617                         continue;
9618                 }
9619                 ha->flags |= ADAPTER_TIMER_BUSY;
9620                 ADAPTER_STATE_UNLOCK(ha);
9621 
9622                 QL_PM_LOCK(ha);
9623                 if (ha->power_level != PM_LEVEL_D0) {
9624                         QL_PM_UNLOCK(ha);
9625 
9626                         ADAPTER_STATE_LOCK(ha);
9627                         ha->flags &= ~ADAPTER_TIMER_BUSY;
9628                         ADAPTER_STATE_UNLOCK(ha);
9629                         continue;
9630                 }
9631                 ha->busy++;
9632                 QL_PM_UNLOCK(ha);
9633 
9634                 set_flags = 0;
9635                 reset_flags = 0;
9636 
9637                 /* Port retry timer handler. */
9638                 if (LOOP_READY(ha)) {
9639                         ADAPTER_STATE_LOCK(ha);
9640                         if (ha->port_retry_timer != 0) {
9641                                 ha->port_retry_timer--;
9642                                 if (ha->port_retry_timer == 0) {
9643                                         set_flags |= PORT_RETRY_NEEDED;
9644                                 }
9645                         }
9646                         ADAPTER_STATE_UNLOCK(ha);
9647                 }
9648 
9649                 /* Loop down timer handler. */
9650                 if (LOOP_RECONFIGURE(ha) == 0) {
9651                         if (ha->loop_down_timer > LOOP_DOWN_TIMER_END) {
9652                                 ha->loop_down_timer--;
9653                                 /*
9654                                  * give the firmware loop down dump flag
9655                                  * a chance to work.
9656                                  */
9657                                 if (ha->loop_down_timer == LOOP_DOWN_RESET) {
9658                                         if (CFG_IST(ha,
9659                                             CFG_DUMP_LOOP_OFFLINE_TIMEOUT)) {
9660                                                 (void) ql_binary_fw_dump(ha,
9661                                                     TRUE);
9662                                         }
9663                                         EL(ha, "loop_down_reset, "
9664                                             "isp_abort_needed\n");
9665                                         set_flags |= ISP_ABORT_NEEDED;
9666                                 }
9667                         }
9668                         if (CFG_IST(ha, CFG_ENABLE_LINK_DOWN_REPORTING)) {
9669                                 /* Command abort time handler. */
9670                                 if (ha->loop_down_timer ==
9671                                     ha->loop_down_abort_time) {
9672                                         ADAPTER_STATE_LOCK(ha);
9673                                         ha->flags |= ABORT_CMDS_LOOP_DOWN_TMO;
9674                                         ADAPTER_STATE_UNLOCK(ha);
9675                                         set_flags |= ABORT_QUEUES_NEEDED;
9676                                         EL(ha, "loop_down_abort_time, "
9677                                             "abort_queues_needed\n");
9678                                 }
9679 
9680                                 /* Watchdog timer handler. */
9681                                 if (ha->watchdog_timer == 0) {
9682                                         ha->watchdog_timer = WATCHDOG_TIME;
9683                                 } else if (LOOP_READY(ha)) {
9684                                         ha->watchdog_timer--;
9685                                         if (ha->watchdog_timer == 0) {
9686                                                 for (vha = ha; vha != NULL;
9687                                                     vha = vha->vp_next) {
9688                                                         ql_watchdog(vha,
9689                                                             &set_flags,
9690                                                             &reset_flags);
9691                                                 }
9692                                                 ha->watchdog_timer =
9693                                                     WATCHDOG_TIME;
9694                                         }
9695                                 }
9696                         }
9697                 }
9698 
9699                 /* Idle timer handler. */
9700                 if (!DRIVER_SUSPENDED(ha)) {
9701                         if (++ha->idle_timer >= IDLE_CHECK_TIMER) {
9702 #if defined(QL_DEBUG_LEVEL_6) || !defined(QL_DEBUG_LEVEL_3)
9703                                 set_flags |= TASK_DAEMON_IDLE_CHK_FLG;
9704 #endif
9705                                 ha->idle_timer = 0;
9706                         }
9707                         if (ha->send_plogi_timer != NULL) {
9708                                 ha->send_plogi_timer--;
9709                                 if (ha->send_plogi_timer == NULL) {
9710                                         set_flags |= SEND_PLOGI;
9711                                 }
9712                         }
9713                 }
9714                 ADAPTER_STATE_LOCK(ha);
9715                 if (ha->idc_restart_timer != 0) {
9716                         ha->idc_restart_timer--;
9717                         if (ha->idc_restart_timer == 0) {
9718                                 ha->idc_restart_cnt = 0;
9719                                 reset_flags |= DRIVER_STALL;
9720                         }
9721                 }
9722                 if (ha->idc_flash_acc_timer != 0) {
9723                         ha->idc_flash_acc_timer--;
9724                         if (ha->idc_flash_acc_timer == 0 &&
9725                             ha->idc_flash_acc != 0) {
9726                                 ha->idc_flash_acc = 1;
9727                                 ha->idc_mb[0] = MBA_IDC_NOTIFICATION;
9728                                 ha->idc_mb[1] = 0;
9729                                 ha->idc_mb[2] = IDC_OPC_DRV_START;
9730                                 set_flags |= IDC_EVENT;
9731                         }
9732                 }
9733                 ADAPTER_STATE_UNLOCK(ha);
9734 
9735                 if (set_flags != 0 || reset_flags != 0) {
9736                         ql_awaken_task_daemon(ha, NULL, set_flags,
9737                             reset_flags);
9738                 }
9739 
9740                 if (ha->xioctl->ledstate.BeaconState == BEACON_ON) {
9741                         ql_blink_led(ha);
9742                 }
9743 
9744                 /* Update the IO stats */
9745                 if (ha->xioctl->IOInputByteCnt >= 0x100000) {
9746                         ha->xioctl->IOInputMByteCnt +=
9747                             (ha->xioctl->IOInputByteCnt / 0x100000);
9748                         ha->xioctl->IOInputByteCnt %= 0x100000;
9749                 }
9750 
9751                 if (ha->xioctl->IOOutputByteCnt >= 0x100000) {
9752                         ha->xioctl->IOOutputMByteCnt +=
9753                             (ha->xioctl->IOOutputByteCnt / 0x100000);
9754                         ha->xioctl->IOOutputByteCnt %= 0x100000;
9755                 }
9756 
9757                 if (CFG_IST(ha, CFG_CTRL_8021)) {
9758                         (void) ql_8021_idc_handler(ha);
9759                 }
9760 
9761                 ADAPTER_STATE_LOCK(ha);
9762                 ha->flags &= ~ADAPTER_TIMER_BUSY;
9763                 ADAPTER_STATE_UNLOCK(ha);
9764 
9765                 QL_PM_LOCK(ha);
9766                 ha->busy--;
9767                 QL_PM_UNLOCK(ha);
9768         }
9769 
9770         /* Restart timer, if not being stopped. */
9771         if (ql_timer_timeout_id != NULL) {
9772                 ql_timer_timeout_id = timeout(ql_timer, arg, ql_timer_ticks);
9773         }
9774 
9775         /* Release global state lock. */
9776         GLOBAL_STATE_UNLOCK();
9777 
9778         QL_PRINT_6(CE_CONT, "done\n");
9779 }
9780 
9781 /*
9782  * ql_timeout_insert
9783  *      Function used to insert a command block onto the
9784  *      watchdog timer queue.
9785  *
9786  *      Note: Must insure that pkt_time is not zero
9787  *                      before calling ql_timeout_insert.
9788  *
9789  * Input:
9790  *      ha:     adapter state pointer.
9791  *      tq:     target queue pointer.
9792  *      sp:     SRB pointer.
9793  *      DEVICE_QUEUE_LOCK must be already obtained.
9794  *
9795  * Context:
9796  *      Kernel context.
9797  */
9798 /* ARGSUSED */
9799 static void
9800 ql_timeout_insert(ql_adapter_state_t *ha, ql_tgt_t *tq, ql_srb_t *sp)
9801 {
9802         QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
9803 
9804         if (sp->pkt->pkt_timeout != 0 && sp->pkt->pkt_timeout < 0x10000) {
9805                 sp->isp_timeout = (uint16_t)(sp->pkt->pkt_timeout);
9806                 /*
9807                  * The WATCHDOG_TIME must be rounded up + 1.  As an example,
9808                  * consider a 1 second timeout. If the WATCHDOG_TIME is 1, it
9809                  * will expire in the next watchdog call, which could be in
9810                  * 1 microsecond.
9811                  *
9812                  */
9813                 sp->wdg_q_time = (sp->isp_timeout + WATCHDOG_TIME - 1) /
9814                     WATCHDOG_TIME;
9815                 /*
9816                  * Added an additional 10 to account for the
9817                  * firmware timer drift which can occur with
9818                  * very long timeout values.
9819                  */
9820                 sp->wdg_q_time += 10;
9821 
9822                 /*
9823                  * Add 6 more to insure watchdog does not timeout at the same
9824                  * time as ISP RISC code timeout.
9825                  */
9826                 sp->wdg_q_time += 6;
9827 
9828                 /* Save initial time for resetting watchdog time. */
9829                 sp->init_wdg_q_time = sp->wdg_q_time;
9830 
9831                 /* Insert command onto watchdog queue. */
9832                 ql_add_link_b(&tq->wdg, &sp->wdg);
9833 
9834                 sp->flags |= SRB_WATCHDOG_ENABLED;
9835         } else {
9836                 sp->isp_timeout = 0;
9837                 sp->wdg_q_time = 0;
9838                 sp->init_wdg_q_time = 0;
9839         }
9840 
9841         QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
9842 }
9843 
9844 /*
9845  * ql_watchdog
9846  *      Timeout handler that runs in interrupt context. The
9847  *      ql_adapter_state_t * argument is the parameter set up when the
9848  *      timeout was initialized (state structure pointer).
9849  *      Function used to update timeout values and if timeout
9850  *      has occurred command will be aborted.
9851  *
9852  * Input:
9853  *      ha:             adapter state pointer.
9854  *      set_flags:      task daemon flags to set.
9855  *      reset_flags:    task daemon flags to reset.
9856  *
9857  * Context:
9858  *      Interrupt context, no mailbox commands allowed.
9859  */
9860 static void
9861 ql_watchdog(ql_adapter_state_t *ha, uint32_t *set_flags, uint32_t *reset_flags)
9862 {
9863         ql_srb_t        *sp;
9864         ql_link_t       *link;
9865         ql_link_t       *next_cmd;
9866         ql_link_t       *next_device;
9867         ql_tgt_t        *tq;
9868         ql_lun_t        *lq;
9869         uint16_t        index;
9870         int             q_sane;
9871 
9872         QL_PRINT_6(CE_CONT, "(%d): started\n", ha->instance);
9873 
9874         /* Loop through all targets. */
9875         for (index = 0; index < DEVICE_HEAD_LIST_SIZE; index++) {
9876                 for (link = ha->dev[index].first; link != NULL;
9877                     link = next_device) {
9878                         tq = link->base_address;
9879 
9880                         /* Try to acquire device queue lock. */
9881                         if (TRY_DEVICE_QUEUE_LOCK(tq) == 0) {
9882                                 next_device = NULL;
9883                                 continue;
9884                         }
9885 
9886                         next_device = link->next;
9887 
9888                         if (!(CFG_IST(ha, CFG_ENABLE_LINK_DOWN_REPORTING)) &&
9889                             (tq->port_down_retry_count == 0)) {
9890                                 /* Release device queue lock. */
9891                                 DEVICE_QUEUE_UNLOCK(tq);
9892                                 continue;
9893                         }
9894 
9895                         /* Find out if this device is in a sane state. */
9896                         if (tq->flags & (TQF_RSCN_RCVD |
9897                             TQF_NEED_AUTHENTICATION | TQF_QUEUE_SUSPENDED)) {
9898                                 q_sane = 0;
9899                         } else {
9900                                 q_sane = 1;
9901                         }
9902                         /* Loop through commands on watchdog queue. */
9903                         for (link = tq->wdg.first; link != NULL;
9904                             link = next_cmd) {
9905                                 next_cmd = link->next;
9906                                 sp = link->base_address;
9907                                 lq = sp->lun_queue;
9908 
9909                                 /*
9910                                  * For SCSI commands, if everything seems to
9911                                  * be going fine and this packet is stuck
9912                                  * because of throttling at LUN or target
9913                                  * level then do not decrement the
9914                                  * sp->wdg_q_time
9915                                  */
9916                                 if (ha->task_daemon_flags & STATE_ONLINE &&
9917                                     (sp->flags & SRB_ISP_STARTED) == 0 &&
9918                                     q_sane && sp->flags & SRB_FCP_CMD_PKT &&
9919                                     lq->lun_outcnt >= ha->execution_throttle) {
9920                                         continue;
9921                                 }
9922 
9923                                 if (sp->wdg_q_time != 0) {
9924                                         sp->wdg_q_time--;
9925 
9926                                         /* Timeout? */
9927                                         if (sp->wdg_q_time != 0) {
9928                                                 continue;
9929                                         }
9930 
9931                                         ql_remove_link(&tq->wdg, &sp->wdg);
9932                                         sp->flags &= ~SRB_WATCHDOG_ENABLED;
9933 
9934                                         if (sp->flags & SRB_ISP_STARTED) {
9935                                                 ql_cmd_timeout(ha, tq, sp,
9936                                                     set_flags, reset_flags);
9937 
9938                                                 DEVICE_QUEUE_UNLOCK(tq);
9939                                                 tq = NULL;
9940                                                 next_cmd = NULL;
9941                                                 next_device = NULL;
9942                                                 index = DEVICE_HEAD_LIST_SIZE;
9943                                         } else {
9944                                                 ql_cmd_timeout(ha, tq, sp,
9945                                                     set_flags, reset_flags);
9946                                         }
9947                                 }
9948                         }
9949 
9950                         /* Release device queue lock. */
9951                         if (tq != NULL) {
9952                                 DEVICE_QUEUE_UNLOCK(tq);
9953                         }
9954                 }
9955         }
9956 
9957         QL_PRINT_6(CE_CONT, "(%d): done\n", ha->instance);
9958 }
9959 
9960 /*
9961  * ql_cmd_timeout
9962  *      Command timeout handler.
9963  *
9964  * Input:
9965  *      ha:             adapter state pointer.
9966  *      tq:             target queue pointer.
9967  *      sp:             SRB pointer.
9968  *      set_flags:      task daemon flags to set.
9969  *      reset_flags:    task daemon flags to reset.
9970  *
9971  * Context:
9972  *      Interrupt context, no mailbox commands allowed.
9973  */
9974 /* ARGSUSED */
9975 static void
9976 ql_cmd_timeout(ql_adapter_state_t *ha, ql_tgt_t *tq, ql_srb_t *sp,
9977     uint32_t *set_flags, uint32_t *reset_flags)
9978 {
9979         QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
9980 
9981         if (!(sp->flags & SRB_ISP_STARTED)) {
9982 
9983                 EL(ha, "command timed out in driver = %ph\n", (void *)sp);
9984 
9985                 REQUEST_RING_LOCK(ha);
9986 
9987                 /* if it's on a queue */
9988                 if (sp->cmd.head) {
9989                         /*
9990                          * The pending_cmds que needs to be
9991                          * protected by the ring lock
9992                          */
9993                         ql_remove_link(sp->cmd.head, &sp->cmd);
9994                 }
9995                 sp->flags &= ~SRB_IN_DEVICE_QUEUE;
9996 
9997                 /* Release device queue lock. */
9998                 REQUEST_RING_UNLOCK(ha);
9999                 DEVICE_QUEUE_UNLOCK(tq);
10000 
10001                 /* Set timeout status */
10002                 sp->pkt->pkt_reason = CS_TIMEOUT;
10003 
10004                 /* Ensure no retry */
10005                 sp->flags &= ~SRB_RETRY;
10006 
10007                 /* Call done routine to handle completion. */
10008                 ql_done(&sp->cmd);
10009 
10010                 DEVICE_QUEUE_LOCK(tq);
10011         } else if (CFG_IST(ha, CFG_CTRL_8021)) {
10012                 int             rval;
10013                 uint32_t        index;
10014 
10015                 EL(ha, "command timed out in isp=%ph, osc=%ph, index=%xh, "
10016                     "spf=%xh\n", (void *)sp,
10017                     (void *)ha->outstanding_cmds[sp->handle & OSC_INDEX_MASK],
10018                     sp->handle & OSC_INDEX_MASK, sp->flags);
10019 
10020                 DEVICE_QUEUE_UNLOCK(tq);
10021 
10022                 INTR_LOCK(ha);
10023                 ha->pha->xioctl->ControllerErrorCount++;
10024                 if (sp->handle) {
10025                         ha->pha->timeout_cnt++;
10026                         index = sp->handle & OSC_INDEX_MASK;
10027                         if (ha->pha->outstanding_cmds[index] == sp) {
10028                                 sp->request_ring_ptr->entry_type =
10029                                     INVALID_ENTRY_TYPE;
10030                                 sp->request_ring_ptr->entry_count = 0;
10031                                 ha->pha->outstanding_cmds[index] = 0;
10032                         }
10033                         INTR_UNLOCK(ha);
10034 
10035                         rval = ql_abort_command(ha, sp);
10036                         if (rval == QL_FUNCTION_TIMEOUT ||
10037                             rval == QL_LOCK_TIMEOUT ||
10038                             rval == QL_FUNCTION_PARAMETER_ERROR ||
10039                             ha->pha->timeout_cnt > TIMEOUT_THRESHOLD) {
10040                                 *set_flags |= ISP_ABORT_NEEDED;
10041                                 EL(ha, "abort status=%xh, tc=%xh, isp_abort_"
10042                                     "needed\n", rval, ha->pha->timeout_cnt);
10043                         }
10044 
10045                         sp->handle = 0;
10046                         sp->flags &= ~SRB_IN_TOKEN_ARRAY;
10047                 } else {
10048                         INTR_UNLOCK(ha);
10049                 }
10050 
10051                 /* Set timeout status */
10052                 sp->pkt->pkt_reason = CS_TIMEOUT;
10053 
10054                 /* Ensure no retry */
10055                 sp->flags &= ~SRB_RETRY;
10056 
10057                 /* Call done routine to handle completion. */
10058                 ql_done(&sp->cmd);
10059 
10060                 DEVICE_QUEUE_LOCK(tq);
10061 
10062         } else {
10063                 EL(ha, "command timed out in isp=%ph, osc=%ph, index=%xh, "
10064                     "spf=%xh, isp_abort_needed\n", (void *)sp,
10065                     (void *)ha->outstanding_cmds[sp->handle & OSC_INDEX_MASK],
10066                     sp->handle & OSC_INDEX_MASK, sp->flags);
10067 
10068                 /* Release device queue lock. */
10069                 DEVICE_QUEUE_UNLOCK(tq);
10070 
10071                 INTR_LOCK(ha);
10072                 ha->pha->xioctl->ControllerErrorCount++;
10073                 INTR_UNLOCK(ha);
10074 
10075                 /* Set ISP needs to be reset */
10076                 sp->flags |= SRB_COMMAND_TIMEOUT;
10077 
10078                 if (CFG_IST(ha, CFG_DUMP_DRIVER_COMMAND_TIMEOUT)) {
10079                         (void) ql_binary_fw_dump(ha, TRUE);
10080                 }
10081 
10082                 *set_flags |= ISP_ABORT_NEEDED;
10083 
10084                 DEVICE_QUEUE_LOCK(tq);
10085         }
10086 
10087         QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
10088 }
10089 
10090 /*
10091  * ql_rst_aen
10092  *      Processes asynchronous reset.
10093  *
10094  * Input:
10095  *      ha = adapter state pointer.
10096  *
10097  * Context:
10098  *      Kernel context.
10099  */
10100 static void
10101 ql_rst_aen(ql_adapter_state_t *ha)
10102 {
10103         QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
10104 
10105         /* Issue marker command. */
10106         (void) ql_marker(ha, 0, 0, MK_SYNC_ALL);
10107 
10108         QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
10109 }
10110 
10111 /*
10112  * ql_cmd_wait
10113  *      Stall driver until all outstanding commands are returned.
10114  *
10115  * Input:
10116  *      ha = adapter state pointer.
10117  *
10118  * Context:
10119  *      Kernel context.
10120  */
10121 void
10122 ql_cmd_wait(ql_adapter_state_t *ha)
10123 {
10124         uint16_t                index;
10125         ql_link_t               *link;
10126         ql_tgt_t                *tq;
10127         ql_adapter_state_t      *vha;
10128 
10129         QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
10130 
10131         /* Wait for all outstanding commands to be returned. */
10132         (void) ql_wait_outstanding(ha);
10133 
10134         /*
10135          * clear out internally queued commands
10136          */
10137         for (vha = ha; vha != NULL; vha = vha->vp_next) {
10138                 for (index = 0; index < DEVICE_HEAD_LIST_SIZE; index++) {
10139                         for (link = vha->dev[index].first; link != NULL;
10140                             link = link->next) {
10141                                 tq = link->base_address;
10142                                 if (tq &&
10143                                     (!(tq->prli_svc_param_word_3 &
10144                                     PRLI_W3_RETRY))) {
10145                                         (void) ql_abort_device(vha, tq, 0);
10146                                 }
10147                         }
10148                 }
10149         }
10150 
10151         QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
10152 }
10153 
10154 /*
10155  * ql_wait_outstanding
10156  *      Wait for all outstanding commands to complete.
10157  *
10158  * Input:
10159  *      ha = adapter state pointer.
10160  *
10161  * Returns:
10162  *      index - the index for ql_srb into outstanding_cmds.
10163  *
10164  * Context:
10165  *      Kernel context.
10166  */
10167 static uint16_t
10168 ql_wait_outstanding(ql_adapter_state_t *ha)
10169 {
10170         ql_srb_t        *sp;
10171         uint16_t        index, count;
10172 
10173         QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
10174 
10175         count = ql_osc_wait_count;
10176         for (index = 1; index < MAX_OUTSTANDING_COMMANDS; index++) {
10177                 if (ha->pha->pending_cmds.first != NULL) {
10178                         ql_start_iocb(ha, NULL);
10179                         index = 1;
10180                 }
10181                 if ((sp = ha->pha->outstanding_cmds[index]) != NULL &&
10182                     (sp->flags & SRB_COMMAND_TIMEOUT) == 0) {
10183                         if (count-- != 0) {
10184                                 ql_delay(ha, 10000);
10185                                 index = 0;
10186                         } else {
10187                                 EL(ha, "failed, sp=%ph, oci=%d, hdl=%xh\n",
10188                                     (void *)sp, index, sp->handle);
10189                                 break;
10190                         }
10191                 }
10192         }
10193 
10194         QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
10195 
10196         return (index);
10197 }
10198 
10199 /*
10200  * ql_restart_queues
10201  *      Restart device queues.
10202  *
10203  * Input:
10204  *      ha = adapter state pointer.
10205  *      DEVICE_QUEUE_LOCK must be released.
10206  *
10207  * Context:
10208  *      Interrupt or Kernel context, no mailbox commands allowed.
10209  */
10210 static void
10211 ql_restart_queues(ql_adapter_state_t *ha)
10212 {
10213         ql_link_t               *link, *link2;
10214         ql_tgt_t                *tq;
10215         ql_lun_t                *lq;
10216         uint16_t                index;
10217         ql_adapter_state_t      *vha;
10218 
10219         QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
10220 
10221         for (vha = ha->pha; vha != NULL; vha = vha->vp_next) {
10222                 for (index = 0; index < DEVICE_HEAD_LIST_SIZE; index++) {
10223                         for (link = vha->dev[index].first; link != NULL;
10224                             link = link->next) {
10225                                 tq = link->base_address;
10226 
10227                                 /* Acquire device queue lock. */
10228                                 DEVICE_QUEUE_LOCK(tq);
10229 
10230                                 tq->flags &= ~TQF_QUEUE_SUSPENDED;
10231 
10232                                 for (link2 = tq->lun_queues.first;
10233                                     link2 != NULL; link2 = link2->next) {
10234                                         lq = link2->base_address;
10235 
10236                                         if (lq->cmd.first != NULL) {
10237                                                 ql_next(vha, lq);
10238                                                 DEVICE_QUEUE_LOCK(tq);
10239                                         }
10240                                 }
10241 
10242                                 /* Release device queue lock. */
10243                                 DEVICE_QUEUE_UNLOCK(tq);
10244                         }
10245                 }
10246         }
10247 
10248         QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
10249 }
10250 
10251 /*
10252  * ql_iidma
10253  *      Setup iiDMA parameters to firmware
10254  *
10255  * Input:
10256  *      ha = adapter state pointer.
10257  *      DEVICE_QUEUE_LOCK must be released.
10258  *
10259  * Context:
10260  *      Interrupt or Kernel context, no mailbox commands allowed.
10261  */
10262 static void
10263 ql_iidma(ql_adapter_state_t *ha)
10264 {
10265         ql_link_t       *link;
10266         ql_tgt_t        *tq;
10267         uint16_t        index;
10268         char            buf[256];
10269         uint32_t        data;
10270 
10271         QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
10272 
10273         if ((CFG_IST(ha, CFG_CTRL_242581)) == 0) {
10274                 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
10275                 return;
10276         }
10277 
10278         for (index = 0; index < DEVICE_HEAD_LIST_SIZE; index++) {
10279                 for (link = ha->dev[index].first; link != NULL;
10280                     link = link->next) {
10281                         tq = link->base_address;
10282 
10283                         /* Acquire device queue lock. */
10284                         DEVICE_QUEUE_LOCK(tq);
10285 
10286                         if ((tq->flags & TQF_IIDMA_NEEDED) == 0) {
10287                                 DEVICE_QUEUE_UNLOCK(tq);
10288                                 continue;
10289                         }
10290 
10291                         tq->flags &= ~TQF_IIDMA_NEEDED;
10292 
10293                         if ((tq->loop_id > LAST_N_PORT_HDL) ||
10294                             (tq->iidma_rate == IIDMA_RATE_NDEF)) {
10295                                 DEVICE_QUEUE_UNLOCK(tq);
10296                                 continue;
10297                         }
10298 
10299                         /* Get the iiDMA persistent data */
10300                         if (tq->iidma_rate == IIDMA_RATE_INIT) {
10301                                 (void) sprintf(buf,
10302                                     "iidma-rate-%02x%02x%02x%02x%02x"
10303                                     "%02x%02x%02x", tq->port_name[0],
10304                                     tq->port_name[1], tq->port_name[2],
10305                                     tq->port_name[3], tq->port_name[4],
10306                                     tq->port_name[5], tq->port_name[6],
10307                                     tq->port_name[7]);
10308 
10309                                 if ((data = ql_get_prop(ha, buf)) ==
10310                                     0xffffffff) {
10311                                         tq->iidma_rate = IIDMA_RATE_NDEF;
10312                                 } else {
10313                                         switch (data) {
10314                                         case IIDMA_RATE_1GB:
10315                                         case IIDMA_RATE_2GB:
10316                                         case IIDMA_RATE_4GB:
10317                                         case IIDMA_RATE_10GB:
10318                                                 tq->iidma_rate = data;
10319                                                 break;
10320                                         case IIDMA_RATE_8GB:
10321                                                 if (CFG_IST(ha,
10322                                                     CFG_CTRL_25XX)) {
10323                                                         tq->iidma_rate = data;
10324                                                 } else {
10325                                                         tq->iidma_rate =
10326                                                             IIDMA_RATE_4GB;
10327                                                 }
10328                                                 break;
10329                                         default:
10330                                                 EL(ha, "invalid data for "
10331                                                     "parameter: %s: %xh\n",
10332                                                     buf, data);
10333                                                 tq->iidma_rate =
10334                                                     IIDMA_RATE_NDEF;
10335                                                 break;
10336                                         }
10337                                 }
10338                         }
10339 
10340                         /* Set the firmware's iiDMA rate */
10341                         if (tq->iidma_rate <= IIDMA_RATE_MAX &&
10342                             !(CFG_IST(ha, CFG_CTRL_8081))) {
10343                                 data = ql_iidma_rate(ha, tq->loop_id,
10344                                     &tq->iidma_rate, EXT_IIDMA_MODE_SET);
10345                                 if (data != QL_SUCCESS) {
10346                                         EL(ha, "mbx failed: %xh\n", data);
10347                                 }
10348                         }
10349 
10350                         /* Release device queue lock. */
10351                         DEVICE_QUEUE_UNLOCK(tq);
10352                 }
10353         }
10354 
10355         QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
10356 }
10357 
10358 /*
10359  * ql_abort_queues
10360  *      Abort all commands on device queues.
10361  *
10362  * Input:
10363  *      ha = adapter state pointer.
10364  *
10365  * Context:
10366  *      Interrupt or Kernel context, no mailbox commands allowed.
10367  */
10368 static void
10369 ql_abort_queues(ql_adapter_state_t *ha)
10370 {
10371         ql_link_t               *link;
10372         ql_tgt_t                *tq;
10373         ql_srb_t                *sp;
10374         uint16_t                index;
10375         ql_adapter_state_t      *vha;
10376 
10377         QL_PRINT_10(CE_CONT, "(%d): started\n", ha->instance);
10378 
10379         /* Return all commands in outstanding command list. */
10380         INTR_LOCK(ha);
10381 
10382         /* Place all commands in outstanding cmd list on device queue. */
10383         for (index = 1; index < MAX_OUTSTANDING_COMMANDS; index++) {
10384                 if (ha->pending_cmds.first != NULL) {
10385                         INTR_UNLOCK(ha);
10386                         ql_start_iocb(ha, NULL);
10387                         /* Delay for system */
10388                         ql_delay(ha, 10000);
10389                         INTR_LOCK(ha);
10390                         index = 1;
10391                 }
10392                 sp = ha->outstanding_cmds[index];
10393 
10394                 /* skip devices capable of FCP2 retrys */
10395                 if ((sp != NULL) &&
10396                     ((tq = sp->lun_queue->target_queue) != NULL) &&
10397                     (!(tq->prli_svc_param_word_3 & PRLI_W3_RETRY))) {
10398                         ha->outstanding_cmds[index] = NULL;
10399                         sp->handle = 0;
10400                         sp->flags &= ~SRB_IN_TOKEN_ARRAY;
10401 
10402                         INTR_UNLOCK(ha);
10403 
10404                         /* Set ending status. */
10405                         sp->pkt->pkt_reason = CS_PORT_UNAVAILABLE;
10406                         sp->flags |= SRB_ISP_COMPLETED;
10407 
10408                         /* Call done routine to handle completions. */
10409                         sp->cmd.next = NULL;
10410                         ql_done(&sp->cmd);
10411 
10412                         INTR_LOCK(ha);
10413                 }
10414         }
10415         INTR_UNLOCK(ha);
10416 
10417         for (vha = ha; vha != NULL; vha = vha->vp_next) {
10418                 QL_PRINT_10(CE_CONT, "(%d,%d): abort instance\n",
10419                     vha->instance, vha->vp_index);
10420                 for (index = 0; index < DEVICE_HEAD_LIST_SIZE; index++) {
10421                         for (link = vha->dev[index].first; link != NULL;
10422                             link = link->next) {
10423                                 tq = link->base_address;
10424                                 /* skip devices capable of FCP2 retrys */
10425                                 if (!(tq->prli_svc_param_word_3 &
10426                                     PRLI_W3_RETRY)) {
10427                                         /*
10428                                          * Set port unavailable status and
10429                                          * return all commands on a devices
10430                                          * queues.
10431                                          */
10432                                         ql_abort_device_queues(ha, tq);
10433                                 }
10434                         }
10435                 }
10436         }
10437         QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
10438 }
10439 
10440 /*
10441  * ql_abort_device_queues
10442  *      Abort all commands on device queues.
10443  *
10444  * Input:
10445  *      ha = adapter state pointer.
10446  *
10447  * Context:
10448  *      Interrupt or Kernel context, no mailbox commands allowed.
10449  */
10450 static void
10451 ql_abort_device_queues(ql_adapter_state_t *ha, ql_tgt_t *tq)
10452 {
10453         ql_link_t       *lun_link, *cmd_link;
10454         ql_srb_t        *sp;
10455         ql_lun_t        *lq;
10456 
10457         QL_PRINT_10(CE_CONT, "(%d): started\n", ha->instance);
10458 
10459         DEVICE_QUEUE_LOCK(tq);
10460 
10461         for (lun_link = tq->lun_queues.first; lun_link != NULL;
10462             lun_link = lun_link->next) {
10463                 lq = lun_link->base_address;
10464 
10465                 cmd_link = lq->cmd.first;
10466                 while (cmd_link != NULL) {
10467                         sp = cmd_link->base_address;
10468 
10469                         if (sp->flags & SRB_ABORT) {
10470                                 cmd_link = cmd_link->next;
10471                                 continue;
10472                         }
10473 
10474                         /* Remove srb from device cmd queue. */
10475                         ql_remove_link(&lq->cmd, &sp->cmd);
10476 
10477                         sp->flags &= ~SRB_IN_DEVICE_QUEUE;
10478 
10479                         DEVICE_QUEUE_UNLOCK(tq);
10480 
10481                         /* Set ending status. */
10482                         sp->pkt->pkt_reason = CS_PORT_UNAVAILABLE;
10483 
10484                         /* Call done routine to handle completion. */
10485                         ql_done(&sp->cmd);
10486 
10487                         /* Delay for system */
10488                         ql_delay(ha, 10000);
10489 
10490                         DEVICE_QUEUE_LOCK(tq);
10491                         cmd_link = lq->cmd.first;
10492                 }
10493         }
10494         DEVICE_QUEUE_UNLOCK(tq);
10495 
10496         QL_PRINT_10(CE_CONT, "(%d): done\n", ha->instance);
10497 }
10498 
10499 /*
10500  * ql_loop_resync
10501  *      Resync with fibre channel devices.
10502  *
10503  * Input:
10504  *      ha = adapter state pointer.
10505  *      DEVICE_QUEUE_LOCK must be released.
10506  *
10507  * Returns:
10508  *      ql local function return status code.
10509  *
10510  * Context:
10511  *      Kernel context.
10512  */
10513 static int
10514 ql_loop_resync(ql_adapter_state_t *ha)
10515 {
10516         int rval;
10517 
10518         QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
10519 
10520         if (ha->flags & IP_INITIALIZED) {
10521                 (void) ql_shutdown_ip(ha);
10522         }
10523 
10524         rval = ql_fw_ready(ha, 10);
10525 
10526         TASK_DAEMON_LOCK(ha);
10527         ha->task_daemon_flags &= ~LOOP_RESYNC_ACTIVE;
10528         TASK_DAEMON_UNLOCK(ha);
10529 
10530         /* Set loop online, if it really is. */
10531         if (rval == QL_SUCCESS) {
10532                 ql_loop_online(ha);
10533                 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
10534         } else {
10535                 EL(ha, "failed, rval = %xh\n", rval);
10536         }
10537 
10538         return (rval);
10539 }
10540 
10541 /*
10542  * ql_loop_online
10543  *      Set loop online status if it really is online.
10544  *
10545  * Input:
10546  *      ha = adapter state pointer.
10547  *      DEVICE_QUEUE_LOCK must be released.
10548  *
10549  * Context:
10550  *      Kernel context.
10551  */
10552 void
10553 ql_loop_online(ql_adapter_state_t *ha)
10554 {
10555         ql_adapter_state_t      *vha;
10556 
10557         QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
10558 
10559         /* Inform the FC Transport that the hardware is online. */
10560         for (vha = ha->pha; vha != NULL; vha = vha->vp_next) {
10561                 if (!(vha->task_daemon_flags &
10562                     (LOOP_RESYNC_NEEDED | LOOP_DOWN))) {
10563                         /* Restart IP if it was shutdown. */
10564                         if (vha->vp_index == 0 && vha->flags & IP_ENABLED &&
10565                             !(vha->flags & IP_INITIALIZED)) {
10566                                 (void) ql_initialize_ip(vha);
10567                                 ql_isp_rcvbuf(vha);
10568                         }
10569 
10570                         if (FC_PORT_STATE_MASK(vha->state) != FC_STATE_LOOP &&
10571                             FC_PORT_STATE_MASK(vha->state) !=
10572                             FC_STATE_ONLINE) {
10573                                 vha->state = FC_PORT_SPEED_MASK(vha->state);
10574                                 if (vha->topology & QL_LOOP_CONNECTION) {
10575                                         vha->state |= FC_STATE_LOOP;
10576                                 } else {
10577                                         vha->state |= FC_STATE_ONLINE;
10578                                 }
10579                                 TASK_DAEMON_LOCK(ha);
10580                                 vha->task_daemon_flags |= FC_STATE_CHANGE;
10581                                 TASK_DAEMON_UNLOCK(ha);
10582                         }
10583                 }
10584         }
10585 
10586         ql_awaken_task_daemon(ha, NULL, 0, 0);
10587 
10588         /* Restart device queues that may have been stopped. */
10589         ql_restart_queues(ha);
10590 
10591         QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
10592 }
10593 
10594 /*
10595  * ql_fca_handle_to_state
10596  *      Verifies handle to be correct.
10597  *
10598  * Input:
10599  *      fca_handle = pointer to state structure.
10600  *
10601  * Returns:
10602  *      NULL = failure
10603  *
10604  * Context:
10605  *      Kernel context.
10606  */
10607 static ql_adapter_state_t *
10608 ql_fca_handle_to_state(opaque_t fca_handle)
10609 {
10610 #ifdef  QL_DEBUG_ROUTINES
10611         ql_link_t               *link;
10612         ql_adapter_state_t      *ha = NULL;
10613         ql_adapter_state_t      *vha = NULL;
10614 
10615         for (link = ql_hba.first; link != NULL; link = link->next) {
10616                 ha = link->base_address;
10617                 for (vha = ha->vp_next; vha != NULL; vha = vha->vp_next) {
10618                         if ((opaque_t)vha == fca_handle) {
10619                                 ha = vha;
10620                                 break;
10621                         }
10622                 }
10623                 if ((opaque_t)ha == fca_handle) {
10624                         break;
10625                 } else {
10626                         ha = NULL;
10627                 }
10628         }
10629 
10630         if (ha == NULL) {
10631                 /*EMPTY*/
10632                 QL_PRINT_2(CE_CONT, "failed\n");
10633         }
10634 
10635 #endif /* QL_DEBUG_ROUTINES */
10636 
10637         return ((ql_adapter_state_t *)fca_handle);
10638 }
10639 
10640 /*
10641  * ql_d_id_to_queue
10642  *      Locate device queue that matches destination ID.
10643  *
10644  * Input:
10645  *      ha = adapter state pointer.
10646  *      d_id = destination ID
10647  *
10648  * Returns:
10649  *      NULL = failure
10650  *
10651  * Context:
10652  *      Interrupt or Kernel context, no mailbox commands allowed.
10653  */
10654 ql_tgt_t *
10655 ql_d_id_to_queue(ql_adapter_state_t *ha, port_id_t d_id)
10656 {
10657         uint16_t        index;
10658         ql_tgt_t        *tq;
10659         ql_link_t       *link;
10660 
10661         /* Get head queue index. */
10662         index = ql_alpa_to_index[d_id.b.al_pa];
10663 
10664         for (link = ha->dev[index].first; link != NULL; link = link->next) {
10665                 tq = link->base_address;
10666                 if (tq->d_id.b24 == d_id.b24 &&
10667                     VALID_DEVICE_ID(ha, tq->loop_id)) {
10668                         return (tq);
10669                 }
10670         }
10671 
10672         return (NULL);
10673 }
10674 
10675 /*
10676  * ql_loop_id_to_queue
10677  *      Locate device queue that matches loop ID.
10678  *
10679  * Input:
10680  *      ha:             adapter state pointer.
10681  *      loop_id:        destination ID
10682  *
10683  * Returns:
10684  *      NULL = failure
10685  *
10686  * Context:
10687  *      Interrupt or Kernel context, no mailbox commands allowed.
10688  */
10689 ql_tgt_t *
10690 ql_loop_id_to_queue(ql_adapter_state_t *ha, uint16_t loop_id)
10691 {
10692         uint16_t        index;
10693         ql_tgt_t        *tq;
10694         ql_link_t       *link;
10695 
10696         for (index = 0; index < DEVICE_HEAD_LIST_SIZE; index++) {
10697                 for (link = ha->dev[index].first; link != NULL;
10698                     link = link->next) {
10699                         tq = link->base_address;
10700                         if (tq->loop_id == loop_id) {
10701                                 return (tq);
10702                         }
10703                 }
10704         }
10705 
10706         return (NULL);
10707 }
10708 
10709 /*
10710  * ql_kstat_update
10711  *      Updates kernel statistics.
10712  *
10713  * Input:
10714  *      ksp - driver kernel statistics structure pointer.
10715  *      rw - function to perform
10716  *
10717  * Returns:
10718  *      0 or EACCES
10719  *
10720  * Context:
10721  *      Kernel context.
10722  */
10723 /* ARGSUSED */
10724 static int
10725 ql_kstat_update(kstat_t *ksp, int rw)
10726 {
10727         int                     rval;
10728 
10729         QL_PRINT_3(CE_CONT, "started\n");
10730 
10731         if (rw == KSTAT_WRITE) {
10732                 rval = EACCES;
10733         } else {
10734                 rval = 0;
10735         }
10736 
10737         if (rval != 0) {
10738                 /*EMPTY*/
10739                 QL_PRINT_2(CE_CONT, "failed, rval = %xh\n", rval);
10740         } else {
10741                 /*EMPTY*/
10742                 QL_PRINT_3(CE_CONT, "done\n");
10743         }
10744         return (rval);
10745 }
10746 
10747 /*
10748  * ql_load_flash
10749  *      Loads flash.
10750  *
10751  * Input:
10752  *      ha:     adapter state pointer.
10753  *      dp:     data pointer.
10754  *      size:   data length.
10755  *
10756  * Returns:
10757  *      ql local function return status code.
10758  *
10759  * Context:
10760  *      Kernel context.
10761  */
10762 int
10763 ql_load_flash(ql_adapter_state_t *ha, uint8_t *dp, uint32_t size)
10764 {
10765         uint32_t        cnt;
10766         int             rval;
10767         uint32_t        size_to_offset;
10768         uint32_t        size_to_compare;
10769         int             erase_all;
10770 
10771         if (CFG_IST(ha, CFG_CTRL_24258081)) {
10772                 return (ql_24xx_load_flash(ha, dp, size, 0));
10773         }
10774 
10775         QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
10776 
10777         size_to_compare = 0x20000;
10778         size_to_offset = 0;
10779         erase_all = 0;
10780         if (CFG_IST(ha, CFG_SBUS_CARD)) {
10781                 if (size == 0x80000) {
10782                         /* Request to flash the entire chip. */
10783                         size_to_compare = 0x80000;
10784                         erase_all = 1;
10785                 } else {
10786                         size_to_compare = 0x40000;
10787                         if (ql_flash_sbus_fpga) {
10788                                 size_to_offset = 0x40000;
10789                         }
10790                 }
10791         }
10792         if (size > size_to_compare) {
10793                 rval = QL_FUNCTION_PARAMETER_ERROR;
10794                 EL(ha, "failed=%xh\n", rval);
10795                 return (rval);
10796         }
10797 
10798         GLOBAL_HW_LOCK();
10799 
10800         /* Enable Flash Read/Write. */
10801         ql_flash_enable(ha);
10802 
10803         /* Erase flash prior to write. */
10804         rval = ql_erase_flash(ha, erase_all);
10805 
10806         if (rval == QL_SUCCESS) {
10807                 /* Write data to flash. */
10808                 for (cnt = 0; cnt < size; cnt++) {
10809                         /* Allow other system activity. */
10810                         if (cnt % 0x1000 == 0) {
10811                                 ql_delay(ha, 10000);
10812                         }
10813                         rval = ql_program_flash_address(ha,
10814                             cnt + size_to_offset, *dp++);
10815                         if (rval != QL_SUCCESS) {
10816                                 break;
10817                         }
10818                 }
10819         }
10820 
10821         ql_flash_disable(ha);
10822 
10823         GLOBAL_HW_UNLOCK();
10824 
10825         if (rval != QL_SUCCESS) {
10826                 EL(ha, "failed=%xh\n", rval);
10827         } else {
10828                 /*EMPTY*/
10829                 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
10830         }
10831         return (rval);
10832 }
10833 
10834 /*
10835  * ql_program_flash_address
10836  *      Program flash address.
10837  *
10838  * Input:
10839  *      ha = adapter state pointer.
10840  *      addr = flash byte address.
10841  *      data = data to be written to flash.
10842  *
10843  * Returns:
10844  *      ql local function return status code.
10845  *
10846  * Context:
10847  *      Kernel context.
10848  */
10849 static int
10850 ql_program_flash_address(ql_adapter_state_t *ha, uint32_t addr, uint8_t data)
10851 {
10852         int rval;
10853 
10854         QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
10855 
10856         if (CFG_IST(ha, CFG_SBUS_CARD)) {
10857                 ql_write_flash_byte(ha, 0x5555, 0xa0);
10858                 ql_write_flash_byte(ha, addr, data);
10859         } else {
10860                 /* Write Program Command Sequence */
10861                 ql_write_flash_byte(ha, 0x5555, 0xaa);
10862                 ql_write_flash_byte(ha, 0x2aaa, 0x55);
10863                 ql_write_flash_byte(ha, 0x5555, 0xa0);
10864                 ql_write_flash_byte(ha, addr, data);
10865         }
10866 
10867         /* Wait for write to complete. */
10868         rval = ql_poll_flash(ha, addr, data);
10869 
10870         if (rval != QL_SUCCESS) {
10871                 EL(ha, "failed=%xh\n", rval);
10872         } else {
10873                 /*EMPTY*/
10874                 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
10875         }
10876         return (rval);
10877 }
10878 
10879 /*
10880  * ql_erase_flash
10881  *      Erases entire flash.
10882  *
10883  * Input:
10884  *      ha = adapter state pointer.
10885  *
10886  * Returns:
10887  *      ql local function return status code.
10888  *
10889  * Context:
10890  *      Kernel context.
10891  */
10892 int
10893 ql_erase_flash(ql_adapter_state_t *ha, int erase_all)
10894 {
10895         int             rval;
10896         uint32_t        erase_delay = 2000000;
10897         uint32_t        sStartAddr;
10898         uint32_t        ssize;
10899         uint32_t        cnt;
10900         uint8_t         *bfp;
10901         uint8_t         *tmp;
10902 
10903         QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
10904 
10905         if ((CFG_IST(ha, CFG_SBUS_CARD)) && !erase_all) {
10906 
10907                 if (ql_flash_sbus_fpga == 1) {
10908                         ssize = QL_SBUS_FCODE_SIZE;
10909                         sStartAddr = QL_FCODE_OFFSET;
10910                 } else {
10911                         ssize = QL_FPGA_SIZE;
10912                         sStartAddr = QL_FPGA_OFFSET;
10913                 }
10914 
10915                 erase_delay = 20000000;
10916 
10917                 bfp = (uint8_t *)kmem_zalloc(ssize, KM_SLEEP);
10918 
10919                 /* Save the section of flash we're not updating to buffer */
10920                 tmp = bfp;
10921                 for (cnt = sStartAddr; cnt < ssize+sStartAddr; cnt++) {
10922                         /* Allow other system activity. */
10923                         if (cnt % 0x1000 == 0) {
10924                                 ql_delay(ha, 10000);
10925                         }
10926                         *tmp++ = (uint8_t)ql_read_flash_byte(ha, cnt);
10927                 }
10928         }
10929 
10930         /* Chip Erase Command Sequence */
10931         ql_write_flash_byte(ha, 0x5555, 0xaa);
10932         ql_write_flash_byte(ha, 0x2aaa, 0x55);
10933         ql_write_flash_byte(ha, 0x5555, 0x80);
10934         ql_write_flash_byte(ha, 0x5555, 0xaa);
10935         ql_write_flash_byte(ha, 0x2aaa, 0x55);
10936         ql_write_flash_byte(ha, 0x5555, 0x10);
10937 
10938         ql_delay(ha, erase_delay);
10939 
10940         /* Wait for erase to complete. */
10941         rval = ql_poll_flash(ha, 0, 0x80);
10942 
10943         if (rval != QL_SUCCESS) {
10944                 EL(ha, "failed=%xh\n", rval);
10945                 if (CFG_IST(ha, CFG_SBUS_CARD)) {
10946                         kmem_free(bfp, ssize);
10947                 }
10948                 return (rval);
10949         }
10950 
10951         /* restore the section we saved in the buffer */
10952         if ((CFG_IST(ha, CFG_SBUS_CARD)) && !erase_all) {
10953                 /* Restore the section we saved off */
10954                 tmp = bfp;
10955                 for (cnt = sStartAddr; cnt < ssize+sStartAddr; cnt++) {
10956                         /* Allow other system activity. */
10957                         if (cnt % 0x1000 == 0) {
10958                                 ql_delay(ha, 10000);
10959                         }
10960                         rval = ql_program_flash_address(ha, cnt, *tmp++);
10961                         if (rval != QL_SUCCESS) {
10962                                 break;
10963                         }
10964                 }
10965 
10966                 kmem_free(bfp, ssize);
10967         }
10968 
10969         if (rval != QL_SUCCESS) {
10970                 EL(ha, "failed=%xh\n", rval);
10971         } else {
10972                 /*EMPTY*/
10973                 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
10974         }
10975         return (rval);
10976 }
10977 
10978 /*
10979  * ql_poll_flash
10980  *      Polls flash for completion.
10981  *
10982  * Input:
10983  *      ha = adapter state pointer.
10984  *      addr = flash byte address.
10985  *      data = data to be polled.
10986  *
10987  * Returns:
10988  *      ql local function return status code.
10989  *
10990  * Context:
10991  *      Kernel context.
10992  */
10993 int
10994 ql_poll_flash(ql_adapter_state_t *ha, uint32_t addr, uint8_t poll_data)
10995 {
10996         uint8_t         flash_data;
10997         uint32_t        cnt;
10998         int             rval = QL_FUNCTION_FAILED;
10999 
11000         QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
11001 
11002         poll_data = (uint8_t)(poll_data & BIT_7);
11003 
11004         /* Wait for 30 seconds for command to finish. */
11005         for (cnt = 30000000; cnt; cnt--) {
11006                 flash_data = (uint8_t)ql_read_flash_byte(ha, addr);
11007 
11008                 if ((flash_data & BIT_7) == poll_data) {
11009                         rval = QL_SUCCESS;
11010                         break;
11011                 }
11012                 if (flash_data & BIT_5 && cnt > 2) {
11013                         cnt = 2;
11014                 }
11015                 drv_usecwait(1);
11016         }
11017 
11018         if (rval != QL_SUCCESS) {
11019                 EL(ha, "failed=%xh\n", rval);
11020         } else {
11021                 /*EMPTY*/
11022                 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
11023         }
11024         return (rval);
11025 }
11026 
11027 /*
11028  * ql_flash_enable
11029  *      Setup flash for reading/writing.
11030  *
11031  * Input:
11032  *      ha = adapter state pointer.
11033  *
11034  * Context:
11035  *      Kernel context.
11036  */
11037 void
11038 ql_flash_enable(ql_adapter_state_t *ha)
11039 {
11040         uint16_t        data;
11041 
11042         QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
11043 
11044         /* Enable Flash Read/Write. */
11045         if (CFG_IST(ha, CFG_SBUS_CARD)) {
11046                 data = (uint16_t)ddi_get16(ha->sbus_fpga_dev_handle,
11047                     (uint16_t *)(ha->sbus_fpga_iobase + FPGA_CONF));
11048                 data = (uint16_t)(data | SBUS_FLASH_WRITE_ENABLE);
11049                 ddi_put16(ha->sbus_fpga_dev_handle,
11050                     (uint16_t *)(ha->sbus_fpga_iobase + FPGA_CONF), data);
11051                 /* Read reset command sequence */
11052                 ql_write_flash_byte(ha, 0xaaa, 0xaa);
11053                 ql_write_flash_byte(ha, 0x555, 0x55);
11054                 ql_write_flash_byte(ha, 0xaaa, 0x20);
11055                 ql_write_flash_byte(ha, 0x555, 0xf0);
11056         } else {
11057                 data = (uint16_t)(RD16_IO_REG(ha, ctrl_status) |
11058                     ISP_FLASH_ENABLE);
11059                 WRT16_IO_REG(ha, ctrl_status, data);
11060 
11061                 /* Read/Reset Command Sequence */
11062                 ql_write_flash_byte(ha, 0x5555, 0xaa);
11063                 ql_write_flash_byte(ha, 0x2aaa, 0x55);
11064                 ql_write_flash_byte(ha, 0x5555, 0xf0);
11065         }
11066         (void) ql_read_flash_byte(ha, 0);
11067 
11068         QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
11069 }
11070 
11071 /*
11072  * ql_flash_disable
11073  *      Disable flash and allow RISC to run.
11074  *
11075  * Input:
11076  *      ha = adapter state pointer.
11077  *
11078  * Context:
11079  *      Kernel context.
11080  */
11081 void
11082 ql_flash_disable(ql_adapter_state_t *ha)
11083 {
11084         uint16_t        data;
11085 
11086         QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
11087 
11088         if (CFG_IST(ha, CFG_SBUS_CARD)) {
11089                 /*
11090                  * Lock the flash back up.
11091                  */
11092                 ql_write_flash_byte(ha, 0x555, 0x90);
11093                 ql_write_flash_byte(ha, 0x555, 0x0);
11094 
11095                 data = (uint16_t)ddi_get16(ha->sbus_fpga_dev_handle,
11096                     (uint16_t *)(ha->sbus_fpga_iobase + FPGA_CONF));
11097                 data = (uint16_t)(data & ~SBUS_FLASH_WRITE_ENABLE);
11098                 ddi_put16(ha->sbus_fpga_dev_handle,
11099                     (uint16_t *)(ha->sbus_fpga_iobase + FPGA_CONF), data);
11100         } else {
11101                 data = (uint16_t)(RD16_IO_REG(ha, ctrl_status) &
11102                     ~ISP_FLASH_ENABLE);
11103                 WRT16_IO_REG(ha, ctrl_status, data);
11104         }
11105 
11106         QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
11107 }
11108 
11109 /*
11110  * ql_write_flash_byte
11111  *      Write byte to flash.
11112  *
11113  * Input:
11114  *      ha = adapter state pointer.
11115  *      addr = flash byte address.
11116  *      data = data to be written.
11117  *
11118  * Context:
11119  *      Kernel context.
11120  */
11121 void
11122 ql_write_flash_byte(ql_adapter_state_t *ha, uint32_t addr, uint8_t data)
11123 {
11124         if (CFG_IST(ha, CFG_SBUS_CARD)) {
11125                 ddi_put16(ha->sbus_fpga_dev_handle,
11126                     (uint16_t *)(ha->sbus_fpga_iobase + FPGA_EEPROM_LOADDR),
11127                     LSW(addr));
11128                 ddi_put16(ha->sbus_fpga_dev_handle,
11129                     (uint16_t *)(ha->sbus_fpga_iobase + FPGA_EEPROM_HIADDR),
11130                     MSW(addr));
11131                 ddi_put16(ha->sbus_fpga_dev_handle,
11132                     (uint16_t *)(ha->sbus_fpga_iobase + FPGA_EEPROM_DATA),
11133                     (uint16_t)data);
11134         } else {
11135                 uint16_t bank_select;
11136 
11137                 /* Setup bit 16 of flash address. */
11138                 bank_select = (uint16_t)RD16_IO_REG(ha, ctrl_status);
11139 
11140                 if (CFG_IST(ha, CFG_CTRL_6322)) {
11141                         bank_select = (uint16_t)(bank_select & ~0xf0);
11142                         bank_select = (uint16_t)(bank_select |
11143                             ((addr >> 12 & 0xf0) | ISP_FLASH_64K_BANK));
11144                         WRT16_IO_REG(ha, ctrl_status, bank_select);
11145                 } else {
11146                         if (addr & BIT_16 && !(bank_select &
11147                             ISP_FLASH_64K_BANK)) {
11148                                 bank_select = (uint16_t)(bank_select |
11149                                     ISP_FLASH_64K_BANK);
11150                                 WRT16_IO_REG(ha, ctrl_status, bank_select);
11151                         } else if (!(addr & BIT_16) && bank_select &
11152                             ISP_FLASH_64K_BANK) {
11153                                 bank_select = (uint16_t)(bank_select &
11154                                     ~ISP_FLASH_64K_BANK);
11155                                 WRT16_IO_REG(ha, ctrl_status, bank_select);
11156                         }
11157                 }
11158 
11159                 if (CFG_IST(ha, CFG_SBUS_CARD)) {
11160                         WRT16_IO_REG(ha, flash_address, (uint16_t)addr);
11161                         WRT16_IO_REG(ha, flash_data, (uint16_t)data);
11162                 } else {
11163                         WRT16_IOMAP_REG(ha, flash_address, addr);
11164                         WRT16_IOMAP_REG(ha, flash_data, data);
11165                 }
11166         }
11167 }
11168 
11169 /*
11170  * ql_read_flash_byte
11171  *      Reads byte from flash, but must read a word from chip.
11172  *
11173  * Input:
11174  *      ha = adapter state pointer.
11175  *      addr = flash byte address.
11176  *
11177  * Returns:
11178  *      byte from flash.
11179  *
11180  * Context:
11181  *      Kernel context.
11182  */
11183 uint8_t
11184 ql_read_flash_byte(ql_adapter_state_t *ha, uint32_t addr)
11185 {
11186         uint8_t data;
11187 
11188         if (CFG_IST(ha, CFG_SBUS_CARD)) {
11189                 ddi_put16(ha->sbus_fpga_dev_handle,
11190                     (uint16_t *)(ha->sbus_fpga_iobase + FPGA_EEPROM_LOADDR),
11191                     LSW(addr));
11192                 ddi_put16(ha->sbus_fpga_dev_handle,
11193                     (uint16_t *)(ha->sbus_fpga_iobase + FPGA_EEPROM_HIADDR),
11194                     MSW(addr));
11195                 data = (uint8_t)ddi_get16(ha->sbus_fpga_dev_handle,
11196                     (uint16_t *)(ha->sbus_fpga_iobase + FPGA_EEPROM_DATA));
11197         } else {
11198                 uint16_t        bank_select;
11199 
11200                 /* Setup bit 16 of flash address. */
11201                 bank_select = RD16_IO_REG(ha, ctrl_status);
11202                 if (CFG_IST(ha, CFG_CTRL_6322)) {
11203                         bank_select = (uint16_t)(bank_select & ~0xf0);
11204                         bank_select = (uint16_t)(bank_select |
11205                             ((addr >> 12 & 0xf0) | ISP_FLASH_64K_BANK));
11206                         WRT16_IO_REG(ha, ctrl_status, bank_select);
11207                 } else {
11208                         if (addr & BIT_16 &&
11209                             !(bank_select & ISP_FLASH_64K_BANK)) {
11210                                 bank_select = (uint16_t)(bank_select |
11211                                     ISP_FLASH_64K_BANK);
11212                                 WRT16_IO_REG(ha, ctrl_status, bank_select);
11213                         } else if (!(addr & BIT_16) &&
11214                             bank_select & ISP_FLASH_64K_BANK) {
11215                                 bank_select = (uint16_t)(bank_select &
11216                                     ~ISP_FLASH_64K_BANK);
11217                                 WRT16_IO_REG(ha, ctrl_status, bank_select);
11218                         }
11219                 }
11220 
11221                 if (CFG_IST(ha, CFG_SBUS_CARD)) {
11222                         WRT16_IO_REG(ha, flash_address, addr);
11223                         data = (uint8_t)RD16_IO_REG(ha, flash_data);
11224                 } else {
11225                         WRT16_IOMAP_REG(ha, flash_address, addr);
11226                         data = (uint8_t)RD16_IOMAP_REG(ha, flash_data);
11227                 }
11228         }
11229 
11230         return (data);
11231 }
11232 
11233 /*
11234  * ql_24xx_flash_id
11235  *      Get flash IDs.
11236  *
11237  * Input:
11238  *      ha:             adapter state pointer.
11239  *
11240  * Returns:
11241  *      ql local function return status code.
11242  *
11243  * Context:
11244  *      Kernel context.
11245  */
11246 int
11247 ql_24xx_flash_id(ql_adapter_state_t *vha)
11248 {
11249         int                     rval;
11250         uint32_t                fdata = 0;
11251         ql_adapter_state_t      *ha = vha->pha;
11252         ql_xioctl_t             *xp = ha->xioctl;
11253 
11254         QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
11255 
11256         rval = ql_24xx_read_flash(ha, FLASH_CONF_ADDR | 0x3AB, &fdata);
11257 
11258         if (rval != QL_SUCCESS || fdata == 0 || CFG_IST(ha, CFG_CTRL_2581)) {
11259                 fdata = 0;
11260                 rval = ql_24xx_read_flash(ha, FLASH_CONF_ADDR |
11261                     (CFG_IST(ha, CFG_CTRL_2422) ? 0x39F : 0x49F), &fdata);
11262         }
11263 
11264         if (rval != QL_SUCCESS) {
11265                 EL(ha, "24xx read_flash failed=%xh\n", rval);
11266         } else if (fdata != 0) {
11267                 xp->fdesc.flash_manuf = LSB(LSW(fdata));
11268                 xp->fdesc.flash_id = MSB(LSW(fdata));
11269                 xp->fdesc.flash_len = LSB(MSW(fdata));
11270         } else {
11271                 xp->fdesc.flash_manuf = ATMEL_FLASH;
11272                 xp->fdesc.flash_id = ATMEL_FLASHID_1024K;
11273                 xp->fdesc.flash_len = 0;
11274         }
11275 
11276         QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
11277 
11278         return (rval);
11279 }
11280 
11281 /*
11282  * ql_24xx_load_flash
11283  *      Loads flash.
11284  *
11285  * Input:
11286  *      ha = adapter state pointer.
11287  *      dp = data pointer.
11288  *      size = data length in bytes.
11289  *      faddr = 32bit word flash byte address.
11290  *
11291  * Returns:
11292  *      ql local function return status code.
11293  *
11294  * Context:
11295  *      Kernel context.
11296  */
11297 int
11298 ql_24xx_load_flash(ql_adapter_state_t *vha, uint8_t *dp, uint32_t size,
11299     uint32_t faddr)
11300 {
11301         int                     rval;
11302         uint32_t                cnt, rest_addr, fdata, wc;
11303         dma_mem_t               dmabuf = {0};
11304         ql_adapter_state_t      *ha = vha->pha;
11305         ql_xioctl_t             *xp = ha->xioctl;
11306 
11307         QL_PRINT_3(CE_CONT, "(%d): started, faddr=%xh, size=%xh\n",
11308             ha->instance, faddr, size);
11309 
11310         /* start address must be 32 bit word aligned */
11311         if ((faddr & 0x3) != 0) {
11312                 EL(ha, "incorrect buffer size alignment\n");
11313                 return (QL_FUNCTION_PARAMETER_ERROR);
11314         }
11315 
11316         /* Allocate DMA buffer */
11317         if (CFG_IST(ha, CFG_CTRL_2581)) {
11318                 if ((rval = ql_get_dma_mem(ha, &dmabuf, 0xffff,
11319                     LITTLE_ENDIAN_DMA, QL_DMA_DATA_ALIGN)) !=
11320                     QL_SUCCESS) {
11321                         EL(ha, "dma alloc failed, rval=%xh\n", rval);
11322                         return (rval);
11323                 }
11324         }
11325 
11326         GLOBAL_HW_LOCK();
11327 
11328         /* Enable flash write */
11329         if ((rval = ql_24xx_unprotect_flash(ha)) != QL_SUCCESS) {
11330                 GLOBAL_HW_UNLOCK();
11331                 EL(ha, "unprotect_flash failed, rval=%xh\n", rval);
11332                 ql_free_phys(ha, &dmabuf);
11333                 return (rval);
11334         }
11335 
11336         /* setup mask of address range within a sector */
11337         rest_addr = (xp->fdesc.block_size - 1) >> 2;
11338 
11339         faddr = faddr >> 2;       /* flash gets 32 bit words */
11340 
11341         /*
11342          * Write data to flash.
11343          */
11344         cnt = 0;
11345         size = (size + 3) >> 2;   /* Round up & convert to dwords */
11346 
11347         while (cnt < size) {
11348                 /* Beginning of a sector? */
11349                 if ((faddr & rest_addr) == 0) {
11350                         if (CFG_IST(ha, CFG_CTRL_8021)) {
11351                                 fdata = ha->flash_data_addr | faddr;
11352                                 rval = ql_8021_rom_erase(ha, fdata);
11353                                 if (rval != QL_SUCCESS) {
11354                                         EL(ha, "8021 erase sector status="
11355                                             "%xh, start=%xh, end=%xh"
11356                                             "\n", rval, fdata,
11357                                             fdata + rest_addr);
11358                                         break;
11359                                 }
11360                         } else if (CFG_IST(ha, CFG_CTRL_81XX)) {
11361                                 fdata = ha->flash_data_addr | faddr;
11362                                 rval = ql_flash_access(ha,
11363                                     FAC_ERASE_SECTOR, fdata, fdata +
11364                                     rest_addr, 0);
11365                                 if (rval != QL_SUCCESS) {
11366                                         EL(ha, "erase sector status="
11367                                             "%xh, start=%xh, end=%xh"
11368                                             "\n", rval, fdata,
11369                                             fdata + rest_addr);
11370                                         break;
11371                                 }
11372                         } else {
11373                                 fdata = (faddr & ~rest_addr) << 2;
11374                                 fdata = (fdata & 0xff00) |
11375                                     (fdata << 16 & 0xff0000) |
11376                                     (fdata >> 16 & 0xff);
11377 
11378                                 if (rest_addr == 0x1fff) {
11379                                         /* 32kb sector block erase */
11380                                         rval = ql_24xx_write_flash(ha,
11381                                             FLASH_CONF_ADDR | 0x0352,
11382                                             fdata);
11383                                 } else {
11384                                         /* 64kb sector block erase */
11385                                         rval = ql_24xx_write_flash(ha,
11386                                             FLASH_CONF_ADDR | 0x03d8,
11387                                             fdata);
11388                                 }
11389                                 if (rval != QL_SUCCESS) {
11390                                         EL(ha, "Unable to flash sector"
11391                                             ": address=%xh\n", faddr);
11392                                         break;
11393                                 }
11394                         }
11395                 }
11396 
11397                 /* Write data */
11398                 if (CFG_IST(ha, CFG_CTRL_2581) &&
11399                     ((faddr & 0x3f) == 0)) {
11400                         /*
11401                          * Limit write up to sector boundary.
11402                          */
11403                         wc = ((~faddr & (rest_addr>>1)) + 1);
11404 
11405                         if (size - cnt < wc) {
11406                                 wc = size - cnt;
11407                         }
11408 
11409                         ddi_rep_put8(dmabuf.acc_handle, (uint8_t *)dp,
11410                             (uint8_t *)dmabuf.bp, wc<<2,
11411                             DDI_DEV_AUTOINCR);
11412 
11413                         rval = ql_wrt_risc_ram(ha, ha->flash_data_addr |
11414                             faddr, dmabuf.cookie.dmac_laddress, wc);
11415                         if (rval != QL_SUCCESS) {
11416                                 EL(ha, "unable to dma to flash "
11417                                     "address=%xh\n", faddr << 2);
11418                                 break;
11419                         }
11420 
11421                         cnt += wc;
11422                         faddr += wc;
11423                         dp += wc << 2;
11424                 } else {
11425                         fdata = *dp++;
11426                         fdata |= *dp++ << 8;
11427                         fdata |= *dp++ << 16;
11428                         fdata |= *dp++ << 24;
11429                         rval = ql_24xx_write_flash(ha,
11430                             ha->flash_data_addr | faddr, fdata);
11431                         if (rval != QL_SUCCESS) {
11432                                 EL(ha, "Unable to program flash "
11433                                     "address=%xh data=%xh\n", faddr,
11434                                     *dp);
11435                                 break;
11436                         }
11437                         cnt++;
11438                         faddr++;
11439 
11440                         /* Allow other system activity. */
11441                         if (cnt % 0x1000 == 0) {
11442                                 ql_delay(ha, 10000);
11443                         }
11444                 }
11445         }
11446 
11447         ql_24xx_protect_flash(ha);
11448 
11449         ql_free_phys(ha, &dmabuf);
11450 
11451         GLOBAL_HW_UNLOCK();
11452 
11453         if (rval != QL_SUCCESS) {
11454                 EL(ha, "failed=%xh\n", rval);
11455         } else {
11456                 /*EMPTY*/
11457                 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
11458         }
11459         return (rval);
11460 }
11461 
11462 /*
11463  * ql_24xx_read_flash
11464  *      Reads a 32bit word from ISP24xx NVRAM/FLASH.
11465  *
11466  * Input:
11467  *      ha:     adapter state pointer.
11468  *      faddr:  NVRAM/FLASH address.
11469  *      bp:     data pointer.
11470  *
11471  * Returns:
11472  *      ql local function return status code.
11473  *
11474  * Context:
11475  *      Kernel context.
11476  */
11477 int
11478 ql_24xx_read_flash(ql_adapter_state_t *vha, uint32_t faddr, uint32_t *bp)
11479 {
11480         uint32_t                timer;
11481         int                     rval = QL_SUCCESS;
11482         ql_adapter_state_t      *ha = vha->pha;
11483 
11484         if (CFG_IST(ha, CFG_CTRL_8021)) {
11485                 if ((rval = ql_8021_rom_read(ha, faddr, bp)) != QL_SUCCESS) {
11486                         EL(ha, "8021 access error\n");
11487                 }
11488                 return (rval);
11489         }
11490 
11491         /* Clear access error flag */
11492         WRT32_IO_REG(ha, ctrl_status,
11493             RD32_IO_REG(ha, ctrl_status) | FLASH_NVRAM_ACCESS_ERROR);
11494 
11495         WRT32_IO_REG(ha, flash_address, faddr & ~FLASH_DATA_FLAG);
11496 
11497         /* Wait for READ cycle to complete. */
11498         for (timer = 300000; timer; timer--) {
11499                 if (RD32_IO_REG(ha, flash_address) & FLASH_DATA_FLAG) {
11500                         break;
11501                 }
11502                 drv_usecwait(10);
11503         }
11504 
11505         if (timer == 0) {
11506                 EL(ha, "failed, timeout\n");
11507                 rval = QL_FUNCTION_TIMEOUT;
11508         } else if (RD32_IO_REG(ha, ctrl_status) & FLASH_NVRAM_ACCESS_ERROR) {
11509                 EL(ha, "failed, access error\n");
11510                 rval = QL_FUNCTION_FAILED;
11511         }
11512 
11513         *bp = RD32_IO_REG(ha, flash_data);
11514 
11515         return (rval);
11516 }
11517 
11518 /*
11519  * ql_24xx_write_flash
11520  *      Writes a 32bit word to ISP24xx NVRAM/FLASH.
11521  *
11522  * Input:
11523  *      ha:     adapter state pointer.
11524  *      addr:   NVRAM/FLASH address.
11525  *      value:  data.
11526  *
11527  * Returns:
11528  *      ql local function return status code.
11529  *
11530  * Context:
11531  *      Kernel context.
11532  */
11533 int
11534 ql_24xx_write_flash(ql_adapter_state_t *vha, uint32_t addr, uint32_t data)
11535 {
11536         uint32_t                timer, fdata;
11537         int                     rval = QL_SUCCESS;
11538         ql_adapter_state_t      *ha = vha->pha;
11539 
11540         if (CFG_IST(ha, CFG_CTRL_8021)) {
11541                 if ((rval = ql_8021_rom_write(ha, addr, data)) != QL_SUCCESS) {
11542                         EL(ha, "8021 access error\n");
11543                 }
11544                 return (rval);
11545         }
11546         /* Clear access error flag */
11547         WRT32_IO_REG(ha, ctrl_status,
11548             RD32_IO_REG(ha, ctrl_status) | FLASH_NVRAM_ACCESS_ERROR);
11549 
11550         WRT32_IO_REG(ha, flash_data, data);
11551         RD32_IO_REG(ha, flash_data);            /* PCI Posting. */
11552         WRT32_IO_REG(ha, flash_address, addr | FLASH_DATA_FLAG);
11553 
11554         /* Wait for Write cycle to complete. */
11555         for (timer = 3000000; timer; timer--) {
11556                 if ((RD32_IO_REG(ha, flash_address) & FLASH_DATA_FLAG) == 0) {
11557                         /* Check flash write in progress. */
11558                         if ((addr & FLASH_ADDR_MASK) == FLASH_CONF_ADDR) {
11559                                 (void) ql_24xx_read_flash(ha,
11560                                     FLASH_CONF_ADDR | 0x005, &fdata);
11561                                 if (!(fdata & BIT_0)) {
11562                                         break;
11563                                 }
11564                         } else {
11565                                 break;
11566                         }
11567                 }
11568                 drv_usecwait(10);
11569         }
11570         if (timer == 0) {
11571                 EL(ha, "failed, timeout\n");
11572                 rval = QL_FUNCTION_TIMEOUT;
11573         } else if (RD32_IO_REG(ha, ctrl_status) & FLASH_NVRAM_ACCESS_ERROR) {
11574                 EL(ha, "access error\n");
11575                 rval = QL_FUNCTION_FAILED;
11576         }
11577 
11578         return (rval);
11579 }
11580 /*
11581  * ql_24xx_unprotect_flash
11582  *      Enable writes
11583  *
11584  * Input:
11585  *      ha:     adapter state pointer.
11586  *
11587  * Returns:
11588  *      ql local function return status code.
11589  *
11590  * Context:
11591  *      Kernel context.
11592  */
11593 int
11594 ql_24xx_unprotect_flash(ql_adapter_state_t *vha)
11595 {
11596         int                     rval;
11597         uint32_t                fdata;
11598         ql_adapter_state_t      *ha = vha->pha;
11599         ql_xioctl_t             *xp = ha->xioctl;
11600 
11601         QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
11602 
11603         if (CFG_IST(ha, CFG_CTRL_8021)) {
11604                 (void) ql_8021_rom_wrsr(ha, xp->fdesc.write_enable_bits);
11605                 rval = ql_8021_rom_wrsr(ha, xp->fdesc.write_enable_bits);
11606                 if (rval != QL_SUCCESS) {
11607                         EL(ha, "8021 access error\n");
11608                 }
11609                 return (rval);
11610         }
11611         if (CFG_IST(ha, CFG_CTRL_81XX)) {
11612                 if (ha->task_daemon_flags & FIRMWARE_UP) {
11613                         if ((rval = ql_flash_access(ha, FAC_WRT_ENABLE, 0, 0,
11614                             0)) != QL_SUCCESS) {
11615                                 EL(ha, "status=%xh\n", rval);
11616                         }
11617                         QL_PRINT_3(CE_CONT, "(%d): 8100 done\n",
11618                             ha->instance);
11619                         return (rval);
11620                 }
11621         } else {
11622                 /* Enable flash write. */
11623                 WRT32_IO_REG(ha, ctrl_status,
11624                     RD32_IO_REG(ha, ctrl_status) | ISP_FLASH_ENABLE);
11625                 RD32_IO_REG(ha, ctrl_status);   /* PCI Posting. */
11626         }
11627 
11628         /*
11629          * Remove block write protection (SST and ST) and
11630          * Sector/Block Protection Register Lock (SST, ST, ATMEL).
11631          * Unprotect sectors.
11632          */
11633         (void) ql_24xx_write_flash(ha, FLASH_CONF_ADDR | 0x100 |
11634             xp->fdesc.write_statusreg_cmd, xp->fdesc.write_enable_bits);
11635 
11636         if (xp->fdesc.unprotect_sector_cmd != 0) {
11637                 for (fdata = 0; fdata < 0x10; fdata++) {
11638                         (void) ql_24xx_write_flash(ha, FLASH_CONF_ADDR |
11639                             0x300 | xp->fdesc.unprotect_sector_cmd, fdata);
11640                 }
11641 
11642                 (void) ql_24xx_write_flash(ha, FLASH_CONF_ADDR | 0x300 |
11643                     xp->fdesc.unprotect_sector_cmd, 0x00400f);
11644                 (void) ql_24xx_write_flash(ha, FLASH_CONF_ADDR | 0x300 |
11645                     xp->fdesc.unprotect_sector_cmd, 0x00600f);
11646                 (void) ql_24xx_write_flash(ha, FLASH_CONF_ADDR | 0x300 |
11647                     xp->fdesc.unprotect_sector_cmd, 0x00800f);
11648         }
11649 
11650         QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
11651 
11652         return (QL_SUCCESS);
11653 }
11654 
11655 /*
11656  * ql_24xx_protect_flash
11657  *      Disable writes
11658  *
11659  * Input:
11660  *      ha:     adapter state pointer.
11661  *
11662  * Context:
11663  *      Kernel context.
11664  */
11665 void
11666 ql_24xx_protect_flash(ql_adapter_state_t *vha)
11667 {
11668         int                     rval;
11669         uint32_t                fdata;
11670         ql_adapter_state_t      *ha = vha->pha;
11671         ql_xioctl_t             *xp = ha->xioctl;
11672 
11673         QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
11674 
11675         if (CFG_IST(ha, CFG_CTRL_8021)) {
11676                 (void) ql_8021_rom_wrsr(ha, xp->fdesc.write_enable_bits);
11677                 rval = ql_8021_rom_wrsr(ha, xp->fdesc.write_disable_bits);
11678                 if (rval != QL_SUCCESS) {
11679                         EL(ha, "8021 access error\n");
11680                 }
11681                 return;
11682         }
11683         if (CFG_IST(ha, CFG_CTRL_81XX)) {
11684                 if (ha->task_daemon_flags & FIRMWARE_UP) {
11685                         if ((rval = ql_flash_access(ha, FAC_WRT_PROTECT, 0, 0,
11686                             0)) != QL_SUCCESS) {
11687                                 EL(ha, "status=%xh\n", rval);
11688                         }
11689                         QL_PRINT_3(CE_CONT, "(%d): 8100 done\n",
11690                             ha->instance);
11691                         return;
11692                 }
11693         } else {
11694                 /* Enable flash write. */
11695                 WRT32_IO_REG(ha, ctrl_status,
11696                     RD32_IO_REG(ha, ctrl_status) | ISP_FLASH_ENABLE);
11697                 RD32_IO_REG(ha, ctrl_status);   /* PCI Posting. */
11698         }
11699 
11700         /*
11701          * Protect sectors.
11702          * Set block write protection (SST and ST) and
11703          * Sector/Block Protection Register Lock (SST, ST, ATMEL).
11704          */
11705         if (xp->fdesc.protect_sector_cmd != 0) {
11706                 for (fdata = 0; fdata < 0x10; fdata++) {
11707                         (void) ql_24xx_write_flash(ha, FLASH_CONF_ADDR |
11708                             0x330 | xp->fdesc.protect_sector_cmd, fdata);
11709                 }
11710                 (void) ql_24xx_write_flash(ha, FLASH_CONF_ADDR | 0x330 |
11711                     xp->fdesc.protect_sector_cmd, 0x00400f);
11712                 (void) ql_24xx_write_flash(ha, FLASH_CONF_ADDR | 0x330 |
11713                     xp->fdesc.protect_sector_cmd, 0x00600f);
11714                 (void) ql_24xx_write_flash(ha, FLASH_CONF_ADDR | 0x330 |
11715                     xp->fdesc.protect_sector_cmd, 0x00800f);
11716 
11717                 /* TODO: ??? */
11718                 (void) ql_24xx_write_flash(ha,
11719                     FLASH_CONF_ADDR | 0x101, 0x80);
11720         } else {
11721                 (void) ql_24xx_write_flash(ha,
11722                     FLASH_CONF_ADDR | 0x101, 0x9c);
11723         }
11724 
11725         /* Disable flash write. */
11726         if (!(CFG_IST(ha, CFG_CTRL_81XX))) {
11727                 WRT32_IO_REG(ha, ctrl_status,
11728                     RD32_IO_REG(ha, ctrl_status) & ~ISP_FLASH_ENABLE);
11729                 RD32_IO_REG(ha, ctrl_status);   /* PCI Posting. */
11730         }
11731 
11732         QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
11733 }
11734 
11735 /*
11736  * ql_dump_firmware
11737  *      Save RISC code state information.
11738  *
11739  * Input:
11740  *      ha = adapter state pointer.
11741  *
11742  * Returns:
11743  *      QL local function return status code.
11744  *
11745  * Context:
11746  *      Kernel context.
11747  */
11748 static int
11749 ql_dump_firmware(ql_adapter_state_t *vha)
11750 {
11751         int                     rval;
11752         clock_t                 timer = drv_usectohz(30000000);
11753         ql_adapter_state_t      *ha = vha->pha;
11754 
11755         QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
11756 
11757         QL_DUMP_LOCK(ha);
11758 
11759         if (ha->ql_dump_state & QL_DUMPING ||
11760             (ha->ql_dump_state & QL_DUMP_VALID &&
11761             !(ha->ql_dump_state & QL_DUMP_UPLOADED))) {
11762                 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
11763                 QL_DUMP_UNLOCK(ha);
11764                 return (QL_SUCCESS);
11765         }
11766 
11767         QL_DUMP_UNLOCK(ha);
11768 
11769         ql_awaken_task_daemon(ha, NULL, DRIVER_STALL, 0);
11770 
11771         /*
11772          * Wait for all outstanding commands to complete
11773          */
11774         (void) ql_wait_outstanding(ha);
11775 
11776         /* Dump firmware. */
11777         rval = ql_binary_fw_dump(ha, TRUE);
11778 
11779         /* Do abort to force restart. */
11780         ql_awaken_task_daemon(ha, NULL, ISP_ABORT_NEEDED, DRIVER_STALL);
11781         EL(ha, "restarting, isp_abort_needed\n");
11782 
11783         /* Acquire task daemon lock. */
11784         TASK_DAEMON_LOCK(ha);
11785 
11786         /* Wait for suspension to end. */
11787         while (ha->task_daemon_flags & QL_SUSPENDED) {
11788                 ha->task_daemon_flags |= SUSPENDED_WAKEUP_FLG;
11789 
11790                 /* 30 seconds from now */
11791                 if (cv_reltimedwait(&ha->cv_dr_suspended,
11792                     &ha->task_daemon_mutex, timer, TR_CLOCK_TICK) == -1) {
11793                         /*
11794                          * The timeout time 'timer' was
11795                          * reached without the condition
11796                          * being signaled.
11797                          */
11798                         break;
11799                 }
11800         }
11801 
11802         /* Release task daemon lock. */
11803         TASK_DAEMON_UNLOCK(ha);
11804 
11805         if (rval == QL_SUCCESS || rval == QL_DATA_EXISTS) {
11806                 /*EMPTY*/
11807                 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
11808         } else {
11809                 EL(ha, "failed, rval = %xh\n", rval);
11810         }
11811         return (rval);
11812 }
11813 
11814 /*
11815  * ql_binary_fw_dump
11816  *      Dumps binary data from firmware.
11817  *
11818  * Input:
11819  *      ha = adapter state pointer.
11820  *      lock_needed = mailbox lock needed.
11821  *
11822  * Returns:
11823  *      ql local function return status code.
11824  *
11825  * Context:
11826  *      Interrupt or Kernel context, no mailbox commands allowed.
11827  */
11828 int
11829 ql_binary_fw_dump(ql_adapter_state_t *vha, int lock_needed)
11830 {
11831         clock_t                 timer;
11832         mbx_cmd_t               mc;
11833         mbx_cmd_t               *mcp = &mc;
11834         int                     rval = QL_SUCCESS;
11835         ql_adapter_state_t      *ha = vha->pha;
11836 
11837         QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
11838 
11839         if (CFG_IST(ha, CFG_CTRL_8021)) {
11840                 EL(ha, "8021 not supported\n");
11841                 return (QL_NOT_SUPPORTED);
11842         }
11843 
11844         QL_DUMP_LOCK(ha);
11845 
11846         if (ha->ql_dump_state & QL_DUMPING ||
11847             (ha->ql_dump_state & QL_DUMP_VALID &&
11848             !(ha->ql_dump_state & QL_DUMP_UPLOADED))) {
11849                 EL(ha, "dump already done, qds=%x\n", ha->ql_dump_state);
11850                 QL_DUMP_UNLOCK(ha);
11851                 return (QL_DATA_EXISTS);
11852         }
11853 
11854         ha->ql_dump_state &= ~(QL_DUMP_VALID | QL_DUMP_UPLOADED);
11855         ha->ql_dump_state |= QL_DUMPING;
11856 
11857         QL_DUMP_UNLOCK(ha);
11858 
11859         if (CFG_IST(ha, CFG_ENABLE_FWEXTTRACE)) {
11860 
11861                 /* Insert Time Stamp */
11862                 rval = ql_fw_etrace(ha, &ha->fwexttracebuf,
11863                     FTO_INSERT_TIME_STAMP);
11864                 if (rval != QL_SUCCESS) {
11865                         EL(ha, "f/w extended trace insert"
11866                             "time stamp failed: %xh\n", rval);
11867                 }
11868         }
11869 
11870         if (lock_needed == TRUE) {
11871                 /* Acquire mailbox register lock. */
11872                 MBX_REGISTER_LOCK(ha);
11873                 timer = (ha->mcp->timeout + 2) * drv_usectohz(1000000);
11874 
11875                 /* Check for mailbox available, if not wait for signal. */
11876                 while (ha->mailbox_flags & MBX_BUSY_FLG) {
11877                         ha->mailbox_flags = (uint8_t)
11878                             (ha->mailbox_flags | MBX_WANT_FLG);
11879 
11880                         /* 30 seconds from now */
11881                         if (cv_reltimedwait(&ha->cv_mbx_wait, &ha->mbx_mutex,
11882                             timer, TR_CLOCK_TICK) == -1) {
11883                                 /*
11884                                  * The timeout time 'timer' was
11885                                  * reached without the condition
11886                                  * being signaled.
11887                                  */
11888 
11889                                 /* Release mailbox register lock. */
11890                                 MBX_REGISTER_UNLOCK(ha);
11891 
11892                                 EL(ha, "failed, rval = %xh\n",
11893                                     QL_FUNCTION_TIMEOUT);
11894                                 return (QL_FUNCTION_TIMEOUT);
11895                         }
11896                 }
11897 
11898                 /* Set busy flag. */
11899                 ha->mailbox_flags = (uint8_t)
11900                     (ha->mailbox_flags | MBX_BUSY_FLG);
11901                 mcp->timeout = 120;
11902                 ha->mcp = mcp;
11903 
11904                 /* Release mailbox register lock. */
11905                 MBX_REGISTER_UNLOCK(ha);
11906         }
11907 
11908         /* Free previous dump buffer. */
11909         if (ha->ql_dump_ptr != NULL) {
11910                 kmem_free(ha->ql_dump_ptr, ha->ql_dump_size);
11911                 ha->ql_dump_ptr = NULL;
11912         }
11913 
11914         if (CFG_IST(ha, CFG_CTRL_2422)) {
11915                 ha->ql_dump_size = (uint32_t)(sizeof (ql_24xx_fw_dump_t) +
11916                     ha->fw_ext_memory_size);
11917         } else if (CFG_IST(ha, CFG_CTRL_25XX)) {
11918                 ha->ql_dump_size = (uint32_t)(sizeof (ql_25xx_fw_dump_t) +
11919                     ha->fw_ext_memory_size);
11920         } else if (CFG_IST(ha, CFG_CTRL_81XX)) {
11921                 ha->ql_dump_size = (uint32_t)(sizeof (ql_81xx_fw_dump_t) +
11922                     ha->fw_ext_memory_size);
11923         } else {
11924                 ha->ql_dump_size = sizeof (ql_fw_dump_t);
11925         }
11926 
11927         if ((ha->ql_dump_ptr = kmem_zalloc(ha->ql_dump_size, KM_NOSLEEP)) ==
11928             NULL) {
11929                 rval = QL_MEMORY_ALLOC_FAILED;
11930         } else {
11931                 if (CFG_IST(ha, (CFG_CTRL_2300 | CFG_CTRL_6322))) {
11932                         rval = ql_2300_binary_fw_dump(ha, ha->ql_dump_ptr);
11933                 } else if (CFG_IST(ha, CFG_CTRL_81XX)) {
11934                         rval = ql_81xx_binary_fw_dump(ha, ha->ql_dump_ptr);
11935                 } else if (CFG_IST(ha, CFG_CTRL_25XX)) {
11936                         rval = ql_25xx_binary_fw_dump(ha, ha->ql_dump_ptr);
11937                 } else if (CFG_IST(ha, CFG_CTRL_2422)) {
11938                         rval = ql_24xx_binary_fw_dump(ha, ha->ql_dump_ptr);
11939                 } else {
11940                         rval = ql_2200_binary_fw_dump(ha, ha->ql_dump_ptr);
11941                 }
11942         }
11943 
11944         /* Reset ISP chip. */
11945         ql_reset_chip(ha);
11946 
11947         QL_DUMP_LOCK(ha);
11948 
11949         if (rval != QL_SUCCESS) {
11950                 if (ha->ql_dump_ptr != NULL) {
11951                         kmem_free(ha->ql_dump_ptr, ha->ql_dump_size);
11952                         ha->ql_dump_ptr = NULL;
11953                 }
11954                 ha->ql_dump_state &= ~(QL_DUMPING | QL_DUMP_VALID |
11955                     QL_DUMP_UPLOADED);
11956                 EL(ha, "failed, rval = %xh\n", rval);
11957         } else {
11958                 ha->ql_dump_state &= ~(QL_DUMPING | QL_DUMP_UPLOADED);
11959                 ha->ql_dump_state |= QL_DUMP_VALID;
11960                 EL(ha, "done\n");
11961         }
11962 
11963         QL_DUMP_UNLOCK(ha);
11964 
11965         return (rval);
11966 }
11967 
11968 /*
11969  * ql_ascii_fw_dump
11970  *      Converts firmware binary dump to ascii.
11971  *
11972  * Input:
11973  *      ha = adapter state pointer.
11974  *      bptr = buffer pointer.
11975  *
11976  * Returns:
11977  *      Amount of data buffer used.
11978  *
11979  * Context:
11980  *      Kernel context.
11981  */
11982 size_t
11983 ql_ascii_fw_dump(ql_adapter_state_t *vha, caddr_t bufp)
11984 {
11985         uint32_t                cnt;
11986         caddr_t                 bp;
11987         int                     mbox_cnt;
11988         ql_adapter_state_t      *ha = vha->pha;
11989         ql_fw_dump_t            *fw = ha->ql_dump_ptr;
11990 
11991         if (CFG_IST(ha, CFG_CTRL_2422)) {
11992                 return (ql_24xx_ascii_fw_dump(ha, bufp));
11993         } else if (CFG_IST(ha, CFG_CTRL_2581)) {
11994                 return (ql_2581_ascii_fw_dump(ha, bufp));
11995         }
11996 
11997         QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
11998 
11999         if (CFG_IST(ha, CFG_CTRL_2300)) {
12000                 (void) sprintf(bufp, "\nISP 2300IP ");
12001         } else if (CFG_IST(ha, CFG_CTRL_6322)) {
12002                 (void) sprintf(bufp, "\nISP 6322FLX ");
12003         } else {
12004                 (void) sprintf(bufp, "\nISP 2200IP ");
12005         }
12006 
12007         bp = bufp + strlen(bufp);
12008         (void) sprintf(bp, "Firmware Version %d.%d.%d\n",
12009             ha->fw_major_version, ha->fw_minor_version,
12010             ha->fw_subminor_version);
12011 
12012         (void) strcat(bufp, "\nPBIU Registers:");
12013         bp = bufp + strlen(bufp);
12014         for (cnt = 0; cnt < sizeof (fw->pbiu_reg) / 2; cnt++) {
12015                 if (cnt % 8 == 0) {
12016                         *bp++ = '\n';
12017                 }
12018                 (void) sprintf(bp, "%04x  ", fw->pbiu_reg[cnt]);
12019                 bp = bp + 6;
12020         }
12021 
12022         if (CFG_IST(ha, (CFG_CTRL_2300 | CFG_CTRL_6322))) {
12023                 (void) strcat(bufp, "\n\nReqQ-RspQ-Risc2Host Status "
12024                     "registers:");
12025                 bp = bufp + strlen(bufp);
12026                 for (cnt = 0; cnt < sizeof (fw->risc_host_reg) / 2; cnt++) {
12027                         if (cnt % 8 == 0) {
12028                                 *bp++ = '\n';
12029                         }
12030                         (void) sprintf(bp, "%04x  ", fw->risc_host_reg[cnt]);
12031                         bp = bp + 6;
12032                 }
12033         }
12034 
12035         (void) strcat(bp, "\n\nMailbox Registers:");
12036         bp = bufp + strlen(bufp);
12037         mbox_cnt = (CFG_IST(ha, (CFG_CTRL_2300 | CFG_CTRL_6322))) ? 16 : 8;
12038         for (cnt = 0; cnt < mbox_cnt; cnt++) {
12039                 if (cnt % 8 == 0) {
12040                         *bp++ = '\n';
12041                 }
12042                 (void) sprintf(bp, "%04x  ", fw->mailbox_reg[cnt]);
12043                 bp = bp + 6;
12044         }
12045 
12046         if (CFG_IST(ha, (CFG_CTRL_2300 | CFG_CTRL_6322))) {
12047                 (void) strcat(bp, "\n\nAuto Request Response DMA Registers:");
12048                 bp = bufp + strlen(bufp);
12049                 for (cnt = 0; cnt < sizeof (fw->resp_dma_reg) / 2; cnt++) {
12050                         if (cnt % 8 == 0) {
12051                                 *bp++ = '\n';
12052                         }
12053                         (void) sprintf(bp, "%04x  ", fw->resp_dma_reg[cnt]);
12054                         bp = bp + 6;
12055                 }
12056         }
12057 
12058         (void) strcat(bp, "\n\nDMA Registers:");
12059         bp = bufp + strlen(bufp);
12060         for (cnt = 0; cnt < sizeof (fw->dma_reg) / 2; cnt++) {
12061                 if (cnt % 8 == 0) {
12062                         *bp++ = '\n';
12063                 }
12064                 (void) sprintf(bp, "%04x  ", fw->dma_reg[cnt]);
12065                 bp = bp + 6;
12066         }
12067 
12068         (void) strcat(bp, "\n\nRISC Hardware Registers:");
12069         bp = bufp + strlen(bufp);
12070         for (cnt = 0; cnt < sizeof (fw->risc_hdw_reg) / 2; cnt++) {
12071                 if (cnt % 8 == 0) {
12072                         *bp++ = '\n';
12073                 }
12074                 (void) sprintf(bp, "%04x  ", fw->risc_hdw_reg[cnt]);
12075                 bp = bp + 6;
12076         }
12077 
12078         (void) strcat(bp, "\n\nRISC GP0 Registers:");
12079         bp = bufp + strlen(bufp);
12080         for (cnt = 0; cnt < sizeof (fw->risc_gp0_reg) / 2; cnt++) {
12081                 if (cnt % 8 == 0) {
12082                         *bp++ = '\n';
12083                 }
12084                 (void) sprintf(bp, "%04x  ", fw->risc_gp0_reg[cnt]);
12085                 bp = bp + 6;
12086         }
12087 
12088         (void) strcat(bp, "\n\nRISC GP1 Registers:");
12089         bp = bufp + strlen(bufp);
12090         for (cnt = 0; cnt < sizeof (fw->risc_gp1_reg) / 2; cnt++) {
12091                 if (cnt % 8 == 0) {
12092                         *bp++ = '\n';
12093                 }
12094                 (void) sprintf(bp, "%04x  ", fw->risc_gp1_reg[cnt]);
12095                 bp = bp + 6;
12096         }
12097 
12098         (void) strcat(bp, "\n\nRISC GP2 Registers:");
12099         bp = bufp + strlen(bufp);
12100         for (cnt = 0; cnt < sizeof (fw->risc_gp2_reg) / 2; cnt++) {
12101                 if (cnt % 8 == 0) {
12102                         *bp++ = '\n';
12103                 }
12104                 (void) sprintf(bp, "%04x  ", fw->risc_gp2_reg[cnt]);
12105                 bp = bp + 6;
12106         }
12107 
12108         (void) strcat(bp, "\n\nRISC GP3 Registers:");
12109         bp = bufp + strlen(bufp);
12110         for (cnt = 0; cnt < sizeof (fw->risc_gp3_reg) / 2; cnt++) {
12111                 if (cnt % 8 == 0) {
12112                         *bp++ = '\n';
12113                 }
12114                 (void) sprintf(bp, "%04x  ", fw->risc_gp3_reg[cnt]);
12115                 bp = bp + 6;
12116         }
12117 
12118         (void) strcat(bp, "\n\nRISC GP4 Registers:");
12119         bp = bufp + strlen(bufp);
12120         for (cnt = 0; cnt < sizeof (fw->risc_gp4_reg) / 2; cnt++) {
12121                 if (cnt % 8 == 0) {
12122                         *bp++ = '\n';
12123                 }
12124                 (void) sprintf(bp, "%04x  ", fw->risc_gp4_reg[cnt]);
12125                 bp = bp + 6;
12126         }
12127 
12128         (void) strcat(bp, "\n\nRISC GP5 Registers:");
12129         bp = bufp + strlen(bufp);
12130         for (cnt = 0; cnt < sizeof (fw->risc_gp5_reg) / 2; cnt++) {
12131                 if (cnt % 8 == 0) {
12132                         *bp++ = '\n';
12133                 }
12134                 (void) sprintf(bp, "%04x  ", fw->risc_gp5_reg[cnt]);
12135                 bp = bp + 6;
12136         }
12137 
12138         (void) strcat(bp, "\n\nRISC GP6 Registers:");
12139         bp = bufp + strlen(bufp);
12140         for (cnt = 0; cnt < sizeof (fw->risc_gp6_reg) / 2; cnt++) {
12141                 if (cnt % 8 == 0) {
12142                         *bp++ = '\n';
12143                 }
12144                 (void) sprintf(bp, "%04x  ", fw->risc_gp6_reg[cnt]);
12145                 bp = bp + 6;
12146         }
12147 
12148         (void) strcat(bp, "\n\nRISC GP7 Registers:");
12149         bp = bufp + strlen(bufp);
12150         for (cnt = 0; cnt < sizeof (fw->risc_gp7_reg) / 2; cnt++) {
12151                 if (cnt % 8 == 0) {
12152                         *bp++ = '\n';
12153                 }
12154                 (void) sprintf(bp, "%04x  ", fw->risc_gp7_reg[cnt]);
12155                 bp = bp + 6;
12156         }
12157 
12158         (void) strcat(bp, "\n\nFrame Buffer Hardware Registers:");
12159         bp = bufp + strlen(bufp);
12160         for (cnt = 0; cnt < sizeof (fw->frame_buf_hdw_reg) / 2; cnt++) {
12161                 if ((cnt == 16) && ((CFG_IST(ha, (CFG_CTRL_2300 |
12162                     CFG_CTRL_6322)) == 0))) {
12163                         break;
12164                 }
12165                 if (cnt % 8 == 0) {
12166                         *bp++ = '\n';
12167                 }
12168                 (void) sprintf(bp, "%04x  ", fw->frame_buf_hdw_reg[cnt]);
12169                 bp = bp + 6;
12170         }
12171 
12172         (void) strcat(bp, "\n\nFPM B0 Registers:");
12173         bp = bufp + strlen(bufp);
12174         for (cnt = 0; cnt < sizeof (fw->fpm_b0_reg) / 2; cnt++) {
12175                 if (cnt % 8 == 0) {
12176                         *bp++ = '\n';
12177                 }
12178                 (void) sprintf(bp, "%04x  ", fw->fpm_b0_reg[cnt]);
12179                 bp = bp + 6;
12180         }
12181 
12182         (void) strcat(bp, "\n\nFPM B1 Registers:");
12183         bp = bufp + strlen(bufp);
12184         for (cnt = 0; cnt < sizeof (fw->fpm_b1_reg) / 2; cnt++) {
12185                 if (cnt % 8 == 0) {
12186                         *bp++ = '\n';
12187                 }
12188                 (void) sprintf(bp, "%04x  ", fw->fpm_b1_reg[cnt]);
12189                 bp = bp + 6;
12190         }
12191 
12192         if (CFG_IST(ha, (CFG_CTRL_2300 | CFG_CTRL_6322))) {
12193                 (void) strcat(bp, "\n\nCode RAM Dump:");
12194                 bp = bufp + strlen(bufp);
12195                 for (cnt = 0; cnt < sizeof (fw->risc_ram) / 2; cnt++) {
12196                         if (cnt % 8 == 0) {
12197                                 (void) sprintf(bp, "\n%05x: ", cnt + 0x0800);
12198                                 bp = bp + 8;
12199                         }
12200                         (void) sprintf(bp, "%04x  ", fw->risc_ram[cnt]);
12201                         bp = bp + 6;
12202                 }
12203 
12204                 (void) strcat(bp, "\n\nStack RAM Dump:");
12205                 bp = bufp + strlen(bufp);
12206                 for (cnt = 0; cnt < sizeof (fw->stack_ram) / 2; cnt++) {
12207                         if (cnt % 8 == 0) {
12208                                 (void) sprintf(bp, "\n%05x: ", cnt + 0x010000);
12209                                 bp = bp + 8;
12210                         }
12211                         (void) sprintf(bp, "%04x  ", fw->stack_ram[cnt]);
12212                         bp = bp + 6;
12213                 }
12214 
12215                 (void) strcat(bp, "\n\nData RAM Dump:");
12216                 bp = bufp + strlen(bufp);
12217                 for (cnt = 0; cnt < sizeof (fw->data_ram) / 2; cnt++) {
12218                         if (cnt % 8 == 0) {
12219                                 (void) sprintf(bp, "\n%05x: ", cnt + 0x010800);
12220                                 bp = bp + 8;
12221                         }
12222                         (void) sprintf(bp, "%04x  ", fw->data_ram[cnt]);
12223                         bp = bp + 6;
12224                 }
12225         } else {
12226                 (void) strcat(bp, "\n\nRISC SRAM:");
12227                 bp = bufp + strlen(bufp);
12228                 for (cnt = 0; cnt < 0xf000; cnt++) {
12229                         if (cnt % 8 == 0) {
12230                                 (void) sprintf(bp, "\n%04x: ", cnt + 0x1000);
12231                                 bp = bp + 7;
12232                         }
12233                         (void) sprintf(bp, "%04x  ", fw->risc_ram[cnt]);
12234                         bp = bp + 6;
12235                 }
12236         }
12237 
12238         (void) strcat(bp, "\n\n[<==END] ISP Debug Dump.");
12239         bp += strlen(bp);
12240 
12241         (void) sprintf(bp, "\n\nRequest Queue");
12242         bp += strlen(bp);
12243         for (cnt = 0; cnt < REQUEST_QUEUE_SIZE / 4; cnt++) {
12244                 if (cnt % 8 == 0) {
12245                         (void) sprintf(bp, "\n%08x: ", cnt);
12246                         bp += strlen(bp);
12247                 }
12248                 (void) sprintf(bp, "%08x ", fw->req_q[cnt]);
12249                 bp += strlen(bp);
12250         }
12251 
12252         (void) sprintf(bp, "\n\nResponse Queue");
12253         bp += strlen(bp);
12254         for (cnt = 0; cnt < RESPONSE_QUEUE_SIZE / 4; cnt++) {
12255                 if (cnt % 8 == 0) {
12256                         (void) sprintf(bp, "\n%08x: ", cnt);
12257                         bp += strlen(bp);
12258                 }
12259                 (void) sprintf(bp, "%08x ", fw->rsp_q[cnt]);
12260                 bp += strlen(bp);
12261         }
12262 
12263         (void) sprintf(bp, "\n");
12264 
12265         QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
12266 
12267         return (strlen(bufp));
12268 }
12269 
12270 /*
12271  * ql_24xx_ascii_fw_dump
12272  *      Converts ISP24xx firmware binary dump to ascii.
12273  *
12274  * Input:
12275  *      ha = adapter state pointer.
12276  *      bptr = buffer pointer.
12277  *
12278  * Returns:
12279  *      Amount of data buffer used.
12280  *
12281  * Context:
12282  *      Kernel context.
12283  */
12284 static size_t
12285 ql_24xx_ascii_fw_dump(ql_adapter_state_t *ha, caddr_t bufp)
12286 {
12287         uint32_t                cnt;
12288         caddr_t                 bp = bufp;
12289         ql_24xx_fw_dump_t       *fw = ha->ql_dump_ptr;
12290 
12291         QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
12292 
12293         (void) sprintf(bp, "ISP FW Version %d.%02d.%02d Attributes %X\n",
12294             ha->fw_major_version, ha->fw_minor_version,
12295             ha->fw_subminor_version, ha->fw_attributes);
12296         bp += strlen(bp);
12297 
12298         (void) sprintf(bp, "\nHCCR Register\n%08x\n", fw->hccr);
12299 
12300         (void) strcat(bp, "\nHost Interface Registers");
12301         bp += strlen(bp);
12302         for (cnt = 0; cnt < sizeof (fw->host_reg) / 4; cnt++) {
12303                 if (cnt % 8 == 0) {
12304                         (void) sprintf(bp++, "\n");
12305                 }
12306 
12307                 (void) sprintf(bp, "%08x ", fw->host_reg[cnt]);
12308                 bp += 9;
12309         }
12310 
12311         (void) sprintf(bp, "\n\nMailbox Registers");
12312         bp += strlen(bp);
12313         for (cnt = 0; cnt < sizeof (fw->mailbox_reg) / 2; cnt++) {
12314                 if (cnt % 16 == 0) {
12315                         (void) sprintf(bp++, "\n");
12316                 }
12317 
12318                 (void) sprintf(bp, "%04x ", fw->mailbox_reg[cnt]);
12319                 bp += 5;
12320         }
12321 
12322         (void) sprintf(bp, "\n\nXSEQ GP Registers");
12323         bp += strlen(bp);
12324         for (cnt = 0; cnt < sizeof (fw->xseq_gp_reg) / 4; cnt++) {
12325                 if (cnt % 8 == 0) {
12326                         (void) sprintf(bp++, "\n");
12327                 }
12328 
12329                 (void) sprintf(bp, "%08x ", fw->xseq_gp_reg[cnt]);
12330                 bp += 9;
12331         }
12332 
12333         (void) sprintf(bp, "\n\nXSEQ-0 Registers");
12334         bp += strlen(bp);
12335         for (cnt = 0; cnt < sizeof (fw->xseq_0_reg) / 4; cnt++) {
12336                 if (cnt % 8 == 0) {
12337                         (void) sprintf(bp++, "\n");
12338                 }
12339 
12340                 (void) sprintf(bp, "%08x ", fw->xseq_0_reg[cnt]);
12341                 bp += 9;
12342         }
12343 
12344         (void) sprintf(bp, "\n\nXSEQ-1 Registers");
12345         bp += strlen(bp);
12346         for (cnt = 0; cnt < sizeof (fw->xseq_1_reg) / 4; cnt++) {
12347                 if (cnt % 8 == 0) {
12348                         (void) sprintf(bp++, "\n");
12349                 }
12350 
12351                 (void) sprintf(bp, "%08x ", fw->xseq_1_reg[cnt]);
12352                 bp += 9;
12353         }
12354 
12355         (void) sprintf(bp, "\n\nRSEQ GP Registers");
12356         bp += strlen(bp);
12357         for (cnt = 0; cnt < sizeof (fw->rseq_gp_reg) / 4; cnt++) {
12358                 if (cnt % 8 == 0) {
12359                         (void) sprintf(bp++, "\n");
12360                 }
12361 
12362                 (void) sprintf(bp, "%08x ", fw->rseq_gp_reg[cnt]);
12363                 bp += 9;
12364         }
12365 
12366         (void) sprintf(bp, "\n\nRSEQ-0 Registers");
12367         bp += strlen(bp);
12368         for (cnt = 0; cnt < sizeof (fw->rseq_0_reg) / 4; cnt++) {
12369                 if (cnt % 8 == 0) {
12370                         (void) sprintf(bp++, "\n");
12371                 }
12372 
12373                 (void) sprintf(bp, "%08x ", fw->rseq_0_reg[cnt]);
12374                 bp += 9;
12375         }
12376 
12377         (void) sprintf(bp, "\n\nRSEQ-1 Registers");
12378         bp += strlen(bp);
12379         for (cnt = 0; cnt < sizeof (fw->rseq_1_reg) / 4; cnt++) {
12380                 if (cnt % 8 == 0) {
12381                         (void) sprintf(bp++, "\n");
12382                 }
12383 
12384                 (void) sprintf(bp, "%08x ", fw->rseq_1_reg[cnt]);
12385                 bp += 9;
12386         }
12387 
12388         (void) sprintf(bp, "\n\nRSEQ-2 Registers");
12389         bp += strlen(bp);
12390         for (cnt = 0; cnt < sizeof (fw->rseq_2_reg) / 4; cnt++) {
12391                 if (cnt % 8 == 0) {
12392                         (void) sprintf(bp++, "\n");
12393                 }
12394 
12395                 (void) sprintf(bp, "%08x ", fw->rseq_2_reg[cnt]);
12396                 bp += 9;
12397         }
12398 
12399         (void) sprintf(bp, "\n\nCommand DMA Registers");
12400         bp += strlen(bp);
12401         for (cnt = 0; cnt < sizeof (fw->cmd_dma_reg) / 4; cnt++) {
12402                 if (cnt % 8 == 0) {
12403                         (void) sprintf(bp++, "\n");
12404                 }
12405 
12406                 (void) sprintf(bp, "%08x ", fw->cmd_dma_reg[cnt]);
12407                 bp += 9;
12408         }
12409 
12410         (void) sprintf(bp, "\n\nRequest0 Queue DMA Channel Registers");
12411         bp += strlen(bp);
12412         for (cnt = 0; cnt < sizeof (fw->req0_dma_reg) / 4; cnt++) {
12413                 if (cnt % 8 == 0) {
12414                         (void) sprintf(bp++, "\n");
12415                 }
12416 
12417                 (void) sprintf(bp, "%08x ", fw->req0_dma_reg[cnt]);
12418                 bp += 9;
12419         }
12420 
12421         (void) sprintf(bp, "\n\nResponse0 Queue DMA Channel Registers");
12422         bp += strlen(bp);
12423         for (cnt = 0; cnt < sizeof (fw->resp0_dma_reg) / 4; cnt++) {
12424                 if (cnt % 8 == 0) {
12425                         (void) sprintf(bp++, "\n");
12426                 }
12427 
12428                 (void) sprintf(bp, "%08x ", fw->resp0_dma_reg[cnt]);
12429                 bp += 9;
12430         }
12431 
12432         (void) sprintf(bp, "\n\nRequest1 Queue DMA Channel Registers");
12433         bp += strlen(bp);
12434         for (cnt = 0; cnt < sizeof (fw->req1_dma_reg) / 4; cnt++) {
12435                 if (cnt % 8 == 0) {
12436                         (void) sprintf(bp++, "\n");
12437                 }
12438 
12439                 (void) sprintf(bp, "%08x ", fw->req1_dma_reg[cnt]);
12440                 bp += 9;
12441         }
12442 
12443         (void) sprintf(bp, "\n\nXMT0 Data DMA Registers");
12444         bp += strlen(bp);
12445         for (cnt = 0; cnt < sizeof (fw->xmt0_dma_reg) / 4; cnt++) {
12446                 if (cnt % 8 == 0) {
12447                         (void) sprintf(bp++, "\n");
12448                 }
12449 
12450                 (void) sprintf(bp, "%08x ", fw->xmt0_dma_reg[cnt]);
12451                 bp += 9;
12452         }
12453 
12454         (void) sprintf(bp, "\n\nXMT1 Data DMA Registers");
12455         bp += strlen(bp);
12456         for (cnt = 0; cnt < sizeof (fw->xmt1_dma_reg) / 4; cnt++) {
12457                 if (cnt % 8 == 0) {
12458                         (void) sprintf(bp++, "\n");
12459                 }
12460 
12461                 (void) sprintf(bp, "%08x ", fw->xmt1_dma_reg[cnt]);
12462                 bp += 9;
12463         }
12464 
12465         (void) sprintf(bp, "\n\nXMT2 Data DMA Registers");
12466         bp += strlen(bp);
12467         for (cnt = 0; cnt < sizeof (fw->xmt2_dma_reg) / 4; cnt++) {
12468                 if (cnt % 8 == 0) {
12469                         (void) sprintf(bp++, "\n");
12470                 }
12471 
12472                 (void) sprintf(bp, "%08x ", fw->xmt2_dma_reg[cnt]);
12473                 bp += 9;
12474         }
12475 
12476         (void) sprintf(bp, "\n\nXMT3 Data DMA Registers");
12477         bp += strlen(bp);
12478         for (cnt = 0; cnt < sizeof (fw->xmt3_dma_reg) / 4; cnt++) {
12479                 if (cnt % 8 == 0) {
12480                         (void) sprintf(bp++, "\n");
12481                 }
12482 
12483                 (void) sprintf(bp, "%08x ", fw->xmt3_dma_reg[cnt]);
12484                 bp += 9;
12485         }
12486 
12487         (void) sprintf(bp, "\n\nXMT4 Data DMA Registers");
12488         bp += strlen(bp);
12489         for (cnt = 0; cnt < sizeof (fw->xmt4_dma_reg) / 4; cnt++) {
12490                 if (cnt % 8 == 0) {
12491                         (void) sprintf(bp++, "\n");
12492                 }
12493 
12494                 (void) sprintf(bp, "%08x ", fw->xmt4_dma_reg[cnt]);
12495                 bp += 9;
12496         }
12497 
12498         (void) sprintf(bp, "\n\nXMT Data DMA Common Registers");
12499         bp += strlen(bp);
12500         for (cnt = 0; cnt < sizeof (fw->xmt_data_dma_reg) / 4; cnt++) {
12501                 if (cnt % 8 == 0) {
12502                         (void) sprintf(bp++, "\n");
12503                 }
12504 
12505                 (void) sprintf(bp, "%08x ", fw->xmt_data_dma_reg[cnt]);
12506                 bp += 9;
12507         }
12508 
12509         (void) sprintf(bp, "\n\nRCV Thread 0 Data DMA Registers");
12510         bp += strlen(bp);
12511         for (cnt = 0; cnt < sizeof (fw->rcvt0_data_dma_reg) / 4; cnt++) {
12512                 if (cnt % 8 == 0) {
12513                         (void) sprintf(bp++, "\n");
12514                 }
12515 
12516                 (void) sprintf(bp, "%08x ", fw->rcvt0_data_dma_reg[cnt]);
12517                 bp += 9;
12518         }
12519 
12520         (void) sprintf(bp, "\n\nRCV Thread 1 Data DMA Registers");
12521         bp += strlen(bp);
12522         for (cnt = 0; cnt < sizeof (fw->rcvt1_data_dma_reg) / 4; cnt++) {
12523                 if (cnt % 8 == 0) {
12524                         (void) sprintf(bp++, "\n");
12525                 }
12526 
12527                 (void) sprintf(bp, "%08x ", fw->rcvt1_data_dma_reg[cnt]);
12528                 bp += 9;
12529         }
12530 
12531         (void) sprintf(bp, "\n\nRISC GP Registers");
12532         bp += strlen(bp);
12533         for (cnt = 0; cnt < sizeof (fw->risc_gp_reg) / 4; cnt++) {
12534                 if (cnt % 8 == 0) {
12535                         (void) sprintf(bp++, "\n");
12536                 }
12537 
12538                 (void) sprintf(bp, "%08x ", fw->risc_gp_reg[cnt]);
12539                 bp += 9;
12540         }
12541 
12542         (void) sprintf(bufp + strlen(bufp), "\n\nShadow Registers");
12543         bp += strlen(bp);
12544         for (cnt = 0; cnt < sizeof (fw->shadow_reg) / 4; cnt++) {
12545                 if (cnt % 8 == 0) {
12546                         (void) sprintf(bp++, "\n");
12547                 }
12548 
12549                 (void) sprintf(bp, "%08x ", fw->shadow_reg[cnt]);
12550                 bp += 9;
12551         }
12552 
12553         (void) sprintf(bp, "\n\nLMC Registers");
12554         bp += strlen(bp);
12555         for (cnt = 0; cnt < sizeof (fw->lmc_reg) / 4; cnt++) {
12556                 if (cnt % 8 == 0) {
12557                         (void) sprintf(bp++, "\n");
12558                 }
12559 
12560                 (void) sprintf(bp, "%08x ", fw->lmc_reg[cnt]);
12561                 bp += 9;
12562         }
12563 
12564         (void) sprintf(bp, "\n\nFPM Hardware Registers");
12565         bp += strlen(bp);
12566         for (cnt = 0; cnt < sizeof (fw->fpm_hdw_reg) / 4; cnt++) {
12567                 if (cnt % 8 == 0) {
12568                         (void) sprintf(bp++, "\n");
12569                 }
12570 
12571                 (void) sprintf(bp, "%08x ", fw->fpm_hdw_reg[cnt]);
12572                 bp += 9;
12573         }
12574 
12575         (void) sprintf(bp, "\n\nFB Hardware Registers");
12576         bp += strlen(bp);
12577         for (cnt = 0; cnt < sizeof (fw->fb_hdw_reg) / 4; cnt++) {
12578                 if (cnt % 8 == 0) {
12579                         (void) sprintf(bp++, "\n");
12580                 }
12581 
12582                 (void) sprintf(bp, "%08x ", fw->fb_hdw_reg[cnt]);
12583                 bp += 9;
12584         }
12585 
12586         (void) sprintf(bp, "\n\nCode RAM");
12587         bp += strlen(bp);
12588         for (cnt = 0; cnt < sizeof (fw->code_ram) / 4; cnt++) {
12589                 if (cnt % 8 == 0) {
12590                         (void) sprintf(bp, "\n%08x: ", cnt + 0x20000);
12591                         bp += 11;
12592                 }
12593 
12594                 (void) sprintf(bp, "%08x ", fw->code_ram[cnt]);
12595                 bp += 9;
12596         }
12597 
12598         (void) sprintf(bp, "\n\nExternal Memory");
12599         bp += strlen(bp);
12600         for (cnt = 0; cnt < ha->fw_ext_memory_size / 4; cnt++) {
12601                 if (cnt % 8 == 0) {
12602                         (void) sprintf(bp, "\n%08x: ", cnt + 0x100000);
12603                         bp += 11;
12604                 }
12605                 (void) sprintf(bp, "%08x ", fw->ext_mem[cnt]);
12606                 bp += 9;
12607         }
12608 
12609         (void) sprintf(bp, "\n[<==END] ISP Debug Dump");
12610         bp += strlen(bp);
12611 
12612         (void) sprintf(bp, "\n\nRequest Queue");
12613         bp += strlen(bp);
12614         for (cnt = 0; cnt < REQUEST_QUEUE_SIZE / 4; cnt++) {
12615                 if (cnt % 8 == 0) {
12616                         (void) sprintf(bp, "\n%08x: ", cnt);
12617                         bp += strlen(bp);
12618                 }
12619                 (void) sprintf(bp, "%08x ", fw->req_q[cnt]);
12620                 bp += strlen(bp);
12621         }
12622 
12623         (void) sprintf(bp, "\n\nResponse Queue");
12624         bp += strlen(bp);
12625         for (cnt = 0; cnt < RESPONSE_QUEUE_SIZE / 4; cnt++) {
12626                 if (cnt % 8 == 0) {
12627                         (void) sprintf(bp, "\n%08x: ", cnt);
12628                         bp += strlen(bp);
12629                 }
12630                 (void) sprintf(bp, "%08x ", fw->rsp_q[cnt]);
12631                 bp += strlen(bp);
12632         }
12633 
12634         if (CFG_IST(ha, CFG_ENABLE_FWEXTTRACE) &&
12635             (ha->fwexttracebuf.bp != NULL)) {
12636                 uint32_t cnt_b = 0;
12637                 uint64_t w64 = (uintptr_t)ha->fwexttracebuf.bp;
12638 
12639                 (void) sprintf(bp, "\n\nExtended Trace Buffer Memory");
12640                 bp += strlen(bp);
12641                 /* show data address as a byte address, data as long words */
12642                 for (cnt = 0; cnt < FWEXTSIZE / 4; cnt++) {
12643                         cnt_b = cnt * 4;
12644                         if (cnt_b % 32 == 0) {
12645                                 (void) sprintf(bp, "\n%08x: ",
12646                                     (int)(w64 + cnt_b));
12647                                 bp += 11;
12648                         }
12649                         (void) sprintf(bp, "%08x ", fw->ext_trace_buf[cnt]);
12650                         bp += 9;
12651                 }
12652         }
12653 
12654         if (CFG_IST(ha, CFG_ENABLE_FWFCETRACE) &&
12655             (ha->fwfcetracebuf.bp != NULL)) {
12656                 uint32_t cnt_b = 0;
12657                 uint64_t w64 = (uintptr_t)ha->fwfcetracebuf.bp;
12658 
12659                 (void) sprintf(bp, "\n\nFC Event Trace Buffer Memory");
12660                 bp += strlen(bp);
12661                 /* show data address as a byte address, data as long words */
12662                 for (cnt = 0; cnt < FWFCESIZE / 4; cnt++) {
12663                         cnt_b = cnt * 4;
12664                         if (cnt_b % 32 == 0) {
12665                                 (void) sprintf(bp, "\n%08x: ",
12666                                     (int)(w64 + cnt_b));
12667                                 bp += 11;
12668                         }
12669                         (void) sprintf(bp, "%08x ", fw->fce_trace_buf[cnt]);
12670                         bp += 9;
12671                 }
12672         }
12673 
12674         (void) sprintf(bp, "\n\n");
12675         bp += strlen(bp);
12676 
12677         cnt = (uint32_t)((uintptr_t)bp - (uintptr_t)bufp);
12678 
12679         QL_PRINT_3(CE_CONT, "(%d): done=%xh\n", ha->instance, cnt);
12680 
12681         return (cnt);
12682 }
12683 
12684 /*
12685  * ql_2581_ascii_fw_dump
12686  *      Converts ISP25xx or ISP81xx firmware binary dump to ascii.
12687  *
12688  * Input:
12689  *      ha = adapter state pointer.
12690  *      bptr = buffer pointer.
12691  *
12692  * Returns:
12693  *      Amount of data buffer used.
12694  *
12695  * Context:
12696  *      Kernel context.
12697  */
12698 static size_t
12699 ql_2581_ascii_fw_dump(ql_adapter_state_t *ha, caddr_t bufp)
12700 {
12701         uint32_t                cnt;
12702         uint32_t                cnt1;
12703         caddr_t                 bp = bufp;
12704         ql_25xx_fw_dump_t       *fw = ha->ql_dump_ptr;
12705 
12706         QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
12707 
12708         (void) sprintf(bp, "\nISP FW Version %d.%02d.%02d Attributes %X\n",
12709             ha->fw_major_version, ha->fw_minor_version,
12710             ha->fw_subminor_version, ha->fw_attributes);
12711         bp += strlen(bp);
12712 
12713         (void) sprintf(bp, "\nR2H Status Register\n%08x\n", fw->r2h_status);
12714         bp += strlen(bp);
12715 
12716         (void) sprintf(bp, "\nHostRisc Registers");
12717         bp += strlen(bp);
12718         for (cnt = 0; cnt < sizeof (fw->hostrisc_reg) / 4; cnt++) {
12719                 if (cnt % 8 == 0) {
12720                         (void) sprintf(bp++, "\n");
12721                 }
12722                 (void) sprintf(bp, "%08x ", fw->hostrisc_reg[cnt]);
12723                 bp += 9;
12724         }
12725 
12726         (void) sprintf(bp, "\n\nPCIe Registers");
12727         bp += strlen(bp);
12728         for (cnt = 0; cnt < sizeof (fw->pcie_reg) / 4; cnt++) {
12729                 if (cnt % 8 == 0) {
12730                         (void) sprintf(bp++, "\n");
12731                 }
12732                 (void) sprintf(bp, "%08x ", fw->pcie_reg[cnt]);
12733                 bp += 9;
12734         }
12735 
12736         (void) strcat(bp, "\n\nHost Interface Registers");
12737         bp += strlen(bp);
12738         for (cnt = 0; cnt < sizeof (fw->host_reg) / 4; cnt++) {
12739                 if (cnt % 8 == 0) {
12740                         (void) sprintf(bp++, "\n");
12741                 }
12742                 (void) sprintf(bp, "%08x ", fw->host_reg[cnt]);
12743                 bp += 9;
12744         }
12745 
12746         (void) sprintf(bufp + strlen(bufp), "\n\nShadow Registers");
12747         bp += strlen(bp);
12748         for (cnt = 0; cnt < sizeof (fw->shadow_reg) / 4; cnt++) {
12749                 if (cnt % 8 == 0) {
12750                         (void) sprintf(bp++, "\n");
12751                 }
12752                 (void) sprintf(bp, "%08x ", fw->shadow_reg[cnt]);
12753                 bp += 9;
12754         }
12755 
12756         (void) sprintf(bufp + strlen(bufp), "\n\nRISC IO Register\n%08x",
12757             fw->risc_io);
12758         bp += strlen(bp);
12759 
12760         (void) sprintf(bp, "\n\nMailbox Registers");
12761         bp += strlen(bp);
12762         for (cnt = 0; cnt < sizeof (fw->mailbox_reg) / 2; cnt++) {
12763                 if (cnt % 16 == 0) {
12764                         (void) sprintf(bp++, "\n");
12765                 }
12766                 (void) sprintf(bp, "%04x ", fw->mailbox_reg[cnt]);
12767                 bp += 5;
12768         }
12769 
12770         (void) sprintf(bp, "\n\nXSEQ GP Registers");
12771         bp += strlen(bp);
12772         for (cnt = 0; cnt < sizeof (fw->xseq_gp_reg) / 4; cnt++) {
12773                 if (cnt % 8 == 0) {
12774                         (void) sprintf(bp++, "\n");
12775                 }
12776                 (void) sprintf(bp, "%08x ", fw->xseq_gp_reg[cnt]);
12777                 bp += 9;
12778         }
12779 
12780         (void) sprintf(bp, "\n\nXSEQ-0 Registers");
12781         bp += strlen(bp);
12782         for (cnt = 0; cnt < sizeof (fw->xseq_0_reg) / 4; cnt++) {
12783                 if (cnt % 8 == 0) {
12784                         (void) sprintf(bp++, "\n");
12785                 }
12786                 (void) sprintf(bp, "%08x ", fw->xseq_0_reg[cnt]);
12787                 bp += 9;
12788         }
12789 
12790         (void) sprintf(bp, "\n\nXSEQ-1 Registers");
12791         bp += strlen(bp);
12792         for (cnt = 0; cnt < sizeof (fw->xseq_1_reg) / 4; cnt++) {
12793                 if (cnt % 8 == 0) {
12794                         (void) sprintf(bp++, "\n");
12795                 }
12796                 (void) sprintf(bp, "%08x ", fw->xseq_1_reg[cnt]);
12797                 bp += 9;
12798         }
12799 
12800         (void) sprintf(bp, "\n\nRSEQ GP Registers");
12801         bp += strlen(bp);
12802         for (cnt = 0; cnt < sizeof (fw->rseq_gp_reg) / 4; cnt++) {
12803                 if (cnt % 8 == 0) {
12804                         (void) sprintf(bp++, "\n");
12805                 }
12806                 (void) sprintf(bp, "%08x ", fw->rseq_gp_reg[cnt]);
12807                 bp += 9;
12808         }
12809 
12810         (void) sprintf(bp, "\n\nRSEQ-0 Registers");
12811         bp += strlen(bp);
12812         for (cnt = 0; cnt < sizeof (fw->rseq_0_reg) / 4; cnt++) {
12813                 if (cnt % 8 == 0) {
12814                         (void) sprintf(bp++, "\n");
12815                 }
12816                 (void) sprintf(bp, "%08x ", fw->rseq_0_reg[cnt]);
12817                 bp += 9;
12818         }
12819 
12820         (void) sprintf(bp, "\n\nRSEQ-1 Registers");
12821         bp += strlen(bp);
12822         for (cnt = 0; cnt < sizeof (fw->rseq_1_reg) / 4; cnt++) {
12823                 if (cnt % 8 == 0) {
12824                         (void) sprintf(bp++, "\n");
12825                 }
12826                 (void) sprintf(bp, "%08x ", fw->rseq_1_reg[cnt]);
12827                 bp += 9;
12828         }
12829 
12830         (void) sprintf(bp, "\n\nRSEQ-2 Registers");
12831         bp += strlen(bp);
12832         for (cnt = 0; cnt < sizeof (fw->rseq_2_reg) / 4; cnt++) {
12833                 if (cnt % 8 == 0) {
12834                         (void) sprintf(bp++, "\n");
12835                 }
12836                 (void) sprintf(bp, "%08x ", fw->rseq_2_reg[cnt]);
12837                 bp += 9;
12838         }
12839 
12840         (void) sprintf(bp, "\n\nASEQ GP Registers");
12841         bp += strlen(bp);
12842         for (cnt = 0; cnt < sizeof (fw->aseq_gp_reg) / 4; cnt++) {
12843                 if (cnt % 8 == 0) {
12844                         (void) sprintf(bp++, "\n");
12845                 }
12846                 (void) sprintf(bp, "%08x ", fw->aseq_gp_reg[cnt]);
12847                 bp += 9;
12848         }
12849 
12850         (void) sprintf(bp, "\n\nASEQ-0 Registers");
12851         bp += strlen(bp);
12852         for (cnt = 0; cnt < sizeof (fw->aseq_0_reg) / 4; cnt++) {
12853                 if (cnt % 8 == 0) {
12854                         (void) sprintf(bp++, "\n");
12855                 }
12856                 (void) sprintf(bp, "%08x ", fw->aseq_0_reg[cnt]);
12857                 bp += 9;
12858         }
12859 
12860         (void) sprintf(bp, "\n\nASEQ-1 Registers");
12861         bp += strlen(bp);
12862         for (cnt = 0; cnt < sizeof (fw->aseq_1_reg) / 4; cnt++) {
12863                 if (cnt % 8 == 0) {
12864                         (void) sprintf(bp++, "\n");
12865                 }
12866                 (void) sprintf(bp, "%08x ", fw->aseq_1_reg[cnt]);
12867                 bp += 9;
12868         }
12869 
12870         (void) sprintf(bp, "\n\nASEQ-2 Registers");
12871         bp += strlen(bp);
12872         for (cnt = 0; cnt < sizeof (fw->aseq_2_reg) / 4; cnt++) {
12873                 if (cnt % 8 == 0) {
12874                         (void) sprintf(bp++, "\n");
12875                 }
12876                 (void) sprintf(bp, "%08x ", fw->aseq_2_reg[cnt]);
12877                 bp += 9;
12878         }
12879 
12880         (void) sprintf(bp, "\n\nCommand DMA Registers");
12881         bp += strlen(bp);
12882         for (cnt = 0; cnt < sizeof (fw->cmd_dma_reg) / 4; cnt++) {
12883                 if (cnt % 8 == 0) {
12884                         (void) sprintf(bp++, "\n");
12885                 }
12886                 (void)  sprintf(bp, "%08x ", fw->cmd_dma_reg[cnt]);
12887                 bp += 9;
12888         }
12889 
12890         (void) sprintf(bp, "\n\nRequest0 Queue DMA Channel Registers");
12891         bp += strlen(bp);
12892         for (cnt = 0; cnt < sizeof (fw->req0_dma_reg) / 4; cnt++) {
12893                 if (cnt % 8 == 0) {
12894                         (void) sprintf(bp++, "\n");
12895                 }
12896                 (void) sprintf(bp, "%08x ", fw->req0_dma_reg[cnt]);
12897                 bp += 9;
12898         }
12899 
12900         (void) sprintf(bp, "\n\nResponse0 Queue DMA Channel Registers");
12901         bp += strlen(bp);
12902         for (cnt = 0; cnt < sizeof (fw->resp0_dma_reg) / 4; cnt++) {
12903                 if (cnt % 8 == 0) {
12904                         (void) sprintf(bp++, "\n");
12905                 }
12906                 (void) sprintf(bp, "%08x ", fw->resp0_dma_reg[cnt]);
12907                 bp += 9;
12908         }
12909 
12910         (void) sprintf(bp, "\n\nRequest1 Queue DMA Channel Registers");
12911         bp += strlen(bp);
12912         for (cnt = 0; cnt < sizeof (fw->req1_dma_reg) / 4; cnt++) {
12913                 if (cnt % 8 == 0) {
12914                         (void) sprintf(bp++, "\n");
12915                 }
12916                 (void) sprintf(bp, "%08x ", fw->req1_dma_reg[cnt]);
12917                 bp += 9;
12918         }
12919 
12920         (void) sprintf(bp, "\n\nXMT0 Data DMA Registers");
12921         bp += strlen(bp);
12922         for (cnt = 0; cnt < sizeof (fw->xmt0_dma_reg) / 4; cnt++) {
12923                 if (cnt % 8 == 0) {
12924                         (void) sprintf(bp++, "\n");
12925                 }
12926                 (void) sprintf(bp, "%08x ", fw->xmt0_dma_reg[cnt]);
12927                 bp += 9;
12928         }
12929 
12930         (void) sprintf(bp, "\n\nXMT1 Data DMA Registers");
12931         bp += strlen(bp);
12932         for (cnt = 0; cnt < sizeof (fw->xmt1_dma_reg) / 4; cnt++) {
12933                 if (cnt % 8 == 0) {
12934                         (void) sprintf(bp++, "\n");
12935                 }
12936                 (void) sprintf(bp, "%08x ", fw->xmt1_dma_reg[cnt]);
12937                 bp += 9;
12938         }
12939 
12940         (void) sprintf(bp, "\n\nXMT2 Data DMA Registers");
12941         bp += strlen(bp);
12942         for (cnt = 0; cnt < sizeof (fw->xmt2_dma_reg) / 4; cnt++) {
12943                 if (cnt % 8 == 0) {
12944                         (void) sprintf(bp++, "\n");
12945                 }
12946                 (void) sprintf(bp, "%08x ", fw->xmt2_dma_reg[cnt]);
12947                 bp += 9;
12948         }
12949 
12950         (void) sprintf(bp, "\n\nXMT3 Data DMA Registers");
12951         bp += strlen(bp);
12952         for (cnt = 0; cnt < sizeof (fw->xmt3_dma_reg) / 4; cnt++) {
12953                 if (cnt % 8 == 0) {
12954                         (void) sprintf(bp++, "\n");
12955                 }
12956                 (void) sprintf(bp, "%08x ", fw->xmt3_dma_reg[cnt]);
12957                 bp += 9;
12958         }
12959 
12960         (void) sprintf(bp, "\n\nXMT4 Data DMA Registers");
12961         bp += strlen(bp);
12962         for (cnt = 0; cnt < sizeof (fw->xmt4_dma_reg) / 4; cnt++) {
12963                 if (cnt % 8 == 0) {
12964                         (void) sprintf(bp++, "\n");
12965                 }
12966                 (void) sprintf(bp, "%08x ", fw->xmt4_dma_reg[cnt]);
12967                 bp += 9;
12968         }
12969 
12970         (void) sprintf(bp, "\n\nXMT Data DMA Common Registers");
12971         bp += strlen(bp);
12972         for (cnt = 0; cnt < sizeof (fw->xmt_data_dma_reg) / 4; cnt++) {
12973                 if (cnt % 8 == 0) {
12974                         (void) sprintf(bp++, "\n");
12975                 }
12976                 (void) sprintf(bp, "%08x ", fw->xmt_data_dma_reg[cnt]);
12977                 bp += 9;
12978         }
12979 
12980         (void) sprintf(bp, "\n\nRCV Thread 0 Data DMA Registers");
12981         bp += strlen(bp);
12982         for (cnt = 0; cnt < sizeof (fw->rcvt0_data_dma_reg) / 4; cnt++) {
12983                 if (cnt % 8 == 0) {
12984                         (void) sprintf(bp++, "\n");
12985                 }
12986                 (void) sprintf(bp, "%08x ", fw->rcvt0_data_dma_reg[cnt]);
12987                 bp += 9;
12988         }
12989 
12990         (void) sprintf(bp, "\n\nRCV Thread 1 Data DMA Registers");
12991         bp += strlen(bp);
12992         for (cnt = 0; cnt < sizeof (fw->rcvt1_data_dma_reg) / 4; cnt++) {
12993                 if (cnt % 8 == 0) {
12994                         (void) sprintf(bp++, "\n");
12995                 }
12996                 (void) sprintf(bp, "%08x ", fw->rcvt1_data_dma_reg[cnt]);
12997                 bp += 9;
12998         }
12999 
13000         (void) sprintf(bp, "\n\nRISC GP Registers");
13001         bp += strlen(bp);
13002         for (cnt = 0; cnt < sizeof (fw->risc_gp_reg) / 4; cnt++) {
13003                 if (cnt % 8 == 0) {
13004                         (void) sprintf(bp++, "\n");
13005                 }
13006                 (void) sprintf(bp, "%08x ", fw->risc_gp_reg[cnt]);
13007                 bp += 9;
13008         }
13009 
13010         (void) sprintf(bp, "\n\nLMC Registers");
13011         bp += strlen(bp);
13012         for (cnt = 0; cnt < sizeof (fw->lmc_reg) / 4; cnt++) {
13013                 if (cnt % 8 == 0) {
13014                         (void) sprintf(bp++, "\n");
13015                 }
13016                 (void) sprintf(bp, "%08x ", fw->lmc_reg[cnt]);
13017                 bp += 9;
13018         }
13019 
13020         (void) sprintf(bp, "\n\nFPM Hardware Registers");
13021         bp += strlen(bp);
13022         cnt1 = CFG_IST(ha, CFG_CTRL_81XX) ?
13023             (uint32_t)(sizeof (((ql_81xx_fw_dump_t *)(fw))->fpm_hdw_reg)) :
13024             (uint32_t)(sizeof (fw->fpm_hdw_reg));
13025         for (cnt = 0; cnt < cnt1 / 4; cnt++) {
13026                 if (cnt % 8 == 0) {
13027                         (void) sprintf(bp++, "\n");
13028                 }
13029                 (void) sprintf(bp, "%08x ", fw->fpm_hdw_reg[cnt]);
13030                 bp += 9;
13031         }
13032 
13033         (void) sprintf(bp, "\n\nFB Hardware Registers");
13034         bp += strlen(bp);
13035         cnt1 = CFG_IST(ha, CFG_CTRL_81XX) ?
13036             (uint32_t)(sizeof (((ql_81xx_fw_dump_t *)(fw))->fb_hdw_reg)) :
13037             (uint32_t)(sizeof (fw->fb_hdw_reg));
13038         for (cnt = 0; cnt < cnt1 / 4; cnt++) {
13039                 if (cnt % 8 == 0) {
13040                         (void) sprintf(bp++, "\n");
13041                 }
13042                 (void) sprintf(bp, "%08x ", fw->fb_hdw_reg[cnt]);
13043                 bp += 9;
13044         }
13045 
13046         (void) sprintf(bp, "\n\nCode RAM");
13047         bp += strlen(bp);
13048         for (cnt = 0; cnt < sizeof (fw->code_ram) / 4; cnt++) {
13049                 if (cnt % 8 == 0) {
13050                         (void) sprintf(bp, "\n%08x: ", cnt + 0x20000);
13051                         bp += 11;
13052                 }
13053                 (void) sprintf(bp, "%08x ", fw->code_ram[cnt]);
13054                 bp += 9;
13055         }
13056 
13057         (void) sprintf(bp, "\n\nExternal Memory");
13058         bp += strlen(bp);
13059         for (cnt = 0; cnt < ha->fw_ext_memory_size / 4; cnt++) {
13060                 if (cnt % 8 == 0) {
13061                         (void) sprintf(bp, "\n%08x: ", cnt + 0x100000);
13062                         bp += 11;
13063                 }
13064                 (void) sprintf(bp, "%08x ", fw->ext_mem[cnt]);
13065                 bp += 9;
13066         }
13067 
13068         (void) sprintf(bp, "\n[<==END] ISP Debug Dump");
13069         bp += strlen(bp);
13070 
13071         (void) sprintf(bp, "\n\nRequest Queue");
13072         bp += strlen(bp);
13073         for (cnt = 0; cnt < REQUEST_QUEUE_SIZE / 4; cnt++) {
13074                 if (cnt % 8 == 0) {
13075                         (void) sprintf(bp, "\n%08x: ", cnt);
13076                         bp += strlen(bp);
13077                 }
13078                 (void) sprintf(bp, "%08x ", fw->req_q[cnt]);
13079                 bp += strlen(bp);
13080         }
13081 
13082         (void) sprintf(bp, "\n\nResponse Queue");
13083         bp += strlen(bp);
13084         for (cnt = 0; cnt < RESPONSE_QUEUE_SIZE / 4; cnt++) {
13085                 if (cnt % 8 == 0) {
13086                         (void) sprintf(bp, "\n%08x: ", cnt);
13087                         bp += strlen(bp);
13088                 }
13089                 (void) sprintf(bp, "%08x ", fw->rsp_q[cnt]);
13090                 bp += strlen(bp);
13091         }
13092 
13093         if (CFG_IST(ha, CFG_ENABLE_FWEXTTRACE) &&
13094             (ha->fwexttracebuf.bp != NULL)) {
13095                 uint32_t cnt_b = 0;
13096                 uint64_t w64 = (uintptr_t)ha->fwexttracebuf.bp;
13097 
13098                 (void) sprintf(bp, "\n\nExtended Trace Buffer Memory");
13099                 bp += strlen(bp);
13100                 /* show data address as a byte address, data as long words */
13101                 for (cnt = 0; cnt < FWEXTSIZE / 4; cnt++) {
13102                         cnt_b = cnt * 4;
13103                         if (cnt_b % 32 == 0) {
13104                                 (void) sprintf(bp, "\n%08x: ",
13105                                     (int)(w64 + cnt_b));
13106                                 bp += 11;
13107                         }
13108                         (void) sprintf(bp, "%08x ", fw->ext_trace_buf[cnt]);
13109                         bp += 9;
13110                 }
13111         }
13112 
13113         if (CFG_IST(ha, CFG_ENABLE_FWFCETRACE) &&
13114             (ha->fwfcetracebuf.bp != NULL)) {
13115                 uint32_t cnt_b = 0;
13116                 uint64_t w64 = (uintptr_t)ha->fwfcetracebuf.bp;
13117 
13118                 (void) sprintf(bp, "\n\nFC Event Trace Buffer Memory");
13119                 bp += strlen(bp);
13120                 /* show data address as a byte address, data as long words */
13121                 for (cnt = 0; cnt < FWFCESIZE / 4; cnt++) {
13122                         cnt_b = cnt * 4;
13123                         if (cnt_b % 32 == 0) {
13124                                 (void) sprintf(bp, "\n%08x: ",
13125                                     (int)(w64 + cnt_b));
13126                                 bp += 11;
13127                         }
13128                         (void) sprintf(bp, "%08x ", fw->fce_trace_buf[cnt]);
13129                         bp += 9;
13130                 }
13131         }
13132 
13133         (void) sprintf(bp, "\n\n");
13134         bp += strlen(bp);
13135 
13136         cnt = (uint32_t)((uintptr_t)bp - (uintptr_t)bufp);
13137 
13138         QL_PRINT_3(CE_CONT, "(%d): done=%xh\n", ha->instance, cnt);
13139 
13140         return (cnt);
13141 }
13142 
13143 /*
13144  * ql_2200_binary_fw_dump
13145  *
13146  * Input:
13147  *      ha:     adapter state pointer.
13148  *      fw:     firmware dump context pointer.
13149  *
13150  * Returns:
13151  *      ql local function return status code.
13152  *
13153  * Context:
13154  *      Interrupt or Kernel context, no mailbox commands allowed.
13155  */
13156 static int
13157 ql_2200_binary_fw_dump(ql_adapter_state_t *ha, ql_fw_dump_t *fw)
13158 {
13159         uint32_t        cnt;
13160         uint16_t        risc_address;
13161         clock_t         timer;
13162         mbx_cmd_t       mc;
13163         mbx_cmd_t       *mcp = &mc;
13164         int             rval = QL_SUCCESS;
13165 
13166         QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
13167 
13168         /* Disable ISP interrupts. */
13169         WRT16_IO_REG(ha, ictrl, 0);
13170         ADAPTER_STATE_LOCK(ha);
13171         ha->flags &= ~INTERRUPTS_ENABLED;
13172         ADAPTER_STATE_UNLOCK(ha);
13173 
13174         /* Release mailbox registers. */
13175         WRT16_IO_REG(ha, semaphore, 0);
13176 
13177         /* Pause RISC. */
13178         WRT16_IO_REG(ha, hccr, HC_PAUSE_RISC);
13179         timer = 30000;
13180         while ((RD16_IO_REG(ha, hccr) & HC_RISC_PAUSE) == 0) {
13181                 if (timer-- != 0) {
13182                         drv_usecwait(MILLISEC);
13183                 } else {
13184                         rval = QL_FUNCTION_TIMEOUT;
13185                         break;
13186                 }
13187         }
13188 
13189         if (rval == QL_SUCCESS) {
13190                 (void) ql_read_regs(ha, fw->pbiu_reg, ha->iobase,
13191                     sizeof (fw->pbiu_reg) / 2, 16);
13192 
13193                 /* In 2200 we only read 8 mailboxes */
13194                 (void) ql_read_regs(ha, fw->mailbox_reg, ha->iobase + 0x10,
13195                     8, 16);
13196 
13197                 (void) ql_read_regs(ha, fw->dma_reg, ha->iobase + 0x20,
13198                     sizeof (fw->dma_reg) / 2, 16);
13199 
13200                 WRT16_IO_REG(ha, ctrl_status, 0);
13201                 (void) ql_read_regs(ha, fw->risc_hdw_reg, ha->iobase + 0xA0,
13202                     sizeof (fw->risc_hdw_reg) / 2, 16);
13203 
13204                 WRT16_IO_REG(ha, pcr, 0x2000);
13205                 (void) ql_read_regs(ha, fw->risc_gp0_reg, ha->iobase + 0x80,
13206                     sizeof (fw->risc_gp0_reg) / 2, 16);
13207 
13208                 WRT16_IO_REG(ha, pcr, 0x2100);
13209                 (void) ql_read_regs(ha, fw->risc_gp1_reg, ha->iobase + 0x80,
13210                     sizeof (fw->risc_gp1_reg) / 2, 16);
13211 
13212                 WRT16_IO_REG(ha, pcr, 0x2200);
13213                 (void) ql_read_regs(ha, fw->risc_gp2_reg, ha->iobase + 0x80,
13214                     sizeof (fw->risc_gp2_reg) / 2, 16);
13215 
13216                 WRT16_IO_REG(ha, pcr, 0x2300);
13217                 (void) ql_read_regs(ha, fw->risc_gp3_reg, ha->iobase + 0x80,
13218                     sizeof (fw->risc_gp3_reg) / 2, 16);
13219 
13220                 WRT16_IO_REG(ha, pcr, 0x2400);
13221                 (void) ql_read_regs(ha, fw->risc_gp4_reg, ha->iobase + 0x80,
13222                     sizeof (fw->risc_gp4_reg) / 2, 16);
13223 
13224                 WRT16_IO_REG(ha, pcr, 0x2500);
13225                 (void) ql_read_regs(ha, fw->risc_gp5_reg, ha->iobase + 0x80,
13226                     sizeof (fw->risc_gp5_reg) / 2, 16);
13227 
13228                 WRT16_IO_REG(ha, pcr, 0x2600);
13229                 (void) ql_read_regs(ha, fw->risc_gp6_reg, ha->iobase + 0x80,
13230                     sizeof (fw->risc_gp6_reg) / 2, 16);
13231 
13232                 WRT16_IO_REG(ha, pcr, 0x2700);
13233                 (void) ql_read_regs(ha, fw->risc_gp7_reg, ha->iobase + 0x80,
13234                     sizeof (fw->risc_gp7_reg) / 2, 16);
13235 
13236                 WRT16_IO_REG(ha, ctrl_status, 0x10);
13237                 /* 2200 has only 16 registers */
13238                 (void) ql_read_regs(ha, fw->frame_buf_hdw_reg,
13239                     ha->iobase + 0x80, 16, 16);
13240 
13241                 WRT16_IO_REG(ha, ctrl_status, 0x20);
13242                 (void) ql_read_regs(ha, fw->fpm_b0_reg, ha->iobase + 0x80,
13243                     sizeof (fw->fpm_b0_reg) / 2, 16);
13244 
13245                 WRT16_IO_REG(ha, ctrl_status, 0x30);
13246                 (void) ql_read_regs(ha, fw->fpm_b1_reg, ha->iobase + 0x80,
13247                     sizeof (fw->fpm_b1_reg) / 2, 16);
13248 
13249                 /* Select FPM registers. */
13250                 WRT16_IO_REG(ha, ctrl_status, 0x20);
13251 
13252                 /* FPM Soft Reset. */
13253                 WRT16_IO_REG(ha, fpm_diag_config, 0x100);
13254 
13255                 /* Select frame buffer registers. */
13256                 WRT16_IO_REG(ha, ctrl_status, 0x10);
13257 
13258                 /* Reset frame buffer FIFOs. */
13259                 WRT16_IO_REG(ha, fb_cmd, 0xa000);
13260 
13261                 /* Select RISC module registers. */
13262                 WRT16_IO_REG(ha, ctrl_status, 0);
13263 
13264                 /* Reset RISC module. */
13265                 WRT16_IO_REG(ha, hccr, HC_RESET_RISC);
13266 
13267                 /* Reset ISP semaphore. */
13268                 WRT16_IO_REG(ha, semaphore, 0);
13269 
13270                 /* Release RISC module. */
13271                 WRT16_IO_REG(ha, hccr, HC_RELEASE_RISC);
13272 
13273                 /* Wait for RISC to recover from reset. */
13274                 timer = 30000;
13275                 while (RD16_IO_REG(ha, mailbox_out[0]) == MBS_BUSY) {
13276                         if (timer-- != 0) {
13277                                 drv_usecwait(MILLISEC);
13278                         } else {
13279                                 rval = QL_FUNCTION_TIMEOUT;
13280                                 break;
13281                         }
13282                 }
13283 
13284                 /* Disable RISC pause on FPM parity error. */
13285                 WRT16_IO_REG(ha, hccr, HC_DISABLE_PARITY_PAUSE);
13286         }
13287 
13288         if (rval == QL_SUCCESS) {
13289                 /* Pause RISC. */
13290                 WRT16_IO_REG(ha, hccr, HC_PAUSE_RISC);
13291                 timer = 30000;
13292                 while ((RD16_IO_REG(ha, hccr) & HC_RISC_PAUSE) == 0) {
13293                         if (timer-- != 0) {
13294                                 drv_usecwait(MILLISEC);
13295                         } else {
13296                                 rval = QL_FUNCTION_TIMEOUT;
13297                                 break;
13298                         }
13299                 }
13300         }
13301 
13302         if (rval == QL_SUCCESS) {
13303                 /* Set memory configuration and timing. */
13304                 WRT16_IO_REG(ha, mctr, 0xf2);
13305 
13306                 /* Release RISC. */
13307                 WRT16_IO_REG(ha, hccr, HC_RELEASE_RISC);
13308 
13309                 /* Get RISC SRAM. */
13310                 risc_address = 0x1000;
13311                 WRT16_IO_REG(ha, mailbox_in[0], MBC_READ_RAM_WORD);
13312                 for (cnt = 0; cnt < 0xf000; cnt++) {
13313                         WRT16_IO_REG(ha, mailbox_in[1], risc_address++);
13314                         WRT16_IO_REG(ha, hccr, HC_SET_HOST_INT);
13315                         for (timer = 6000000; timer != 0; timer--) {
13316                                 /* Check for pending interrupts. */
13317                                 if (INTERRUPT_PENDING(ha)) {
13318                                         if (RD16_IO_REG(ha, semaphore) &
13319                                             BIT_0) {
13320                                                 WRT16_IO_REG(ha, hccr,
13321                                                     HC_CLR_RISC_INT);
13322                                                 mcp->mb[0] = RD16_IO_REG(ha,
13323                                                     mailbox_out[0]);
13324                                                 fw->risc_ram[cnt] =
13325                                                     RD16_IO_REG(ha,
13326                                                     mailbox_out[2]);
13327                                                 WRT16_IO_REG(ha,
13328                                                     semaphore, 0);
13329                                                 break;
13330                                         }
13331                                         WRT16_IO_REG(ha, hccr,
13332                                             HC_CLR_RISC_INT);
13333                                 }
13334                                 drv_usecwait(5);
13335                         }
13336 
13337                         if (timer == 0) {
13338                                 rval = QL_FUNCTION_TIMEOUT;
13339                         } else {
13340                                 rval = mcp->mb[0];
13341                         }
13342 
13343                         if (rval != QL_SUCCESS) {
13344                                 break;
13345                         }
13346                 }
13347         }
13348 
13349         QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
13350 
13351         return (rval);
13352 }
13353 
13354 /*
13355  * ql_2300_binary_fw_dump
13356  *
13357  * Input:
13358  *      ha:     adapter state pointer.
13359  *      fw:     firmware dump context pointer.
13360  *
13361  * Returns:
13362  *      ql local function return status code.
13363  *
13364  * Context:
13365  *      Interrupt or Kernel context, no mailbox commands allowed.
13366  */
13367 static int
13368 ql_2300_binary_fw_dump(ql_adapter_state_t *ha, ql_fw_dump_t *fw)
13369 {
13370         clock_t timer;
13371         int     rval = QL_SUCCESS;
13372 
13373         QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
13374 
13375         /* Disable ISP interrupts. */
13376         WRT16_IO_REG(ha, ictrl, 0);
13377         ADAPTER_STATE_LOCK(ha);
13378         ha->flags &= ~INTERRUPTS_ENABLED;
13379         ADAPTER_STATE_UNLOCK(ha);
13380 
13381         /* Release mailbox registers. */
13382         WRT16_IO_REG(ha, semaphore, 0);
13383 
13384         /* Pause RISC. */
13385         WRT16_IO_REG(ha, hccr, HC_PAUSE_RISC);
13386         timer = 30000;
13387         while ((RD16_IO_REG(ha, hccr) & HC_RISC_PAUSE) == 0) {
13388                 if (timer-- != 0) {
13389                         drv_usecwait(MILLISEC);
13390                 } else {
13391                         rval = QL_FUNCTION_TIMEOUT;
13392                         break;
13393                 }
13394         }
13395 
13396         if (rval == QL_SUCCESS) {
13397                 (void) ql_read_regs(ha, fw->pbiu_reg, ha->iobase,
13398                     sizeof (fw->pbiu_reg) / 2, 16);
13399 
13400                 (void) ql_read_regs(ha, fw->risc_host_reg, ha->iobase + 0x10,
13401                     sizeof (fw->risc_host_reg) / 2, 16);
13402 
13403                 (void) ql_read_regs(ha, fw->mailbox_reg, ha->iobase + 0x40,
13404                     sizeof (fw->mailbox_reg) / 2, 16);
13405 
13406                 WRT16_IO_REG(ha, ctrl_status, 0x40);
13407                 (void) ql_read_regs(ha, fw->resp_dma_reg, ha->iobase + 0x80,
13408                     sizeof (fw->resp_dma_reg) / 2, 16);
13409 
13410                 WRT16_IO_REG(ha, ctrl_status, 0x50);
13411                 (void) ql_read_regs(ha, fw->dma_reg, ha->iobase + 0x80,
13412                     sizeof (fw->dma_reg) / 2, 16);
13413 
13414                 WRT16_IO_REG(ha, ctrl_status, 0);
13415                 (void) ql_read_regs(ha, fw->risc_hdw_reg, ha->iobase + 0xA0,
13416                     sizeof (fw->risc_hdw_reg) / 2, 16);
13417 
13418                 WRT16_IO_REG(ha, pcr, 0x2000);
13419                 (void) ql_read_regs(ha, fw->risc_gp0_reg, ha->iobase + 0x80,
13420                     sizeof (fw->risc_gp0_reg) / 2, 16);
13421 
13422                 WRT16_IO_REG(ha, pcr, 0x2200);
13423                 (void) ql_read_regs(ha, fw->risc_gp1_reg, ha->iobase + 0x80,
13424                     sizeof (fw->risc_gp1_reg) / 2, 16);
13425 
13426                 WRT16_IO_REG(ha, pcr, 0x2400);
13427                 (void) ql_read_regs(ha, fw->risc_gp2_reg, ha->iobase + 0x80,
13428                     sizeof (fw->risc_gp2_reg) / 2, 16);
13429 
13430                 WRT16_IO_REG(ha, pcr, 0x2600);
13431                 (void) ql_read_regs(ha, fw->risc_gp3_reg, ha->iobase + 0x80,
13432                     sizeof (fw->risc_gp3_reg) / 2, 16);
13433 
13434                 WRT16_IO_REG(ha, pcr, 0x2800);
13435                 (void) ql_read_regs(ha, fw->risc_gp4_reg, ha->iobase + 0x80,
13436                     sizeof (fw->risc_gp4_reg) / 2, 16);
13437 
13438                 WRT16_IO_REG(ha, pcr, 0x2A00);
13439                 (void) ql_read_regs(ha, fw->risc_gp5_reg, ha->iobase + 0x80,
13440                     sizeof (fw->risc_gp5_reg) / 2, 16);
13441 
13442                 WRT16_IO_REG(ha, pcr, 0x2C00);
13443                 (void) ql_read_regs(ha, fw->risc_gp6_reg, ha->iobase + 0x80,
13444                     sizeof (fw->risc_gp6_reg) / 2, 16);
13445 
13446                 WRT16_IO_REG(ha, pcr, 0x2E00);
13447                 (void) ql_read_regs(ha, fw->risc_gp7_reg, ha->iobase + 0x80,
13448                     sizeof (fw->risc_gp7_reg) / 2, 16);
13449 
13450                 WRT16_IO_REG(ha, ctrl_status, 0x10);
13451                 (void) ql_read_regs(ha, fw->frame_buf_hdw_reg,
13452                     ha->iobase + 0x80, sizeof (fw->frame_buf_hdw_reg) / 2, 16);
13453 
13454                 WRT16_IO_REG(ha, ctrl_status, 0x20);
13455                 (void) ql_read_regs(ha, fw->fpm_b0_reg, ha->iobase + 0x80,
13456                     sizeof (fw->fpm_b0_reg) / 2, 16);
13457 
13458                 WRT16_IO_REG(ha, ctrl_status, 0x30);
13459                 (void) ql_read_regs(ha, fw->fpm_b1_reg, ha->iobase + 0x80,
13460                     sizeof (fw->fpm_b1_reg) / 2, 16);
13461 
13462                 /* Select FPM registers. */
13463                 WRT16_IO_REG(ha, ctrl_status, 0x20);
13464 
13465                 /* FPM Soft Reset. */
13466                 WRT16_IO_REG(ha, fpm_diag_config, 0x100);
13467 
13468                 /* Select frame buffer registers. */
13469                 WRT16_IO_REG(ha, ctrl_status, 0x10);
13470 
13471                 /* Reset frame buffer FIFOs. */
13472                 WRT16_IO_REG(ha, fb_cmd, 0xa000);
13473 
13474                 /* Select RISC module registers. */
13475                 WRT16_IO_REG(ha, ctrl_status, 0);
13476 
13477                 /* Reset RISC module. */
13478                 WRT16_IO_REG(ha, hccr, HC_RESET_RISC);
13479 
13480                 /* Reset ISP semaphore. */
13481                 WRT16_IO_REG(ha, semaphore, 0);
13482 
13483                 /* Release RISC module. */
13484                 WRT16_IO_REG(ha, hccr, HC_RELEASE_RISC);
13485 
13486                 /* Wait for RISC to recover from reset. */
13487                 timer = 30000;
13488                 while (RD16_IO_REG(ha, mailbox_out[0]) == MBS_BUSY) {
13489                         if (timer-- != 0) {
13490                                 drv_usecwait(MILLISEC);
13491                         } else {
13492                                 rval = QL_FUNCTION_TIMEOUT;
13493                                 break;
13494                         }
13495                 }
13496 
13497                 /* Disable RISC pause on FPM parity error. */
13498                 WRT16_IO_REG(ha, hccr, HC_DISABLE_PARITY_PAUSE);
13499         }
13500 
13501         /* Get RISC SRAM. */
13502         if (rval == QL_SUCCESS) {
13503                 rval = ql_read_risc_ram(ha, 0x800, 0xf800, fw->risc_ram);
13504         }
13505         /* Get STACK SRAM. */
13506         if (rval == QL_SUCCESS) {
13507                 rval = ql_read_risc_ram(ha, 0x10000, 0x800, fw->stack_ram);
13508         }
13509         /* Get DATA SRAM. */
13510         if (rval == QL_SUCCESS) {
13511                 rval = ql_read_risc_ram(ha, 0x10800, 0xf800, fw->data_ram);
13512         }
13513 
13514         QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
13515 
13516         return (rval);
13517 }
13518 
13519 /*
13520  * ql_24xx_binary_fw_dump
13521  *
13522  * Input:
13523  *      ha:     adapter state pointer.
13524  *      fw:     firmware dump context pointer.
13525  *
13526  * Returns:
13527  *      ql local function return status code.
13528  *
13529  * Context:
13530  *      Interrupt or Kernel context, no mailbox commands allowed.
13531  */
13532 static int
13533 ql_24xx_binary_fw_dump(ql_adapter_state_t *ha, ql_24xx_fw_dump_t *fw)
13534 {
13535         uint32_t        *reg32;
13536         void            *bp;
13537         clock_t         timer;
13538         int             rval = QL_SUCCESS;
13539 
13540         QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
13541 
13542         fw->hccr = RD32_IO_REG(ha, hccr);
13543 
13544         /* Pause RISC. */
13545         if ((RD32_IO_REG(ha, risc2host) & RH_RISC_PAUSED) == 0) {
13546                 /* Disable ISP interrupts. */
13547                 WRT16_IO_REG(ha, ictrl, 0);
13548 
13549                 WRT32_IO_REG(ha, hccr, HC24_PAUSE_RISC);
13550                 for (timer = 30000;
13551                     (RD32_IO_REG(ha, risc2host) & RH_RISC_PAUSED) == 0 &&
13552                     rval == QL_SUCCESS; timer--) {
13553                         if (timer) {
13554                                 drv_usecwait(100);
13555                         } else {
13556                                 rval = QL_FUNCTION_TIMEOUT;
13557                         }
13558                 }
13559         }
13560 
13561         if (rval == QL_SUCCESS) {
13562                 /* Host interface registers. */
13563                 (void) ql_read_regs(ha, fw->host_reg, ha->iobase,
13564                     sizeof (fw->host_reg) / 4, 32);
13565 
13566                 /* Disable ISP interrupts. */
13567                 WRT32_IO_REG(ha, ictrl, 0);
13568                 RD32_IO_REG(ha, ictrl);
13569                 ADAPTER_STATE_LOCK(ha);
13570                 ha->flags &= ~INTERRUPTS_ENABLED;
13571                 ADAPTER_STATE_UNLOCK(ha);
13572 
13573                 /* Shadow registers. */
13574 
13575                 WRT32_IO_REG(ha, io_base_addr, 0x0F70);
13576                 RD32_IO_REG(ha, io_base_addr);
13577 
13578                 reg32 = (uint32_t *)((caddr_t)ha->iobase + 0xF0);
13579                 WRT_REG_DWORD(ha, reg32, 0xB0000000);
13580                 reg32 = (uint32_t *)((caddr_t)ha->iobase + 0xFC);
13581                 fw->shadow_reg[0] = RD_REG_DWORD(ha, reg32);
13582 
13583                 reg32 = (uint32_t *)((caddr_t)ha->iobase + 0xF0);
13584                 WRT_REG_DWORD(ha, reg32, 0xB0100000);
13585                 reg32 = (uint32_t *)((caddr_t)ha->iobase + 0xFC);
13586                 fw->shadow_reg[1] = RD_REG_DWORD(ha, reg32);
13587 
13588                 reg32 = (uint32_t *)((caddr_t)ha->iobase + 0xF0);
13589                 WRT_REG_DWORD(ha, reg32, 0xB0200000);
13590                 reg32 = (uint32_t *)((caddr_t)ha->iobase + 0xFC);
13591                 fw->shadow_reg[2] = RD_REG_DWORD(ha, reg32);
13592 
13593                 reg32 = (uint32_t *)((caddr_t)ha->iobase + 0xF0);
13594                 WRT_REG_DWORD(ha, reg32, 0xB0300000);
13595                 reg32 = (uint32_t *)((caddr_t)ha->iobase + 0xFC);
13596                 fw->shadow_reg[3] = RD_REG_DWORD(ha, reg32);
13597 
13598                 reg32 = (uint32_t *)((caddr_t)ha->iobase + 0xF0);
13599                 WRT_REG_DWORD(ha, reg32, 0xB0400000);
13600                 reg32 = (uint32_t *)((caddr_t)ha->iobase + 0xFC);
13601                 fw->shadow_reg[4] = RD_REG_DWORD(ha, reg32);
13602 
13603                 reg32 = (uint32_t *)((caddr_t)ha->iobase + 0xF0);
13604                 WRT_REG_DWORD(ha, reg32, 0xB0500000);
13605                 reg32 = (uint32_t *)((caddr_t)ha->iobase + 0xFC);
13606                 fw->shadow_reg[5] = RD_REG_DWORD(ha, reg32);
13607 
13608                 reg32 = (uint32_t *)((caddr_t)ha->iobase + 0xF0);
13609                 WRT_REG_DWORD(ha, reg32, 0xB0600000);
13610                 reg32 = (uint32_t *)((caddr_t)ha->iobase + 0xFC);
13611                 fw->shadow_reg[6] = RD_REG_DWORD(ha, reg32);
13612 
13613                 /* Mailbox registers. */
13614                 (void) ql_read_regs(ha, fw->mailbox_reg, ha->iobase + 0x80,
13615                     sizeof (fw->mailbox_reg) / 2, 16);
13616 
13617                 /* Transfer sequence registers. */
13618 
13619                 /* XSEQ GP */
13620                 WRT32_IO_REG(ha, io_base_addr, 0xBF00);
13621                 bp = ql_read_regs(ha, fw->xseq_gp_reg, ha->iobase + 0xC0,
13622                     16, 32);
13623                 WRT32_IO_REG(ha, io_base_addr, 0xBF10);
13624                 bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
13625                 WRT32_IO_REG(ha, io_base_addr, 0xBF20);
13626                 bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
13627                 WRT32_IO_REG(ha, io_base_addr, 0xBF30);
13628                 bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
13629                 WRT32_IO_REG(ha, io_base_addr, 0xBF40);
13630                 bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
13631                 WRT32_IO_REG(ha, io_base_addr, 0xBF50);
13632                 bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
13633                 WRT32_IO_REG(ha, io_base_addr, 0xBF60);
13634                 bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
13635                 WRT32_IO_REG(ha, io_base_addr, 0xBF70);
13636                 (void) ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
13637 
13638                 /* XSEQ-0 */
13639                 WRT32_IO_REG(ha, io_base_addr, 0xBFE0);
13640                 (void) ql_read_regs(ha, fw->xseq_0_reg, ha->iobase + 0xC0,
13641                     sizeof (fw->xseq_0_reg) / 4, 32);
13642 
13643                 /* XSEQ-1 */
13644                 WRT32_IO_REG(ha, io_base_addr, 0xBFF0);
13645                 (void) ql_read_regs(ha, fw->xseq_1_reg, ha->iobase + 0xC0,
13646                     sizeof (fw->xseq_1_reg) / 4, 32);
13647 
13648                 /* Receive sequence registers. */
13649 
13650                 /* RSEQ GP */
13651                 WRT32_IO_REG(ha, io_base_addr, 0xFF00);
13652                 bp = ql_read_regs(ha, fw->rseq_gp_reg, ha->iobase + 0xC0,
13653                     16, 32);
13654                 WRT32_IO_REG(ha, io_base_addr, 0xFF10);
13655                 bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
13656                 WRT32_IO_REG(ha, io_base_addr, 0xFF20);
13657                 bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
13658                 WRT32_IO_REG(ha, io_base_addr, 0xFF30);
13659                 bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
13660                 WRT32_IO_REG(ha, io_base_addr, 0xFF40);
13661                 bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
13662                 WRT32_IO_REG(ha, io_base_addr, 0xFF50);
13663                 bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
13664                 WRT32_IO_REG(ha, io_base_addr, 0xFF60);
13665                 bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
13666                 WRT32_IO_REG(ha, io_base_addr, 0xFF70);
13667                 (void) ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
13668 
13669                 /* RSEQ-0 */
13670                 WRT32_IO_REG(ha, io_base_addr, 0xFFD0);
13671                 (void) ql_read_regs(ha, fw->rseq_0_reg, ha->iobase + 0xC0,
13672                     sizeof (fw->rseq_0_reg) / 4, 32);
13673 
13674                 /* RSEQ-1 */
13675                 WRT32_IO_REG(ha, io_base_addr, 0xFFE0);
13676                 (void) ql_read_regs(ha, fw->rseq_1_reg, ha->iobase + 0xC0,
13677                     sizeof (fw->rseq_1_reg) / 4, 32);
13678 
13679                 /* RSEQ-2 */
13680                 WRT32_IO_REG(ha, io_base_addr, 0xFFF0);
13681                 (void) ql_read_regs(ha, fw->rseq_2_reg, ha->iobase + 0xC0,
13682                     sizeof (fw->rseq_2_reg) / 4, 32);
13683 
13684                 /* Command DMA registers. */
13685 
13686                 WRT32_IO_REG(ha, io_base_addr, 0x7100);
13687                 (void) ql_read_regs(ha, fw->cmd_dma_reg, ha->iobase + 0xC0,
13688                     sizeof (fw->cmd_dma_reg) / 4, 32);
13689 
13690                 /* Queues. */
13691 
13692                 /* RequestQ0 */
13693                 WRT32_IO_REG(ha, io_base_addr, 0x7200);
13694                 bp = ql_read_regs(ha, fw->req0_dma_reg, ha->iobase + 0xC0,
13695                     8, 32);
13696                 (void) ql_read_regs(ha, bp, ha->iobase + 0xE4, 7, 32);
13697 
13698                 /* ResponseQ0 */
13699                 WRT32_IO_REG(ha, io_base_addr, 0x7300);
13700                 bp = ql_read_regs(ha, fw->resp0_dma_reg, ha->iobase + 0xC0,
13701                     8, 32);
13702                 (void) ql_read_regs(ha, bp, ha->iobase + 0xE4, 7, 32);
13703 
13704                 /* RequestQ1 */
13705                 WRT32_IO_REG(ha, io_base_addr, 0x7400);
13706                 bp = ql_read_regs(ha, fw->req1_dma_reg, ha->iobase + 0xC0,
13707                     8, 32);
13708                 (void) ql_read_regs(ha, bp, ha->iobase + 0xE4, 7, 32);
13709 
13710                 /* Transmit DMA registers. */
13711 
13712                 /* XMT0 */
13713                 WRT32_IO_REG(ha, io_base_addr, 0x7600);
13714                 bp = ql_read_regs(ha, fw->xmt0_dma_reg, ha->iobase + 0xC0,
13715                     16, 32);
13716                 WRT32_IO_REG(ha, io_base_addr, 0x7610);
13717                 (void) ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
13718 
13719                 /* XMT1 */
13720                 WRT32_IO_REG(ha, io_base_addr, 0x7620);
13721                 bp = ql_read_regs(ha, fw->xmt1_dma_reg, ha->iobase + 0xC0,
13722                     16, 32);
13723                 WRT32_IO_REG(ha, io_base_addr, 0x7630);
13724                 (void) ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
13725 
13726                 /* XMT2 */
13727                 WRT32_IO_REG(ha, io_base_addr, 0x7640);
13728                 bp = ql_read_regs(ha, fw->xmt2_dma_reg, ha->iobase + 0xC0,
13729                     16, 32);
13730                 WRT32_IO_REG(ha, io_base_addr, 0x7650);
13731                 (void) ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
13732 
13733                 /* XMT3 */
13734                 WRT32_IO_REG(ha, io_base_addr, 0x7660);
13735                 bp = ql_read_regs(ha, fw->xmt3_dma_reg, ha->iobase + 0xC0,
13736                     16, 32);
13737                 WRT32_IO_REG(ha, io_base_addr, 0x7670);
13738                 (void) ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
13739 
13740                 /* XMT4 */
13741                 WRT32_IO_REG(ha, io_base_addr, 0x7680);
13742                 bp = ql_read_regs(ha, fw->xmt4_dma_reg, ha->iobase + 0xC0,
13743                     16, 32);
13744                 WRT32_IO_REG(ha, io_base_addr, 0x7690);
13745                 (void) ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
13746 
13747                 /* XMT Common */
13748                 WRT32_IO_REG(ha, io_base_addr, 0x76A0);
13749                 (void) ql_read_regs(ha, fw->xmt_data_dma_reg,
13750                     ha->iobase + 0xC0, sizeof (fw->xmt_data_dma_reg) / 4, 32);
13751 
13752                 /* Receive DMA registers. */
13753 
13754                 /* RCVThread0 */
13755                 WRT32_IO_REG(ha, io_base_addr, 0x7700);
13756                 bp = ql_read_regs(ha, fw->rcvt0_data_dma_reg,
13757                     ha->iobase + 0xC0, 16, 32);
13758                 WRT32_IO_REG(ha, io_base_addr, 0x7710);
13759                 (void) ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
13760 
13761                 /* RCVThread1 */
13762                 WRT32_IO_REG(ha, io_base_addr, 0x7720);
13763                 bp = ql_read_regs(ha, fw->rcvt1_data_dma_reg,
13764                     ha->iobase + 0xC0, 16, 32);
13765                 WRT32_IO_REG(ha, io_base_addr, 0x7730);
13766                 (void) ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
13767 
13768                 /* RISC registers. */
13769 
13770                 /* RISC GP */
13771                 WRT32_IO_REG(ha, io_base_addr, 0x0F00);
13772                 bp = ql_read_regs(ha, fw->risc_gp_reg, ha->iobase + 0xC0,
13773                     16, 32);
13774                 WRT32_IO_REG(ha, io_base_addr, 0x0F10);
13775                 bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
13776                 WRT32_IO_REG(ha, io_base_addr, 0x0F20);
13777                 bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
13778                 WRT32_IO_REG(ha, io_base_addr, 0x0F30);
13779                 bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
13780                 WRT32_IO_REG(ha, io_base_addr, 0x0F40);
13781                 bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
13782                 WRT32_IO_REG(ha, io_base_addr, 0x0F50);
13783                 bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
13784                 WRT32_IO_REG(ha, io_base_addr, 0x0F60);
13785                 bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
13786                 WRT32_IO_REG(ha, io_base_addr, 0x0F70);
13787                 (void) ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
13788 
13789                 /* Local memory controller registers. */
13790 
13791                 /* LMC */
13792                 WRT32_IO_REG(ha, io_base_addr, 0x3000);
13793                 bp = ql_read_regs(ha, fw->lmc_reg, ha->iobase + 0xC0,
13794                     16, 32);
13795                 WRT32_IO_REG(ha, io_base_addr, 0x3010);
13796                 bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
13797                 WRT32_IO_REG(ha, io_base_addr, 0x3020);
13798                 bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
13799                 WRT32_IO_REG(ha, io_base_addr, 0x3030);
13800                 bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
13801                 WRT32_IO_REG(ha, io_base_addr, 0x3040);
13802                 bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
13803                 WRT32_IO_REG(ha, io_base_addr, 0x3050);
13804                 bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
13805                 WRT32_IO_REG(ha, io_base_addr, 0x3060);
13806                 (void) ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
13807 
13808                 /* Fibre Protocol Module registers. */
13809 
13810                 /* FPM hardware */
13811                 WRT32_IO_REG(ha, io_base_addr, 0x4000);
13812                 bp = ql_read_regs(ha, fw->fpm_hdw_reg, ha->iobase + 0xC0,
13813                     16, 32);
13814                 WRT32_IO_REG(ha, io_base_addr, 0x4010);
13815                 bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
13816                 WRT32_IO_REG(ha, io_base_addr, 0x4020);
13817                 bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
13818                 WRT32_IO_REG(ha, io_base_addr, 0x4030);
13819                 bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
13820                 WRT32_IO_REG(ha, io_base_addr, 0x4040);
13821                 bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
13822                 WRT32_IO_REG(ha, io_base_addr, 0x4050);
13823                 bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
13824                 WRT32_IO_REG(ha, io_base_addr, 0x4060);
13825                 bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
13826                 WRT32_IO_REG(ha, io_base_addr, 0x4070);
13827                 bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
13828                 WRT32_IO_REG(ha, io_base_addr, 0x4080);
13829                 bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
13830                 WRT32_IO_REG(ha, io_base_addr, 0x4090);
13831                 bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
13832                 WRT32_IO_REG(ha, io_base_addr, 0x40A0);
13833                 bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
13834                 WRT32_IO_REG(ha, io_base_addr, 0x40B0);
13835                 (void) ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
13836 
13837                 /* Frame Buffer registers. */
13838 
13839                 /* FB hardware */
13840                 WRT32_IO_REG(ha, io_base_addr, 0x6000);
13841                 bp = ql_read_regs(ha, fw->fb_hdw_reg, ha->iobase + 0xC0,
13842                     16, 32);
13843                 WRT32_IO_REG(ha, io_base_addr, 0x6010);
13844                 bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
13845                 WRT32_IO_REG(ha, io_base_addr, 0x6020);
13846                 bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
13847                 WRT32_IO_REG(ha, io_base_addr, 0x6030);
13848                 bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
13849                 WRT32_IO_REG(ha, io_base_addr, 0x6040);
13850                 bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
13851                 WRT32_IO_REG(ha, io_base_addr, 0x6100);
13852                 bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
13853                 WRT32_IO_REG(ha, io_base_addr, 0x6130);
13854                 bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
13855                 WRT32_IO_REG(ha, io_base_addr, 0x6150);
13856                 bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
13857                 WRT32_IO_REG(ha, io_base_addr, 0x6170);
13858                 bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
13859                 WRT32_IO_REG(ha, io_base_addr, 0x6190);
13860                 bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
13861                 WRT32_IO_REG(ha, io_base_addr, 0x61B0);
13862                 (void) ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
13863         }
13864 
13865         /* Get the request queue */
13866         if (rval == QL_SUCCESS) {
13867                 uint32_t        cnt;
13868                 uint32_t        *w32 = (uint32_t *)ha->request_ring_bp;
13869 
13870                 /* Sync DMA buffer. */
13871                 (void) ddi_dma_sync(ha->hba_buf.dma_handle,
13872                     REQUEST_Q_BUFFER_OFFSET, sizeof (fw->req_q),
13873                     DDI_DMA_SYNC_FORKERNEL);
13874 
13875                 for (cnt = 0; cnt < sizeof (fw->req_q) / 4; cnt++) {
13876                         fw->req_q[cnt] = *w32++;
13877                         LITTLE_ENDIAN_32(&fw->req_q[cnt]);
13878                 }
13879         }
13880 
13881         /* Get the response queue */
13882         if (rval == QL_SUCCESS) {
13883                 uint32_t        cnt;
13884                 uint32_t        *w32 = (uint32_t *)ha->response_ring_bp;
13885 
13886                 /* Sync DMA buffer. */
13887                 (void) ddi_dma_sync(ha->hba_buf.dma_handle,
13888                     RESPONSE_Q_BUFFER_OFFSET, sizeof (fw->rsp_q),
13889                     DDI_DMA_SYNC_FORKERNEL);
13890 
13891                 for (cnt = 0; cnt < sizeof (fw->rsp_q) / 4; cnt++) {
13892                         fw->rsp_q[cnt] = *w32++;
13893                         LITTLE_ENDIAN_32(&fw->rsp_q[cnt]);
13894                 }
13895         }
13896 
13897         /* Reset RISC. */
13898         ql_reset_chip(ha);
13899 
13900         /* Memory. */
13901         if (rval == QL_SUCCESS) {
13902                 /* Code RAM. */
13903                 rval = ql_read_risc_ram(ha, 0x20000,
13904                     sizeof (fw->code_ram) / 4, fw->code_ram);
13905         }
13906         if (rval == QL_SUCCESS) {
13907                 /* External Memory. */
13908                 rval = ql_read_risc_ram(ha, 0x100000,
13909                     ha->fw_ext_memory_size / 4, fw->ext_mem);
13910         }
13911 
13912         /* Get the extended trace buffer */
13913         if (rval == QL_SUCCESS) {
13914                 if (CFG_IST(ha, CFG_ENABLE_FWEXTTRACE) &&
13915                     (ha->fwexttracebuf.bp != NULL)) {
13916                         uint32_t        cnt;
13917                         uint32_t        *w32 = ha->fwexttracebuf.bp;
13918 
13919                         /* Sync DMA buffer. */
13920                         (void) ddi_dma_sync(ha->fwexttracebuf.dma_handle, 0,
13921                             FWEXTSIZE, DDI_DMA_SYNC_FORKERNEL);
13922 
13923                         for (cnt = 0; cnt < FWEXTSIZE / 4; cnt++) {
13924                                 fw->ext_trace_buf[cnt] = *w32++;
13925                         }
13926                 }
13927         }
13928 
13929         /* Get the FC event trace buffer */
13930         if (rval == QL_SUCCESS) {
13931                 if (CFG_IST(ha, CFG_ENABLE_FWFCETRACE) &&
13932                     (ha->fwfcetracebuf.bp != NULL)) {
13933                         uint32_t        cnt;
13934                         uint32_t        *w32 = ha->fwfcetracebuf.bp;
13935 
13936                         /* Sync DMA buffer. */
13937                         (void) ddi_dma_sync(ha->fwfcetracebuf.dma_handle, 0,
13938                             FWFCESIZE, DDI_DMA_SYNC_FORKERNEL);
13939 
13940                         for (cnt = 0; cnt < FWFCESIZE / 4; cnt++) {
13941                                 fw->fce_trace_buf[cnt] = *w32++;
13942                         }
13943                 }
13944         }
13945 
13946         if (rval != QL_SUCCESS) {
13947                 EL(ha, "failed=%xh\n", rval);
13948         } else {
13949                 /*EMPTY*/
13950                 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
13951         }
13952 
13953         return (rval);
13954 }
13955 
13956 /*
13957  * ql_25xx_binary_fw_dump
13958  *
13959  * Input:
13960  *      ha:     adapter state pointer.
13961  *      fw:     firmware dump context pointer.
13962  *
13963  * Returns:
13964  *      ql local function return status code.
13965  *
13966  * Context:
13967  *      Interrupt or Kernel context, no mailbox commands allowed.
13968  */
13969 static int
13970 ql_25xx_binary_fw_dump(ql_adapter_state_t *ha, ql_25xx_fw_dump_t *fw)
13971 {
13972         uint32_t        *reg32;
13973         void            *bp;
13974         clock_t         timer;
13975         int             rval = QL_SUCCESS;
13976 
13977         QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
13978 
13979         fw->r2h_status = RD32_IO_REG(ha, risc2host);
13980 
13981         /* Pause RISC. */
13982         if ((RD32_IO_REG(ha, risc2host) & RH_RISC_PAUSED) == 0) {
13983                 /* Disable ISP interrupts. */
13984                 WRT16_IO_REG(ha, ictrl, 0);
13985 
13986                 WRT32_IO_REG(ha, hccr, HC24_PAUSE_RISC);
13987                 for (timer = 30000;
13988                     (RD32_IO_REG(ha, risc2host) & RH_RISC_PAUSED) == 0 &&
13989                     rval == QL_SUCCESS; timer--) {
13990                         if (timer) {
13991                                 drv_usecwait(100);
13992                                 if (timer % 10000 == 0) {
13993                                         EL(ha, "risc pause %d\n", timer);
13994                                 }
13995                         } else {
13996                                 EL(ha, "risc pause timeout\n");
13997                                 rval = QL_FUNCTION_TIMEOUT;
13998                         }
13999                 }
14000         }
14001 
14002         if (rval == QL_SUCCESS) {
14003 
14004                 /* Host Interface registers */
14005 
14006                 /* HostRisc registers. */
14007                 WRT32_IO_REG(ha, io_base_addr, 0x7000);
14008                 bp = ql_read_regs(ha, fw->hostrisc_reg, ha->iobase + 0xC0,
14009                     16, 32);
14010                 WRT32_IO_REG(ha, io_base_addr, 0x7010);
14011                 bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
14012 
14013                 /* PCIe registers. */
14014                 WRT32_IO_REG(ha, io_base_addr, 0x7c00);
14015                 WRT_REG_DWORD(ha, ha->iobase + 0xc0, 0x1);
14016                 bp = ql_read_regs(ha, fw->pcie_reg, ha->iobase + 0xC4,
14017                     3, 32);
14018                 (void) ql_read_regs(ha, bp, ha->iobase + 0xC0, 1, 32);
14019                 WRT_REG_DWORD(ha, ha->iobase + 0xc0, 0x0);
14020 
14021                 /* Host interface registers. */
14022                 (void) ql_read_regs(ha, fw->host_reg, ha->iobase,
14023                     sizeof (fw->host_reg) / 4, 32);
14024 
14025                 /* Disable ISP interrupts. */
14026 
14027                 WRT32_IO_REG(ha, ictrl, 0);
14028                 RD32_IO_REG(ha, ictrl);
14029                 ADAPTER_STATE_LOCK(ha);
14030                 ha->flags &= ~INTERRUPTS_ENABLED;
14031                 ADAPTER_STATE_UNLOCK(ha);
14032 
14033                 /* Shadow registers. */
14034 
14035                 WRT32_IO_REG(ha, io_base_addr, 0x0F70);
14036                 RD32_IO_REG(ha, io_base_addr);
14037 
14038                 reg32 = (uint32_t *)((caddr_t)ha->iobase + 0xF0);
14039                 WRT_REG_DWORD(ha, reg32, 0xB0000000);
14040                 reg32 = (uint32_t *)((caddr_t)ha->iobase + 0xFC);
14041                 fw->shadow_reg[0] = RD_REG_DWORD(ha, reg32);
14042 
14043                 reg32 = (uint32_t *)((caddr_t)ha->iobase + 0xF0);
14044                 WRT_REG_DWORD(ha, reg32, 0xB0100000);
14045                 reg32 = (uint32_t *)((caddr_t)ha->iobase + 0xFC);
14046                 fw->shadow_reg[1] = RD_REG_DWORD(ha, reg32);
14047 
14048                 reg32 = (uint32_t *)((caddr_t)ha->iobase + 0xF0);
14049                 WRT_REG_DWORD(ha, reg32, 0xB0200000);
14050                 reg32 = (uint32_t *)((caddr_t)ha->iobase + 0xFC);
14051                 fw->shadow_reg[2] = RD_REG_DWORD(ha, reg32);
14052 
14053                 reg32 = (uint32_t *)((caddr_t)ha->iobase + 0xF0);
14054                 WRT_REG_DWORD(ha, reg32, 0xB0300000);
14055                 reg32 = (uint32_t *)((caddr_t)ha->iobase + 0xFC);
14056                 fw->shadow_reg[3] = RD_REG_DWORD(ha, reg32);
14057 
14058                 reg32 = (uint32_t *)((caddr_t)ha->iobase + 0xF0);
14059                 WRT_REG_DWORD(ha, reg32, 0xB0400000);
14060                 reg32 = (uint32_t *)((caddr_t)ha->iobase + 0xFC);
14061                 fw->shadow_reg[4] = RD_REG_DWORD(ha, reg32);
14062 
14063                 reg32 = (uint32_t *)((caddr_t)ha->iobase + 0xF0);
14064                 WRT_REG_DWORD(ha, reg32, 0xB0500000);
14065                 reg32 = (uint32_t *)((caddr_t)ha->iobase + 0xFC);
14066                 fw->shadow_reg[5] = RD_REG_DWORD(ha, reg32);
14067 
14068                 reg32 = (uint32_t *)((caddr_t)ha->iobase + 0xF0);
14069                 WRT_REG_DWORD(ha, reg32, 0xB0600000);
14070                 reg32 = (uint32_t *)((caddr_t)ha->iobase + 0xFC);
14071                 fw->shadow_reg[6] = RD_REG_DWORD(ha, reg32);
14072 
14073                 reg32 = (uint32_t *)((caddr_t)ha->iobase + 0xF0);
14074                 WRT_REG_DWORD(ha, reg32, 0xB0700000);
14075                 reg32 = (uint32_t *)((caddr_t)ha->iobase + 0xFC);
14076                 fw->shadow_reg[7] = RD_REG_DWORD(ha, reg32);
14077 
14078                 reg32 = (uint32_t *)((caddr_t)ha->iobase + 0xF0);
14079                 WRT_REG_DWORD(ha, reg32, 0xB0800000);
14080                 reg32 = (uint32_t *)((caddr_t)ha->iobase + 0xFC);
14081                 fw->shadow_reg[8] = RD_REG_DWORD(ha, reg32);
14082 
14083                 reg32 = (uint32_t *)((caddr_t)ha->iobase + 0xF0);
14084                 WRT_REG_DWORD(ha, reg32, 0xB0900000);
14085                 reg32 = (uint32_t *)((caddr_t)ha->iobase + 0xFC);
14086                 fw->shadow_reg[9] = RD_REG_DWORD(ha, reg32);
14087 
14088                 reg32 = (uint32_t *)((caddr_t)ha->iobase + 0xF0);
14089                 WRT_REG_DWORD(ha, reg32, 0xB0A00000);
14090                 reg32 = (uint32_t *)((caddr_t)ha->iobase + 0xFC);
14091                 fw->shadow_reg[0xa] = RD_REG_DWORD(ha, reg32);
14092 
14093                 /* RISC I/O register. */
14094 
14095                 WRT32_IO_REG(ha, io_base_addr, 0x0010);
14096                 (void) ql_read_regs(ha, &fw->risc_io, ha->iobase + 0xC0,
14097                     1, 32);
14098 
14099                 /* Mailbox registers. */
14100 
14101                 (void) ql_read_regs(ha, fw->mailbox_reg, ha->iobase + 0x80,
14102                     sizeof (fw->mailbox_reg) / 2, 16);
14103 
14104                 /* Transfer sequence registers. */
14105 
14106                 /* XSEQ GP */
14107                 WRT32_IO_REG(ha, io_base_addr, 0xBF00);
14108                 bp = ql_read_regs(ha, fw->xseq_gp_reg, ha->iobase + 0xC0,
14109                     16, 32);
14110                 WRT32_IO_REG(ha, io_base_addr, 0xBF10);
14111                 bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
14112                 WRT32_IO_REG(ha, io_base_addr, 0xBF20);
14113                 bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
14114                 WRT32_IO_REG(ha, io_base_addr, 0xBF30);
14115                 bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
14116                 WRT32_IO_REG(ha, io_base_addr, 0xBF40);
14117                 bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
14118                 WRT32_IO_REG(ha, io_base_addr, 0xBF50);
14119                 bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
14120                 WRT32_IO_REG(ha, io_base_addr, 0xBF60);
14121                 bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
14122                 WRT32_IO_REG(ha, io_base_addr, 0xBF70);
14123                 (void) ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
14124 
14125                 /* XSEQ-0 */
14126                 WRT32_IO_REG(ha, io_base_addr, 0xBFC0);
14127                 bp = ql_read_regs(ha, fw->xseq_0_reg, ha->iobase + 0xC0,
14128                     16, 32);
14129                 WRT32_IO_REG(ha, io_base_addr, 0xBFD0);
14130                 bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
14131                 WRT32_IO_REG(ha, io_base_addr, 0xBFE0);
14132                 (void) ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
14133 
14134                 /* XSEQ-1 */
14135                 WRT32_IO_REG(ha, io_base_addr, 0xBFF0);
14136                 (void) ql_read_regs(ha, fw->xseq_1_reg, ha->iobase + 0xC0,
14137                     16, 32);
14138 
14139                 /* Receive sequence registers. */
14140 
14141                 /* RSEQ GP */
14142                 WRT32_IO_REG(ha, io_base_addr, 0xFF00);
14143                 bp = ql_read_regs(ha, fw->rseq_gp_reg, ha->iobase + 0xC0,
14144                     16, 32);
14145                 WRT32_IO_REG(ha, io_base_addr, 0xFF10);
14146                 bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
14147                 WRT32_IO_REG(ha, io_base_addr, 0xFF20);
14148                 bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
14149                 WRT32_IO_REG(ha, io_base_addr, 0xFF30);
14150                 bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
14151                 WRT32_IO_REG(ha, io_base_addr, 0xFF40);
14152                 bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
14153                 WRT32_IO_REG(ha, io_base_addr, 0xFF50);
14154                 bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
14155                 WRT32_IO_REG(ha, io_base_addr, 0xFF60);
14156                 bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
14157                 WRT32_IO_REG(ha, io_base_addr, 0xFF70);
14158                 (void) ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
14159 
14160                 /* RSEQ-0 */
14161                 WRT32_IO_REG(ha, io_base_addr, 0xFFC0);
14162                 bp = ql_read_regs(ha, fw->rseq_0_reg, ha->iobase + 0xC0,
14163                     16, 32);
14164                 WRT32_IO_REG(ha, io_base_addr, 0xFFD0);
14165                 (void) ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
14166 
14167                 /* RSEQ-1 */
14168                 WRT32_IO_REG(ha, io_base_addr, 0xFFE0);
14169                 (void) ql_read_regs(ha, fw->rseq_1_reg, ha->iobase + 0xC0,
14170                     sizeof (fw->rseq_1_reg) / 4, 32);
14171 
14172                 /* RSEQ-2 */
14173                 WRT32_IO_REG(ha, io_base_addr, 0xFFF0);
14174                 (void) ql_read_regs(ha, fw->rseq_2_reg, ha->iobase + 0xC0,
14175                     sizeof (fw->rseq_2_reg) / 4, 32);
14176 
14177                 /* Auxiliary sequencer registers. */
14178 
14179                 /* ASEQ GP */
14180                 WRT32_IO_REG(ha, io_base_addr, 0xB000);
14181                 bp = ql_read_regs(ha, fw->aseq_gp_reg, ha->iobase + 0xC0,
14182                     16, 32);
14183                 WRT32_IO_REG(ha, io_base_addr, 0xB010);
14184                 bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
14185                 WRT32_IO_REG(ha, io_base_addr, 0xB020);
14186                 bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
14187                 WRT32_IO_REG(ha, io_base_addr, 0xB030);
14188                 bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
14189                 WRT32_IO_REG(ha, io_base_addr, 0xB040);
14190                 bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
14191                 WRT32_IO_REG(ha, io_base_addr, 0xB050);
14192                 bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
14193                 WRT32_IO_REG(ha, io_base_addr, 0xB060);
14194                 bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
14195                 WRT32_IO_REG(ha, io_base_addr, 0xB070);
14196                 (void) ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
14197 
14198                 /* ASEQ-0 */
14199                 WRT32_IO_REG(ha, io_base_addr, 0xB0C0);
14200                 bp = ql_read_regs(ha, fw->aseq_0_reg, ha->iobase + 0xC0,
14201                     16, 32);
14202                 WRT32_IO_REG(ha, io_base_addr, 0xB0D0);
14203                 (void) ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
14204 
14205                 /* ASEQ-1 */
14206                 WRT32_IO_REG(ha, io_base_addr, 0xB0E0);
14207                 (void) ql_read_regs(ha, fw->aseq_1_reg, ha->iobase + 0xC0,
14208                     16, 32);
14209 
14210                 /* ASEQ-2 */
14211                 WRT32_IO_REG(ha, io_base_addr, 0xB0F0);
14212                 (void) ql_read_regs(ha, fw->aseq_2_reg, ha->iobase + 0xC0,
14213                     16, 32);
14214 
14215                 /* Command DMA registers. */
14216 
14217                 WRT32_IO_REG(ha, io_base_addr, 0x7100);
14218                 (void) ql_read_regs(ha, fw->cmd_dma_reg, ha->iobase + 0xC0,
14219                     sizeof (fw->cmd_dma_reg) / 4, 32);
14220 
14221                 /* Queues. */
14222 
14223                 /* RequestQ0 */
14224                 WRT32_IO_REG(ha, io_base_addr, 0x7200);
14225                 bp = ql_read_regs(ha, fw->req0_dma_reg, ha->iobase + 0xC0,
14226                     8, 32);
14227                 (void) ql_read_regs(ha, bp, ha->iobase + 0xE4, 7, 32);
14228 
14229                 /* ResponseQ0 */
14230                 WRT32_IO_REG(ha, io_base_addr, 0x7300);
14231                 bp = ql_read_regs(ha, fw->resp0_dma_reg, ha->iobase + 0xC0,
14232                     8, 32);
14233                 (void) ql_read_regs(ha, bp, ha->iobase + 0xE4, 7, 32);
14234 
14235                 /* RequestQ1 */
14236                 WRT32_IO_REG(ha, io_base_addr, 0x7400);
14237                 bp = ql_read_regs(ha, fw->req1_dma_reg, ha->iobase + 0xC0,
14238                     8, 32);
14239                 (void) ql_read_regs(ha, bp, ha->iobase + 0xE4, 7, 32);
14240 
14241                 /* Transmit DMA registers. */
14242 
14243                 /* XMT0 */
14244                 WRT32_IO_REG(ha, io_base_addr, 0x7600);
14245                 bp = ql_read_regs(ha, fw->xmt0_dma_reg, ha->iobase + 0xC0,
14246                     16, 32);
14247                 WRT32_IO_REG(ha, io_base_addr, 0x7610);
14248                 (void) ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
14249 
14250                 /* XMT1 */
14251                 WRT32_IO_REG(ha, io_base_addr, 0x7620);
14252                 bp = ql_read_regs(ha, fw->xmt1_dma_reg, ha->iobase + 0xC0,
14253                     16, 32);
14254                 WRT32_IO_REG(ha, io_base_addr, 0x7630);
14255                 (void) ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
14256 
14257                 /* XMT2 */
14258                 WRT32_IO_REG(ha, io_base_addr, 0x7640);
14259                 bp = ql_read_regs(ha, fw->xmt2_dma_reg, ha->iobase + 0xC0,
14260                     16, 32);
14261                 WRT32_IO_REG(ha, io_base_addr, 0x7650);
14262                 (void) ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
14263 
14264                 /* XMT3 */
14265                 WRT32_IO_REG(ha, io_base_addr, 0x7660);
14266                 bp = ql_read_regs(ha, fw->xmt3_dma_reg, ha->iobase + 0xC0,
14267                     16, 32);
14268                 WRT32_IO_REG(ha, io_base_addr, 0x7670);
14269                 (void) ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
14270 
14271                 /* XMT4 */
14272                 WRT32_IO_REG(ha, io_base_addr, 0x7680);
14273                 bp = ql_read_regs(ha, fw->xmt4_dma_reg, ha->iobase + 0xC0,
14274                     16, 32);
14275                 WRT32_IO_REG(ha, io_base_addr, 0x7690);
14276                 (void) ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
14277 
14278                 /* XMT Common */
14279                 WRT32_IO_REG(ha, io_base_addr, 0x76A0);
14280                 (void) ql_read_regs(ha, fw->xmt_data_dma_reg,
14281                     ha->iobase + 0xC0, sizeof (fw->xmt_data_dma_reg) / 4, 32);
14282 
14283                 /* Receive DMA registers. */
14284 
14285                 /* RCVThread0 */
14286                 WRT32_IO_REG(ha, io_base_addr, 0x7700);
14287                 bp = ql_read_regs(ha, fw->rcvt0_data_dma_reg,
14288                     ha->iobase + 0xC0, 16, 32);
14289                 WRT32_IO_REG(ha, io_base_addr, 0x7710);
14290                 (void) ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
14291 
14292                 /* RCVThread1 */
14293                 WRT32_IO_REG(ha, io_base_addr, 0x7720);
14294                 bp = ql_read_regs(ha, fw->rcvt1_data_dma_reg,
14295                     ha->iobase + 0xC0, 16, 32);
14296                 WRT32_IO_REG(ha, io_base_addr, 0x7730);
14297                 (void) ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
14298 
14299                 /* RISC registers. */
14300 
14301                 /* RISC GP */
14302                 WRT32_IO_REG(ha, io_base_addr, 0x0F00);
14303                 bp = ql_read_regs(ha, fw->risc_gp_reg, ha->iobase + 0xC0,
14304                     16, 32);
14305                 WRT32_IO_REG(ha, io_base_addr, 0x0F10);
14306                 bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
14307                 WRT32_IO_REG(ha, io_base_addr, 0x0F20);
14308                 bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
14309                 WRT32_IO_REG(ha, io_base_addr, 0x0F30);
14310                 bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
14311                 WRT32_IO_REG(ha, io_base_addr, 0x0F40);
14312                 bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
14313                 WRT32_IO_REG(ha, io_base_addr, 0x0F50);
14314                 bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
14315                 WRT32_IO_REG(ha, io_base_addr, 0x0F60);
14316                 bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
14317                 WRT32_IO_REG(ha, io_base_addr, 0x0F70);
14318                 (void) ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
14319 
14320                 /* Local memory controller (LMC) registers. */
14321 
14322                 /* LMC */
14323                 WRT32_IO_REG(ha, io_base_addr, 0x3000);
14324                 bp = ql_read_regs(ha, fw->lmc_reg, ha->iobase + 0xC0,
14325                     16, 32);
14326                 WRT32_IO_REG(ha, io_base_addr, 0x3010);
14327                 bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
14328                 WRT32_IO_REG(ha, io_base_addr, 0x3020);
14329                 bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
14330                 WRT32_IO_REG(ha, io_base_addr, 0x3030);
14331                 bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
14332                 WRT32_IO_REG(ha, io_base_addr, 0x3040);
14333                 bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
14334                 WRT32_IO_REG(ha, io_base_addr, 0x3050);
14335                 bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
14336                 WRT32_IO_REG(ha, io_base_addr, 0x3060);
14337                 bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
14338                 WRT32_IO_REG(ha, io_base_addr, 0x3070);
14339                 (void) ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
14340 
14341                 /* Fibre Protocol Module registers. */
14342 
14343                 /* FPM hardware */
14344                 WRT32_IO_REG(ha, io_base_addr, 0x4000);
14345                 bp = ql_read_regs(ha, fw->fpm_hdw_reg, ha->iobase + 0xC0,
14346                     16, 32);
14347                 WRT32_IO_REG(ha, io_base_addr, 0x4010);
14348                 bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
14349                 WRT32_IO_REG(ha, io_base_addr, 0x4020);
14350                 bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
14351                 WRT32_IO_REG(ha, io_base_addr, 0x4030);
14352                 bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
14353                 WRT32_IO_REG(ha, io_base_addr, 0x4040);
14354                 bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
14355                 WRT32_IO_REG(ha, io_base_addr, 0x4050);
14356                 bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
14357                 WRT32_IO_REG(ha, io_base_addr, 0x4060);
14358                 bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
14359                 WRT32_IO_REG(ha, io_base_addr, 0x4070);
14360                 bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
14361                 WRT32_IO_REG(ha, io_base_addr, 0x4080);
14362                 bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
14363                 WRT32_IO_REG(ha, io_base_addr, 0x4090);
14364                 bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
14365                 WRT32_IO_REG(ha, io_base_addr, 0x40A0);
14366                 bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
14367                 WRT32_IO_REG(ha, io_base_addr, 0x40B0);
14368                 (void) ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
14369 
14370                 /* Frame Buffer registers. */
14371 
14372                 /* FB hardware */
14373                 WRT32_IO_REG(ha, io_base_addr, 0x6000);
14374                 bp = ql_read_regs(ha, fw->fb_hdw_reg, ha->iobase + 0xC0,
14375                     16, 32);
14376                 WRT32_IO_REG(ha, io_base_addr, 0x6010);
14377                 bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
14378                 WRT32_IO_REG(ha, io_base_addr, 0x6020);
14379                 bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
14380                 WRT32_IO_REG(ha, io_base_addr, 0x6030);
14381                 bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
14382                 WRT32_IO_REG(ha, io_base_addr, 0x6040);
14383                 bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
14384                 WRT32_IO_REG(ha, io_base_addr, 0x6100);
14385                 bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
14386                 WRT32_IO_REG(ha, io_base_addr, 0x6130);
14387                 bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
14388                 WRT32_IO_REG(ha, io_base_addr, 0x6150);
14389                 bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
14390                 WRT32_IO_REG(ha, io_base_addr, 0x6170);
14391                 bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
14392                 WRT32_IO_REG(ha, io_base_addr, 0x6190);
14393                 bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
14394                 WRT32_IO_REG(ha, io_base_addr, 0x61B0);
14395                 bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
14396                 WRT32_IO_REG(ha, io_base_addr, 0x6F00);
14397                 (void) ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
14398         }
14399 
14400         /* Get the request queue */
14401         if (rval == QL_SUCCESS) {
14402                 uint32_t        cnt;
14403                 uint32_t        *w32 = (uint32_t *)ha->request_ring_bp;
14404 
14405                 /* Sync DMA buffer. */
14406                 (void) ddi_dma_sync(ha->hba_buf.dma_handle,
14407                     REQUEST_Q_BUFFER_OFFSET, sizeof (fw->req_q),
14408                     DDI_DMA_SYNC_FORKERNEL);
14409 
14410                 for (cnt = 0; cnt < sizeof (fw->req_q) / 4; cnt++) {
14411                         fw->req_q[cnt] = *w32++;
14412                         LITTLE_ENDIAN_32(&fw->req_q[cnt]);
14413                 }
14414         }
14415 
14416         /* Get the respons queue */
14417         if (rval == QL_SUCCESS) {
14418                 uint32_t        cnt;
14419                 uint32_t        *w32 = (uint32_t *)ha->response_ring_bp;
14420 
14421                 /* Sync DMA buffer. */
14422                 (void) ddi_dma_sync(ha->hba_buf.dma_handle,
14423                     RESPONSE_Q_BUFFER_OFFSET, sizeof (fw->rsp_q),
14424                     DDI_DMA_SYNC_FORKERNEL);
14425 
14426                 for (cnt = 0; cnt < sizeof (fw->rsp_q) / 4; cnt++) {
14427                         fw->rsp_q[cnt] = *w32++;
14428                         LITTLE_ENDIAN_32(&fw->rsp_q[cnt]);
14429                 }
14430         }
14431 
14432         /* Reset RISC. */
14433 
14434         ql_reset_chip(ha);
14435 
14436         /* Memory. */
14437 
14438         if (rval == QL_SUCCESS) {
14439                 /* Code RAM. */
14440                 rval = ql_read_risc_ram(ha, 0x20000,
14441                     sizeof (fw->code_ram) / 4, fw->code_ram);
14442         }
14443         if (rval == QL_SUCCESS) {
14444                 /* External Memory. */
14445                 rval = ql_read_risc_ram(ha, 0x100000,
14446                     ha->fw_ext_memory_size / 4, fw->ext_mem);
14447         }
14448 
14449         /* Get the FC event trace buffer */
14450         if (rval == QL_SUCCESS) {
14451                 if (CFG_IST(ha, CFG_ENABLE_FWFCETRACE) &&
14452                     (ha->fwfcetracebuf.bp != NULL)) {
14453                         uint32_t        cnt;
14454                         uint32_t        *w32 = ha->fwfcetracebuf.bp;
14455 
14456                         /* Sync DMA buffer. */
14457                         (void) ddi_dma_sync(ha->fwfcetracebuf.dma_handle, 0,
14458                             FWFCESIZE, DDI_DMA_SYNC_FORKERNEL);
14459 
14460                         for (cnt = 0; cnt < FWFCESIZE / 4; cnt++) {
14461                                 fw->fce_trace_buf[cnt] = *w32++;
14462                         }
14463                 }
14464         }
14465 
14466         /* Get the extended trace buffer */
14467         if (rval == QL_SUCCESS) {
14468                 if (CFG_IST(ha, CFG_ENABLE_FWEXTTRACE) &&
14469                     (ha->fwexttracebuf.bp != NULL)) {
14470                         uint32_t        cnt;
14471                         uint32_t        *w32 = ha->fwexttracebuf.bp;
14472 
14473                         /* Sync DMA buffer. */
14474                         (void) ddi_dma_sync(ha->fwexttracebuf.dma_handle, 0,
14475                             FWEXTSIZE, DDI_DMA_SYNC_FORKERNEL);
14476 
14477                         for (cnt = 0; cnt < FWEXTSIZE / 4; cnt++) {
14478                                 fw->ext_trace_buf[cnt] = *w32++;
14479                         }
14480                 }
14481         }
14482 
14483         if (rval != QL_SUCCESS) {
14484                 EL(ha, "failed=%xh\n", rval);
14485         } else {
14486                 /*EMPTY*/
14487                 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
14488         }
14489 
14490         return (rval);
14491 }
14492 
14493 /*
14494  * ql_81xx_binary_fw_dump
14495  *
14496  * Input:
14497  *      ha:     adapter state pointer.
14498  *      fw:     firmware dump context pointer.
14499  *
14500  * Returns:
14501  *      ql local function return status code.
14502  *
14503  * Context:
14504  *      Interrupt or Kernel context, no mailbox commands allowed.
14505  */
14506 static int
14507 ql_81xx_binary_fw_dump(ql_adapter_state_t *ha, ql_81xx_fw_dump_t *fw)
14508 {
14509         uint32_t        *reg32;
14510         void            *bp;
14511         clock_t         timer;
14512         int             rval = QL_SUCCESS;
14513 
14514         QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
14515 
14516         fw->r2h_status = RD32_IO_REG(ha, risc2host);
14517 
14518         /* Pause RISC. */
14519         if ((RD32_IO_REG(ha, risc2host) & RH_RISC_PAUSED) == 0) {
14520                 /* Disable ISP interrupts. */
14521                 WRT16_IO_REG(ha, ictrl, 0);
14522 
14523                 WRT32_IO_REG(ha, hccr, HC24_PAUSE_RISC);
14524                 for (timer = 30000;
14525                     (RD32_IO_REG(ha, risc2host) & RH_RISC_PAUSED) == 0 &&
14526                     rval == QL_SUCCESS; timer--) {
14527                         if (timer) {
14528                                 drv_usecwait(100);
14529                                 if (timer % 10000 == 0) {
14530                                         EL(ha, "risc pause %d\n", timer);
14531                                 }
14532                         } else {
14533                                 EL(ha, "risc pause timeout\n");
14534                                 rval = QL_FUNCTION_TIMEOUT;
14535                         }
14536                 }
14537         }
14538 
14539         if (rval == QL_SUCCESS) {
14540 
14541                 /* Host Interface registers */
14542 
14543                 /* HostRisc registers. */
14544                 WRT32_IO_REG(ha, io_base_addr, 0x7000);
14545                 bp = ql_read_regs(ha, fw->hostrisc_reg, ha->iobase + 0xC0,
14546                     16, 32);
14547                 WRT32_IO_REG(ha, io_base_addr, 0x7010);
14548                 bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
14549 
14550                 /* PCIe registers. */
14551                 WRT32_IO_REG(ha, io_base_addr, 0x7c00);
14552                 WRT_REG_DWORD(ha, ha->iobase + 0xc0, 0x1);
14553                 bp = ql_read_regs(ha, fw->pcie_reg, ha->iobase + 0xC4,
14554                     3, 32);
14555                 (void) ql_read_regs(ha, bp, ha->iobase + 0xC0, 1, 32);
14556                 WRT_REG_DWORD(ha, ha->iobase + 0xc0, 0x0);
14557 
14558                 /* Host interface registers. */
14559                 (void) ql_read_regs(ha, fw->host_reg, ha->iobase,
14560                     sizeof (fw->host_reg) / 4, 32);
14561 
14562                 /* Disable ISP interrupts. */
14563 
14564                 WRT32_IO_REG(ha, ictrl, 0);
14565                 RD32_IO_REG(ha, ictrl);
14566                 ADAPTER_STATE_LOCK(ha);
14567                 ha->flags &= ~INTERRUPTS_ENABLED;
14568                 ADAPTER_STATE_UNLOCK(ha);
14569 
14570                 /* Shadow registers. */
14571 
14572                 WRT32_IO_REG(ha, io_base_addr, 0x0F70);
14573                 RD32_IO_REG(ha, io_base_addr);
14574 
14575                 reg32 = (uint32_t *)((caddr_t)ha->iobase + 0xF0);
14576                 WRT_REG_DWORD(ha, reg32, 0xB0000000);
14577                 reg32 = (uint32_t *)((caddr_t)ha->iobase + 0xFC);
14578                 fw->shadow_reg[0] = RD_REG_DWORD(ha, reg32);
14579 
14580                 reg32 = (uint32_t *)((caddr_t)ha->iobase + 0xF0);
14581                 WRT_REG_DWORD(ha, reg32, 0xB0100000);
14582                 reg32 = (uint32_t *)((caddr_t)ha->iobase + 0xFC);
14583                 fw->shadow_reg[1] = RD_REG_DWORD(ha, reg32);
14584 
14585                 reg32 = (uint32_t *)((caddr_t)ha->iobase + 0xF0);
14586                 WRT_REG_DWORD(ha, reg32, 0xB0200000);
14587                 reg32 = (uint32_t *)((caddr_t)ha->iobase + 0xFC);
14588                 fw->shadow_reg[2] = RD_REG_DWORD(ha, reg32);
14589 
14590                 reg32 = (uint32_t *)((caddr_t)ha->iobase + 0xF0);
14591                 WRT_REG_DWORD(ha, reg32, 0xB0300000);
14592                 reg32 = (uint32_t *)((caddr_t)ha->iobase + 0xFC);
14593                 fw->shadow_reg[3] = RD_REG_DWORD(ha, reg32);
14594 
14595                 reg32 = (uint32_t *)((caddr_t)ha->iobase + 0xF0);
14596                 WRT_REG_DWORD(ha, reg32, 0xB0400000);
14597                 reg32 = (uint32_t *)((caddr_t)ha->iobase + 0xFC);
14598                 fw->shadow_reg[4] = RD_REG_DWORD(ha, reg32);
14599 
14600                 reg32 = (uint32_t *)((caddr_t)ha->iobase + 0xF0);
14601                 WRT_REG_DWORD(ha, reg32, 0xB0500000);
14602                 reg32 = (uint32_t *)((caddr_t)ha->iobase + 0xFC);
14603                 fw->shadow_reg[5] = RD_REG_DWORD(ha, reg32);
14604 
14605                 reg32 = (uint32_t *)((caddr_t)ha->iobase + 0xF0);
14606                 WRT_REG_DWORD(ha, reg32, 0xB0600000);
14607                 reg32 = (uint32_t *)((caddr_t)ha->iobase + 0xFC);
14608                 fw->shadow_reg[6] = RD_REG_DWORD(ha, reg32);
14609 
14610                 reg32 = (uint32_t *)((caddr_t)ha->iobase + 0xF0);
14611                 WRT_REG_DWORD(ha, reg32, 0xB0700000);
14612                 reg32 = (uint32_t *)((caddr_t)ha->iobase + 0xFC);
14613                 fw->shadow_reg[7] = RD_REG_DWORD(ha, reg32);
14614 
14615                 reg32 = (uint32_t *)((caddr_t)ha->iobase + 0xF0);
14616                 WRT_REG_DWORD(ha, reg32, 0xB0800000);
14617                 reg32 = (uint32_t *)((caddr_t)ha->iobase + 0xFC);
14618                 fw->shadow_reg[8] = RD_REG_DWORD(ha, reg32);
14619 
14620                 reg32 = (uint32_t *)((caddr_t)ha->iobase + 0xF0);
14621                 WRT_REG_DWORD(ha, reg32, 0xB0900000);
14622                 reg32 = (uint32_t *)((caddr_t)ha->iobase + 0xFC);
14623                 fw->shadow_reg[9] = RD_REG_DWORD(ha, reg32);
14624 
14625                 reg32 = (uint32_t *)((caddr_t)ha->iobase + 0xF0);
14626                 WRT_REG_DWORD(ha, reg32, 0xB0A00000);
14627                 reg32 = (uint32_t *)((caddr_t)ha->iobase + 0xFC);
14628                 fw->shadow_reg[0xa] = RD_REG_DWORD(ha, reg32);
14629 
14630                 /* RISC I/O register. */
14631 
14632                 WRT32_IO_REG(ha, io_base_addr, 0x0010);
14633                 (void) ql_read_regs(ha, &fw->risc_io, ha->iobase + 0xC0,
14634                     1, 32);
14635 
14636                 /* Mailbox registers. */
14637 
14638                 (void) ql_read_regs(ha, fw->mailbox_reg, ha->iobase + 0x80,
14639                     sizeof (fw->mailbox_reg) / 2, 16);
14640 
14641                 /* Transfer sequence registers. */
14642 
14643                 /* XSEQ GP */
14644                 WRT32_IO_REG(ha, io_base_addr, 0xBF00);
14645                 bp = ql_read_regs(ha, fw->xseq_gp_reg, ha->iobase + 0xC0,
14646                     16, 32);
14647                 WRT32_IO_REG(ha, io_base_addr, 0xBF10);
14648                 bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
14649                 WRT32_IO_REG(ha, io_base_addr, 0xBF20);
14650                 bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
14651                 WRT32_IO_REG(ha, io_base_addr, 0xBF30);
14652                 bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
14653                 WRT32_IO_REG(ha, io_base_addr, 0xBF40);
14654                 bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
14655                 WRT32_IO_REG(ha, io_base_addr, 0xBF50);
14656                 bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
14657                 WRT32_IO_REG(ha, io_base_addr, 0xBF60);
14658                 bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
14659                 WRT32_IO_REG(ha, io_base_addr, 0xBF70);
14660                 (void) ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
14661 
14662                 /* XSEQ-0 */
14663                 WRT32_IO_REG(ha, io_base_addr, 0xBFC0);
14664                 bp = ql_read_regs(ha, fw->xseq_0_reg, ha->iobase + 0xC0,
14665                     16, 32);
14666                 WRT32_IO_REG(ha, io_base_addr, 0xBFD0);
14667                 bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
14668                 WRT32_IO_REG(ha, io_base_addr, 0xBFE0);
14669                 (void) ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
14670 
14671                 /* XSEQ-1 */
14672                 WRT32_IO_REG(ha, io_base_addr, 0xBFF0);
14673                 (void) ql_read_regs(ha, fw->xseq_1_reg, ha->iobase + 0xC0,
14674                     16, 32);
14675 
14676                 /* Receive sequence registers. */
14677 
14678                 /* RSEQ GP */
14679                 WRT32_IO_REG(ha, io_base_addr, 0xFF00);
14680                 bp = ql_read_regs(ha, fw->rseq_gp_reg, ha->iobase + 0xC0,
14681                     16, 32);
14682                 WRT32_IO_REG(ha, io_base_addr, 0xFF10);
14683                 bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
14684                 WRT32_IO_REG(ha, io_base_addr, 0xFF20);
14685                 bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
14686                 WRT32_IO_REG(ha, io_base_addr, 0xFF30);
14687                 bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
14688                 WRT32_IO_REG(ha, io_base_addr, 0xFF40);
14689                 bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
14690                 WRT32_IO_REG(ha, io_base_addr, 0xFF50);
14691                 bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
14692                 WRT32_IO_REG(ha, io_base_addr, 0xFF60);
14693                 bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
14694                 WRT32_IO_REG(ha, io_base_addr, 0xFF70);
14695                 (void) ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
14696 
14697                 /* RSEQ-0 */
14698                 WRT32_IO_REG(ha, io_base_addr, 0xFFC0);
14699                 bp = ql_read_regs(ha, fw->rseq_0_reg, ha->iobase + 0xC0,
14700                     16, 32);
14701                 WRT32_IO_REG(ha, io_base_addr, 0xFFD0);
14702                 (void) ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
14703 
14704                 /* RSEQ-1 */
14705                 WRT32_IO_REG(ha, io_base_addr, 0xFFE0);
14706                 (void) ql_read_regs(ha, fw->rseq_1_reg, ha->iobase + 0xC0,
14707                     sizeof (fw->rseq_1_reg) / 4, 32);
14708 
14709                 /* RSEQ-2 */
14710                 WRT32_IO_REG(ha, io_base_addr, 0xFFF0);
14711                 (void) ql_read_regs(ha, fw->rseq_2_reg, ha->iobase + 0xC0,
14712                     sizeof (fw->rseq_2_reg) / 4, 32);
14713 
14714                 /* Auxiliary sequencer registers. */
14715 
14716                 /* ASEQ GP */
14717                 WRT32_IO_REG(ha, io_base_addr, 0xB000);
14718                 bp = ql_read_regs(ha, fw->aseq_gp_reg, ha->iobase + 0xC0,
14719                     16, 32);
14720                 WRT32_IO_REG(ha, io_base_addr, 0xB010);
14721                 bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
14722                 WRT32_IO_REG(ha, io_base_addr, 0xB020);
14723                 bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
14724                 WRT32_IO_REG(ha, io_base_addr, 0xB030);
14725                 bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
14726                 WRT32_IO_REG(ha, io_base_addr, 0xB040);
14727                 bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
14728                 WRT32_IO_REG(ha, io_base_addr, 0xB050);
14729                 bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
14730                 WRT32_IO_REG(ha, io_base_addr, 0xB060);
14731                 bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
14732                 WRT32_IO_REG(ha, io_base_addr, 0xB070);
14733                 (void) ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
14734 
14735                 /* ASEQ-0 */
14736                 WRT32_IO_REG(ha, io_base_addr, 0xB0C0);
14737                 bp = ql_read_regs(ha, fw->aseq_0_reg, ha->iobase + 0xC0,
14738                     16, 32);
14739                 WRT32_IO_REG(ha, io_base_addr, 0xB0D0);
14740                 (void) ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
14741 
14742                 /* ASEQ-1 */
14743                 WRT32_IO_REG(ha, io_base_addr, 0xB0E0);
14744                 (void) ql_read_regs(ha, fw->aseq_1_reg, ha->iobase + 0xC0,
14745                     16, 32);
14746 
14747                 /* ASEQ-2 */
14748                 WRT32_IO_REG(ha, io_base_addr, 0xB0F0);
14749                 (void) ql_read_regs(ha, fw->aseq_2_reg, ha->iobase + 0xC0,
14750                     16, 32);
14751 
14752                 /* Command DMA registers. */
14753 
14754                 WRT32_IO_REG(ha, io_base_addr, 0x7100);
14755                 (void) ql_read_regs(ha, fw->cmd_dma_reg, ha->iobase + 0xC0,
14756                     sizeof (fw->cmd_dma_reg) / 4, 32);
14757 
14758                 /* Queues. */
14759 
14760                 /* RequestQ0 */
14761                 WRT32_IO_REG(ha, io_base_addr, 0x7200);
14762                 bp = ql_read_regs(ha, fw->req0_dma_reg, ha->iobase + 0xC0,
14763                     8, 32);
14764                 (void) ql_read_regs(ha, bp, ha->iobase + 0xE4, 7, 32);
14765 
14766                 /* ResponseQ0 */
14767                 WRT32_IO_REG(ha, io_base_addr, 0x7300);
14768                 bp = ql_read_regs(ha, fw->resp0_dma_reg, ha->iobase + 0xC0,
14769                     8, 32);
14770                 (void) ql_read_regs(ha, bp, ha->iobase + 0xE4, 7, 32);
14771 
14772                 /* RequestQ1 */
14773                 WRT32_IO_REG(ha, io_base_addr, 0x7400);
14774                 bp = ql_read_regs(ha, fw->req1_dma_reg, ha->iobase + 0xC0,
14775                     8, 32);
14776                 (void) ql_read_regs(ha, bp, ha->iobase + 0xE4, 7, 32);
14777 
14778                 /* Transmit DMA registers. */
14779 
14780                 /* XMT0 */
14781                 WRT32_IO_REG(ha, io_base_addr, 0x7600);
14782                 bp = ql_read_regs(ha, fw->xmt0_dma_reg, ha->iobase + 0xC0,
14783                     16, 32);
14784                 WRT32_IO_REG(ha, io_base_addr, 0x7610);
14785                 (void) ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
14786 
14787                 /* XMT1 */
14788                 WRT32_IO_REG(ha, io_base_addr, 0x7620);
14789                 bp = ql_read_regs(ha, fw->xmt1_dma_reg, ha->iobase + 0xC0,
14790                     16, 32);
14791                 WRT32_IO_REG(ha, io_base_addr, 0x7630);
14792                 (void) ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
14793 
14794                 /* XMT2 */
14795                 WRT32_IO_REG(ha, io_base_addr, 0x7640);
14796                 bp = ql_read_regs(ha, fw->xmt2_dma_reg, ha->iobase + 0xC0,
14797                     16, 32);
14798                 WRT32_IO_REG(ha, io_base_addr, 0x7650);
14799                 (void) ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
14800 
14801                 /* XMT3 */
14802                 WRT32_IO_REG(ha, io_base_addr, 0x7660);
14803                 bp = ql_read_regs(ha, fw->xmt3_dma_reg, ha->iobase + 0xC0,
14804                     16, 32);
14805                 WRT32_IO_REG(ha, io_base_addr, 0x7670);
14806                 (void) ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
14807 
14808                 /* XMT4 */
14809                 WRT32_IO_REG(ha, io_base_addr, 0x7680);
14810                 bp = ql_read_regs(ha, fw->xmt4_dma_reg, ha->iobase + 0xC0,
14811                     16, 32);
14812                 WRT32_IO_REG(ha, io_base_addr, 0x7690);
14813                 (void) ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
14814 
14815                 /* XMT Common */
14816                 WRT32_IO_REG(ha, io_base_addr, 0x76A0);
14817                 (void) ql_read_regs(ha, fw->xmt_data_dma_reg,
14818                     ha->iobase + 0xC0, sizeof (fw->xmt_data_dma_reg) / 4, 32);
14819 
14820                 /* Receive DMA registers. */
14821 
14822                 /* RCVThread0 */
14823                 WRT32_IO_REG(ha, io_base_addr, 0x7700);
14824                 bp = ql_read_regs(ha, fw->rcvt0_data_dma_reg,
14825                     ha->iobase + 0xC0, 16, 32);
14826                 WRT32_IO_REG(ha, io_base_addr, 0x7710);
14827                 (void) ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
14828 
14829                 /* RCVThread1 */
14830                 WRT32_IO_REG(ha, io_base_addr, 0x7720);
14831                 bp = ql_read_regs(ha, fw->rcvt1_data_dma_reg,
14832                     ha->iobase + 0xC0, 16, 32);
14833                 WRT32_IO_REG(ha, io_base_addr, 0x7730);
14834                 (void) ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
14835 
14836                 /* RISC registers. */
14837 
14838                 /* RISC GP */
14839                 WRT32_IO_REG(ha, io_base_addr, 0x0F00);
14840                 bp = ql_read_regs(ha, fw->risc_gp_reg, ha->iobase + 0xC0,
14841                     16, 32);
14842                 WRT32_IO_REG(ha, io_base_addr, 0x0F10);
14843                 bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
14844                 WRT32_IO_REG(ha, io_base_addr, 0x0F20);
14845                 bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
14846                 WRT32_IO_REG(ha, io_base_addr, 0x0F30);
14847                 bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
14848                 WRT32_IO_REG(ha, io_base_addr, 0x0F40);
14849                 bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
14850                 WRT32_IO_REG(ha, io_base_addr, 0x0F50);
14851                 bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
14852                 WRT32_IO_REG(ha, io_base_addr, 0x0F60);
14853                 bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
14854                 WRT32_IO_REG(ha, io_base_addr, 0x0F70);
14855                 (void) ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
14856 
14857                 /* Local memory controller (LMC) registers. */
14858 
14859                 /* LMC */
14860                 WRT32_IO_REG(ha, io_base_addr, 0x3000);
14861                 bp = ql_read_regs(ha, fw->lmc_reg, ha->iobase + 0xC0,
14862                     16, 32);
14863                 WRT32_IO_REG(ha, io_base_addr, 0x3010);
14864                 bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
14865                 WRT32_IO_REG(ha, io_base_addr, 0x3020);
14866                 bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
14867                 WRT32_IO_REG(ha, io_base_addr, 0x3030);
14868                 bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
14869                 WRT32_IO_REG(ha, io_base_addr, 0x3040);
14870                 bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
14871                 WRT32_IO_REG(ha, io_base_addr, 0x3050);
14872                 bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
14873                 WRT32_IO_REG(ha, io_base_addr, 0x3060);
14874                 bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
14875                 WRT32_IO_REG(ha, io_base_addr, 0x3070);
14876                 (void) ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
14877 
14878                 /* Fibre Protocol Module registers. */
14879 
14880                 /* FPM hardware */
14881                 WRT32_IO_REG(ha, io_base_addr, 0x4000);
14882                 bp = ql_read_regs(ha, fw->fpm_hdw_reg, ha->iobase + 0xC0,
14883                     16, 32);
14884                 WRT32_IO_REG(ha, io_base_addr, 0x4010);
14885                 bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
14886                 WRT32_IO_REG(ha, io_base_addr, 0x4020);
14887                 bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
14888                 WRT32_IO_REG(ha, io_base_addr, 0x4030);
14889                 bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
14890                 WRT32_IO_REG(ha, io_base_addr, 0x4040);
14891                 bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
14892                 WRT32_IO_REG(ha, io_base_addr, 0x4050);
14893                 bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
14894                 WRT32_IO_REG(ha, io_base_addr, 0x4060);
14895                 bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
14896                 WRT32_IO_REG(ha, io_base_addr, 0x4070);
14897                 bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
14898                 WRT32_IO_REG(ha, io_base_addr, 0x4080);
14899                 bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
14900                 WRT32_IO_REG(ha, io_base_addr, 0x4090);
14901                 bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
14902                 WRT32_IO_REG(ha, io_base_addr, 0x40A0);
14903                 bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
14904                 WRT32_IO_REG(ha, io_base_addr, 0x40B0);
14905                 bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
14906                 WRT32_IO_REG(ha, io_base_addr, 0x40C0);
14907                 bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
14908                 WRT32_IO_REG(ha, io_base_addr, 0x40D0);
14909                 (void) ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
14910 
14911                 /* Frame Buffer registers. */
14912 
14913                 /* FB hardware */
14914                 WRT32_IO_REG(ha, io_base_addr, 0x6000);
14915                 bp = ql_read_regs(ha, fw->fb_hdw_reg, ha->iobase + 0xC0,
14916                     16, 32);
14917                 WRT32_IO_REG(ha, io_base_addr, 0x6010);
14918                 bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
14919                 WRT32_IO_REG(ha, io_base_addr, 0x6020);
14920                 bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
14921                 WRT32_IO_REG(ha, io_base_addr, 0x6030);
14922                 bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
14923                 WRT32_IO_REG(ha, io_base_addr, 0x6040);
14924                 bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
14925                 WRT32_IO_REG(ha, io_base_addr, 0x6100);
14926                 bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
14927                 WRT32_IO_REG(ha, io_base_addr, 0x6130);
14928                 bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
14929                 WRT32_IO_REG(ha, io_base_addr, 0x6150);
14930                 bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
14931                 WRT32_IO_REG(ha, io_base_addr, 0x6170);
14932                 bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
14933                 WRT32_IO_REG(ha, io_base_addr, 0x6190);
14934                 bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
14935                 WRT32_IO_REG(ha, io_base_addr, 0x61B0);
14936                 bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
14937                 WRT32_IO_REG(ha, io_base_addr, 0x61C0);
14938                 bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
14939                 WRT32_IO_REG(ha, io_base_addr, 0x6F00);
14940                 (void) ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
14941         }
14942 
14943         /* Get the request queue */
14944         if (rval == QL_SUCCESS) {
14945                 uint32_t        cnt;
14946                 uint32_t        *w32 = (uint32_t *)ha->request_ring_bp;
14947 
14948                 /* Sync DMA buffer. */
14949                 (void) ddi_dma_sync(ha->hba_buf.dma_handle,
14950                     REQUEST_Q_BUFFER_OFFSET, sizeof (fw->req_q),
14951                     DDI_DMA_SYNC_FORKERNEL);
14952 
14953                 for (cnt = 0; cnt < sizeof (fw->req_q) / 4; cnt++) {
14954                         fw->req_q[cnt] = *w32++;
14955                         LITTLE_ENDIAN_32(&fw->req_q[cnt]);
14956                 }
14957         }
14958 
14959         /* Get the response queue */
14960         if (rval == QL_SUCCESS) {
14961                 uint32_t        cnt;
14962                 uint32_t        *w32 = (uint32_t *)ha->response_ring_bp;
14963 
14964                 /* Sync DMA buffer. */
14965                 (void) ddi_dma_sync(ha->hba_buf.dma_handle,
14966                     RESPONSE_Q_BUFFER_OFFSET, sizeof (fw->rsp_q),
14967                     DDI_DMA_SYNC_FORKERNEL);
14968 
14969                 for (cnt = 0; cnt < sizeof (fw->rsp_q) / 4; cnt++) {
14970                         fw->rsp_q[cnt] = *w32++;
14971                         LITTLE_ENDIAN_32(&fw->rsp_q[cnt]);
14972                 }
14973         }
14974 
14975         /* Reset RISC. */
14976 
14977         ql_reset_chip(ha);
14978 
14979         /* Memory. */
14980 
14981         if (rval == QL_SUCCESS) {
14982                 /* Code RAM. */
14983                 rval = ql_read_risc_ram(ha, 0x20000,
14984                     sizeof (fw->code_ram) / 4, fw->code_ram);
14985         }
14986         if (rval == QL_SUCCESS) {
14987                 /* External Memory. */
14988                 rval = ql_read_risc_ram(ha, 0x100000,
14989                     ha->fw_ext_memory_size / 4, fw->ext_mem);
14990         }
14991 
14992         /* Get the FC event trace buffer */
14993         if (rval == QL_SUCCESS) {
14994                 if (CFG_IST(ha, CFG_ENABLE_FWFCETRACE) &&
14995                     (ha->fwfcetracebuf.bp != NULL)) {
14996                         uint32_t        cnt;
14997                         uint32_t        *w32 = ha->fwfcetracebuf.bp;
14998 
14999                         /* Sync DMA buffer. */
15000                         (void) ddi_dma_sync(ha->fwfcetracebuf.dma_handle, 0,
15001                             FWFCESIZE, DDI_DMA_SYNC_FORKERNEL);
15002 
15003                         for (cnt = 0; cnt < FWFCESIZE / 4; cnt++) {
15004                                 fw->fce_trace_buf[cnt] = *w32++;
15005                         }
15006                 }
15007         }
15008 
15009         /* Get the extended trace buffer */
15010         if (rval == QL_SUCCESS) {
15011                 if (CFG_IST(ha, CFG_ENABLE_FWEXTTRACE) &&
15012                     (ha->fwexttracebuf.bp != NULL)) {
15013                         uint32_t        cnt;
15014                         uint32_t        *w32 = ha->fwexttracebuf.bp;
15015 
15016                         /* Sync DMA buffer. */
15017                         (void) ddi_dma_sync(ha->fwexttracebuf.dma_handle, 0,
15018                             FWEXTSIZE, DDI_DMA_SYNC_FORKERNEL);
15019 
15020                         for (cnt = 0; cnt < FWEXTSIZE / 4; cnt++) {
15021                                 fw->ext_trace_buf[cnt] = *w32++;
15022                         }
15023                 }
15024         }
15025 
15026         if (rval != QL_SUCCESS) {
15027                 EL(ha, "failed=%xh\n", rval);
15028         } else {
15029                 /*EMPTY*/
15030                 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
15031         }
15032 
15033         return (rval);
15034 }
15035 
15036 /*
15037  * ql_read_risc_ram
15038  *      Reads RISC RAM one word at a time.
15039  *      Risc interrupts must be disabled when this routine is called.
15040  *
15041  * Input:
15042  *      ha:     adapter state pointer.
15043  *      risc_address:   RISC code start address.
15044  *      len:            Number of words.
15045  *      buf:            buffer pointer.
15046  *
15047  * Returns:
15048  *      ql local function return status code.
15049  *
15050  * Context:
15051  *      Interrupt or Kernel context, no mailbox commands allowed.
15052  */
15053 static int
15054 ql_read_risc_ram(ql_adapter_state_t *ha, uint32_t risc_address, uint32_t len,
15055     void *buf)
15056 {
15057         uint32_t        cnt;
15058         uint16_t        stat;
15059         clock_t         timer;
15060         uint16_t        *buf16 = (uint16_t *)buf;
15061         uint32_t        *buf32 = (uint32_t *)buf;
15062         int             rval = QL_SUCCESS;
15063 
15064         for (cnt = 0; cnt < len; cnt++, risc_address++) {
15065                 WRT16_IO_REG(ha, mailbox_in[0], MBC_READ_RAM_EXTENDED);
15066                 WRT16_IO_REG(ha, mailbox_in[1], LSW(risc_address));
15067                 WRT16_IO_REG(ha, mailbox_in[8], MSW(risc_address));
15068                 if (CFG_IST(ha, CFG_CTRL_8021)) {
15069                         WRT32_IO_REG(ha, nx_host_int, NX_MBX_CMD);
15070                 } else if (CFG_IST(ha, CFG_CTRL_242581)) {
15071                         WRT32_IO_REG(ha, hccr, HC24_SET_HOST_INT);
15072                 } else {
15073                         WRT16_IO_REG(ha, hccr, HC_SET_HOST_INT);
15074                 }
15075                 for (timer = 6000000; timer && rval == QL_SUCCESS; timer--) {
15076                         if (INTERRUPT_PENDING(ha)) {
15077                                 stat = (uint16_t)
15078                                     (RD16_IO_REG(ha, risc2host) & 0xff);
15079                                 if ((stat == 1) || (stat == 0x10)) {
15080                                         if (CFG_IST(ha, CFG_CTRL_24258081)) {
15081                                                 buf32[cnt] = SHORT_TO_LONG(
15082                                                     RD16_IO_REG(ha,
15083                                                     mailbox_out[2]),
15084                                                     RD16_IO_REG(ha,
15085                                                     mailbox_out[3]));
15086                                         } else {
15087                                                 buf16[cnt] =
15088                                                     RD16_IO_REG(ha,
15089                                                     mailbox_out[2]);
15090                                         }
15091 
15092                                         break;
15093                                 } else if ((stat == 2) || (stat == 0x11)) {
15094                                         rval = RD16_IO_REG(ha, mailbox_out[0]);
15095                                         break;
15096                                 }
15097                                 if (CFG_IST(ha, CFG_CTRL_8021)) {
15098                                         ql_8021_clr_hw_intr(ha);
15099                                         ql_8021_clr_fw_intr(ha);
15100                                 } else if (CFG_IST(ha, CFG_CTRL_242581)) {
15101                                         WRT32_IO_REG(ha, hccr,
15102                                             HC24_CLR_RISC_INT);
15103                                         RD32_IO_REG(ha, hccr);
15104                                 } else {
15105                                         WRT16_IO_REG(ha, hccr,
15106                                             HC_CLR_RISC_INT);
15107                                 }
15108                         }
15109                         drv_usecwait(5);
15110                 }
15111                 if (CFG_IST(ha, CFG_CTRL_8021)) {
15112                         ql_8021_clr_hw_intr(ha);
15113                         ql_8021_clr_fw_intr(ha);
15114                 } else if (CFG_IST(ha, CFG_CTRL_242581)) {
15115                         WRT32_IO_REG(ha, hccr, HC24_CLR_RISC_INT);
15116                         RD32_IO_REG(ha, hccr);
15117                 } else {
15118                         WRT16_IO_REG(ha, hccr, HC_CLR_RISC_INT);
15119                         WRT16_IO_REG(ha, semaphore, 0);
15120                 }
15121 
15122                 if (timer == 0) {
15123                         rval = QL_FUNCTION_TIMEOUT;
15124                 }
15125         }
15126 
15127         return (rval);
15128 }
15129 
15130 /*
15131  * ql_read_regs
15132  *      Reads adapter registers to buffer.
15133  *
15134  * Input:
15135  *      ha:     adapter state pointer.
15136  *      buf:    buffer pointer.
15137  *      reg:    start address.
15138  *      count:  number of registers.
15139  *      wds:    register size.
15140  *
15141  * Context:
15142  *      Interrupt or Kernel context, no mailbox commands allowed.
15143  */
15144 static void *
15145 ql_read_regs(ql_adapter_state_t *ha, void *buf, void *reg, uint32_t count,
15146     uint8_t wds)
15147 {
15148         uint32_t        *bp32, *reg32;
15149         uint16_t        *bp16, *reg16;
15150         uint8_t         *bp8, *reg8;
15151 
15152         switch (wds) {
15153         case 32:
15154                 bp32 = buf;
15155                 reg32 = reg;
15156                 while (count--) {
15157                         *bp32++ = RD_REG_DWORD(ha, reg32++);
15158                 }
15159                 return (bp32);
15160         case 16:
15161                 bp16 = buf;
15162                 reg16 = reg;
15163                 while (count--) {
15164                         *bp16++ = RD_REG_WORD(ha, reg16++);
15165                 }
15166                 return (bp16);
15167         case 8:
15168                 bp8 = buf;
15169                 reg8 = reg;
15170                 while (count--) {
15171                         *bp8++ = RD_REG_BYTE(ha, reg8++);
15172                 }
15173                 return (bp8);
15174         default:
15175                 EL(ha, "Unknown word size=%d\n", wds);
15176                 return (buf);
15177         }
15178 }
15179 
15180 static int
15181 ql_save_config_regs(dev_info_t *dip)
15182 {
15183         ql_adapter_state_t      *ha;
15184         int                     ret;
15185         ql_config_space_t       chs;
15186         caddr_t                 prop = "ql-config-space";
15187 
15188         ha = ddi_get_soft_state(ql_state, ddi_get_instance(dip));
15189         if (ha == NULL) {
15190                 QL_PRINT_2(CE_CONT, "(%d): no adapter\n",
15191                     ddi_get_instance(dip));
15192                 return (DDI_FAILURE);
15193         }
15194 
15195         QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
15196 
15197         /*LINTED [Solaris DDI_DEV_T_ANY Lint warning]*/
15198         if (ddi_prop_exists(DDI_DEV_T_ANY, dip, DDI_PROP_DONTPASS, prop) ==
15199             1) {
15200                 QL_PRINT_2(CE_CONT, "(%d): no prop exit\n", ha->instance);
15201                 return (DDI_SUCCESS);
15202         }
15203 
15204         chs.chs_command = (uint16_t)ql_pci_config_get16(ha, PCI_CONF_COMM);
15205         chs.chs_header_type = (uint8_t)ql_pci_config_get8(ha,
15206             PCI_CONF_HEADER);
15207         if ((chs.chs_header_type & PCI_HEADER_TYPE_M) == PCI_HEADER_ONE) {
15208                 chs.chs_bridge_control = (uint8_t)ql_pci_config_get8(ha,
15209                     PCI_BCNF_BCNTRL);
15210         }
15211 
15212         chs.chs_cache_line_size = (uint8_t)ql_pci_config_get8(ha,
15213             PCI_CONF_CACHE_LINESZ);
15214 
15215         chs.chs_latency_timer = (uint8_t)ql_pci_config_get8(ha,
15216             PCI_CONF_LATENCY_TIMER);
15217 
15218         if ((chs.chs_header_type & PCI_HEADER_TYPE_M) == PCI_HEADER_ONE) {
15219                 chs.chs_sec_latency_timer = (uint8_t)ql_pci_config_get8(ha,
15220                     PCI_BCNF_LATENCY_TIMER);
15221         }
15222 
15223         chs.chs_base0 = ql_pci_config_get32(ha, PCI_CONF_BASE0);
15224         chs.chs_base1 = ql_pci_config_get32(ha, PCI_CONF_BASE1);
15225         chs.chs_base2 = ql_pci_config_get32(ha, PCI_CONF_BASE2);
15226         chs.chs_base3 = ql_pci_config_get32(ha, PCI_CONF_BASE3);
15227         chs.chs_base4 = ql_pci_config_get32(ha, PCI_CONF_BASE4);
15228         chs.chs_base5 = ql_pci_config_get32(ha, PCI_CONF_BASE5);
15229 
15230         /*LINTED [Solaris DDI_DEV_T_NONE Lint warning]*/
15231         ret = ndi_prop_update_byte_array(DDI_DEV_T_NONE, dip, prop,
15232             (uchar_t *)&chs, sizeof (ql_config_space_t));
15233 
15234         if (ret != DDI_PROP_SUCCESS) {
15235                 cmn_err(CE_WARN, "!Qlogic %s(%d) can't update prop %s",
15236                     QL_NAME, ddi_get_instance(dip), prop);
15237                 return (DDI_FAILURE);
15238         }
15239 
15240         QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
15241 
15242         return (DDI_SUCCESS);
15243 }
15244 
15245 static int
15246 ql_restore_config_regs(dev_info_t *dip)
15247 {
15248         ql_adapter_state_t      *ha;
15249         uint_t                  elements;
15250         ql_config_space_t       *chs_p;
15251         caddr_t                 prop = "ql-config-space";
15252 
15253         ha = ddi_get_soft_state(ql_state, ddi_get_instance(dip));
15254         if (ha == NULL) {
15255                 QL_PRINT_2(CE_CONT, "(%d): no adapter\n",
15256                     ddi_get_instance(dip));
15257                 return (DDI_FAILURE);
15258         }
15259 
15260         QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
15261 
15262         /*LINTED [Solaris DDI_DEV_T_ANY Lint warning]*/
15263         if (ddi_prop_lookup_byte_array(DDI_DEV_T_ANY, dip,
15264             DDI_PROP_DONTPASS | DDI_PROP_NOTPROM, prop,
15265             (uchar_t **)&chs_p, &elements) != DDI_PROP_SUCCESS) {
15266                 QL_PRINT_2(CE_CONT, "(%d): no prop exit\n", ha->instance);
15267                 return (DDI_FAILURE);
15268         }
15269 
15270         ql_pci_config_put16(ha, PCI_CONF_COMM, chs_p->chs_command);
15271 
15272         if ((chs_p->chs_header_type & PCI_HEADER_TYPE_M) == PCI_HEADER_ONE) {
15273                 ql_pci_config_put16(ha, PCI_BCNF_BCNTRL,
15274                     chs_p->chs_bridge_control);
15275         }
15276 
15277         ql_pci_config_put8(ha, PCI_CONF_CACHE_LINESZ,
15278             chs_p->chs_cache_line_size);
15279 
15280         ql_pci_config_put8(ha, PCI_CONF_LATENCY_TIMER,
15281             chs_p->chs_latency_timer);
15282 
15283         if ((chs_p->chs_header_type & PCI_HEADER_TYPE_M) == PCI_HEADER_ONE) {
15284                 ql_pci_config_put8(ha, PCI_BCNF_LATENCY_TIMER,
15285                     chs_p->chs_sec_latency_timer);
15286         }
15287 
15288         ql_pci_config_put32(ha, PCI_CONF_BASE0, chs_p->chs_base0);
15289         ql_pci_config_put32(ha, PCI_CONF_BASE1, chs_p->chs_base1);
15290         ql_pci_config_put32(ha, PCI_CONF_BASE2, chs_p->chs_base2);
15291         ql_pci_config_put32(ha, PCI_CONF_BASE3, chs_p->chs_base3);
15292         ql_pci_config_put32(ha, PCI_CONF_BASE4, chs_p->chs_base4);
15293         ql_pci_config_put32(ha, PCI_CONF_BASE5, chs_p->chs_base5);
15294 
15295         ddi_prop_free(chs_p);
15296 
15297         /*LINTED [Solaris DDI_DEV_T_NONE Lint warning]*/
15298         if (ndi_prop_remove(DDI_DEV_T_NONE, dip, prop) != DDI_PROP_SUCCESS) {
15299                 cmn_err(CE_WARN, "!Qlogic %s(%d): can't remove prop %s",
15300                     QL_NAME, ddi_get_instance(dip), prop);
15301         }
15302 
15303         QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
15304 
15305         return (DDI_SUCCESS);
15306 }
15307 
15308 uint8_t
15309 ql_pci_config_get8(ql_adapter_state_t *ha, off_t off)
15310 {
15311         if (CFG_IST(ha, CFG_SBUS_CARD)) {
15312                 return (ddi_get8(ha->sbus_config_handle,
15313                     (uint8_t *)(ha->sbus_config_base + off)));
15314         }
15315 
15316 #ifdef KERNEL_32
15317         return (pci_config_getb(ha->pci_handle, off));
15318 #else
15319         return (pci_config_get8(ha->pci_handle, off));
15320 #endif
15321 }
15322 
15323 uint16_t
15324 ql_pci_config_get16(ql_adapter_state_t *ha, off_t off)
15325 {
15326         if (CFG_IST(ha, CFG_SBUS_CARD)) {
15327                 return (ddi_get16(ha->sbus_config_handle,
15328                     (uint16_t *)(ha->sbus_config_base + off)));
15329         }
15330 
15331 #ifdef KERNEL_32
15332         return (pci_config_getw(ha->pci_handle, off));
15333 #else
15334         return (pci_config_get16(ha->pci_handle, off));
15335 #endif
15336 }
15337 
15338 uint32_t
15339 ql_pci_config_get32(ql_adapter_state_t *ha, off_t off)
15340 {
15341         if (CFG_IST(ha, CFG_SBUS_CARD)) {
15342                 return (ddi_get32(ha->sbus_config_handle,
15343                     (uint32_t *)(ha->sbus_config_base + off)));
15344         }
15345 
15346 #ifdef KERNEL_32
15347         return (pci_config_getl(ha->pci_handle, off));
15348 #else
15349         return (pci_config_get32(ha->pci_handle, off));
15350 #endif
15351 }
15352 
15353 void
15354 ql_pci_config_put8(ql_adapter_state_t *ha, off_t off, uint8_t val)
15355 {
15356         if (CFG_IST(ha, CFG_SBUS_CARD)) {
15357                 ddi_put8(ha->sbus_config_handle,
15358                     (uint8_t *)(ha->sbus_config_base + off), val);
15359         } else {
15360 #ifdef KERNEL_32
15361                 pci_config_putb(ha->pci_handle, off, val);
15362 #else
15363                 pci_config_put8(ha->pci_handle, off, val);
15364 #endif
15365         }
15366 }
15367 
15368 void
15369 ql_pci_config_put16(ql_adapter_state_t *ha, off_t off, uint16_t val)
15370 {
15371         if (CFG_IST(ha, CFG_SBUS_CARD)) {
15372                 ddi_put16(ha->sbus_config_handle,
15373                     (uint16_t *)(ha->sbus_config_base + off), val);
15374         } else {
15375 #ifdef KERNEL_32
15376                 pci_config_putw(ha->pci_handle, off, val);
15377 #else
15378                 pci_config_put16(ha->pci_handle, off, val);
15379 #endif
15380         }
15381 }
15382 
15383 void
15384 ql_pci_config_put32(ql_adapter_state_t *ha, off_t off, uint32_t val)
15385 {
15386         if (CFG_IST(ha, CFG_SBUS_CARD)) {
15387                 ddi_put32(ha->sbus_config_handle,
15388                     (uint32_t *)(ha->sbus_config_base + off), val);
15389         } else {
15390 #ifdef KERNEL_32
15391                 pci_config_putl(ha->pci_handle, off, val);
15392 #else
15393                 pci_config_put32(ha->pci_handle, off, val);
15394 #endif
15395         }
15396 }
15397 
15398 /*
15399  * ql_halt
15400  *      Waits for commands that are running to finish and
15401  *      if they do not, commands are aborted.
15402  *      Finally the adapter is reset.
15403  *
15404  * Input:
15405  *      ha:     adapter state pointer.
15406  *      pwr:    power state.
15407  *
15408  * Context:
15409  *      Kernel context.
15410  */
15411 static void
15412 ql_halt(ql_adapter_state_t *ha, int pwr)
15413 {
15414         uint32_t        cnt;
15415         ql_tgt_t        *tq;
15416         ql_srb_t        *sp;
15417         uint16_t        index;
15418         ql_link_t       *link;
15419 
15420         QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
15421 
15422         /* Wait for all commands running to finish. */
15423         for (index = 0; index < DEVICE_HEAD_LIST_SIZE; index++) {
15424                 for (link = ha->dev[index].first; link != NULL;
15425                     link = link->next) {
15426                         tq = link->base_address;
15427                         (void) ql_abort_device(ha, tq, 0);
15428 
15429                         /* Wait for 30 seconds for commands to finish. */
15430                         for (cnt = 3000; cnt != 0; cnt--) {
15431                                 /* Acquire device queue lock. */
15432                                 DEVICE_QUEUE_LOCK(tq);
15433                                 if (tq->outcnt == 0) {
15434                                         /* Release device queue lock. */
15435                                         DEVICE_QUEUE_UNLOCK(tq);
15436                                         break;
15437                                 } else {
15438                                         /* Release device queue lock. */
15439                                         DEVICE_QUEUE_UNLOCK(tq);
15440                                         ql_delay(ha, 10000);
15441                                 }
15442                         }
15443 
15444                         /* Finish any commands waiting for more status. */
15445                         if (ha->status_srb != NULL) {
15446                                 sp = ha->status_srb;
15447                                 ha->status_srb = NULL;
15448                                 sp->cmd.next = NULL;
15449                                 ql_done(&sp->cmd);
15450                         }
15451 
15452                         /* Abort commands that did not finish. */
15453                         if (cnt == 0) {
15454                                 for (cnt = 1; cnt < MAX_OUTSTANDING_COMMANDS;
15455                                     cnt++) {
15456                                         if (ha->pending_cmds.first != NULL) {
15457                                                 ql_start_iocb(ha, NULL);
15458                                                 cnt = 1;
15459                                         }
15460                                         sp = ha->outstanding_cmds[cnt];
15461                                         if (sp != NULL &&
15462                                             sp->lun_queue->target_queue ==
15463                                             tq) {
15464                                                 (void) ql_abort((opaque_t)ha,
15465                                                     sp->pkt, 0);
15466                                         }
15467                                 }
15468                         }
15469                 }
15470         }
15471 
15472         /* Shutdown IP. */
15473         if (ha->flags & IP_INITIALIZED) {
15474                 (void) ql_shutdown_ip(ha);
15475         }
15476 
15477         /* Stop all timers. */
15478         ADAPTER_STATE_LOCK(ha);
15479         ha->port_retry_timer = 0;
15480         ha->loop_down_timer = LOOP_DOWN_TIMER_OFF;
15481         ha->watchdog_timer = 0;
15482         ADAPTER_STATE_UNLOCK(ha);
15483 
15484         if (pwr == PM_LEVEL_D3) {
15485                 ADAPTER_STATE_LOCK(ha);
15486                 ha->flags &= ~ONLINE;
15487                 ADAPTER_STATE_UNLOCK(ha);
15488 
15489                 /* Reset ISP chip. */
15490                 ql_reset_chip(ha);
15491         }
15492 
15493         QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
15494 }
15495 
15496 /*
15497  * ql_get_dma_mem
15498  *      Function used to allocate dma memory.
15499  *
15500  * Input:
15501  *      ha:                     adapter state pointer.
15502  *      mem:                    pointer to dma memory object.
15503  *      size:                   size of the request in bytes
15504  *
15505  * Returns:
15506  *      qn local function return status code.
15507  *
15508  * Context:
15509  *      Kernel context.
15510  */
15511 int
15512 ql_get_dma_mem(ql_adapter_state_t *ha, dma_mem_t *mem, uint32_t size,
15513     mem_alloc_type_t allocation_type, mem_alignment_t alignment)
15514 {
15515         int     rval;
15516 
15517         QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
15518 
15519         mem->size = size;
15520         mem->type = allocation_type;
15521         mem->cookie_count = 1;
15522 
15523         switch (alignment) {
15524         case QL_DMA_DATA_ALIGN:
15525                 mem->alignment = QL_DMA_ALIGN_8_BYTE_BOUNDARY;
15526                 break;
15527         case QL_DMA_RING_ALIGN:
15528                 mem->alignment = QL_DMA_ALIGN_64_BYTE_BOUNDARY;
15529                 break;
15530         default:
15531                 EL(ha, "failed, unknown alignment type %x\n", alignment);
15532                 break;
15533         }
15534 
15535         if ((rval = ql_alloc_phys(ha, mem, KM_SLEEP)) != QL_SUCCESS) {
15536                 ql_free_phys(ha, mem);
15537                 EL(ha, "failed, alloc_phys=%xh\n", rval);
15538         }
15539 
15540         QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
15541 
15542         return (rval);
15543 }
15544 
15545 /*
15546  * ql_alloc_phys
15547  *      Function used to allocate memory and zero it.
15548  *      Memory is below 4 GB.
15549  *
15550  * Input:
15551  *      ha:                     adapter state pointer.
15552  *      mem:                    pointer to dma memory object.
15553  *      sleep:                  KM_SLEEP/KM_NOSLEEP flag.
15554  *      mem->cookie_count    number of segments allowed.
15555  *      mem->type            memory allocation type.
15556  *      mem->size            memory size.
15557  *      mem->alignment               memory alignment.
15558  *
15559  * Returns:
15560  *      qn local function return status code.
15561  *
15562  * Context:
15563  *      Kernel context.
15564  */
15565 int
15566 ql_alloc_phys(ql_adapter_state_t *ha, dma_mem_t *mem, int sleep)
15567 {
15568         size_t                  rlen;
15569         ddi_dma_attr_t          dma_attr;
15570         ddi_device_acc_attr_t   acc_attr = ql_dev_acc_attr;
15571 
15572         QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
15573 
15574         dma_attr = CFG_IST(ha, CFG_ENABLE_64BIT_ADDRESSING) ?
15575             ql_64bit_io_dma_attr : ql_32bit_io_dma_attr;
15576 
15577         dma_attr.dma_attr_align = mem->alignment; /* DMA address alignment */
15578         dma_attr.dma_attr_sgllen = (int)mem->cookie_count;
15579 
15580         /*
15581          * Workaround for SUN XMITS buffer must end and start on 8 byte
15582          * boundary. Else, hardware will overrun the buffer. Simple fix is
15583          * to make sure buffer has enough room for overrun.
15584          */
15585         if (mem->size & 7) {
15586                 mem->size += 8 - (mem->size & 7);
15587         }
15588 
15589         mem->flags = DDI_DMA_CONSISTENT;
15590 
15591         /*
15592          * Allocate DMA memory for command.
15593          */
15594         if (ddi_dma_alloc_handle(ha->dip, &dma_attr, (sleep == KM_SLEEP) ?
15595             DDI_DMA_SLEEP : DDI_DMA_DONTWAIT, NULL, &mem->dma_handle) !=
15596             DDI_SUCCESS) {
15597                 EL(ha, "failed, ddi_dma_alloc_handle\n");
15598                 mem->dma_handle = NULL;
15599                 return (QL_MEMORY_ALLOC_FAILED);
15600         }
15601 
15602         switch (mem->type) {
15603         case KERNEL_MEM:
15604                 mem->bp = kmem_zalloc(mem->size, sleep);
15605                 break;
15606         case BIG_ENDIAN_DMA:
15607         case LITTLE_ENDIAN_DMA:
15608         case NO_SWAP_DMA:
15609                 if (mem->type == BIG_ENDIAN_DMA) {
15610                         acc_attr.devacc_attr_endian_flags =
15611                             DDI_STRUCTURE_BE_ACC;
15612                 } else if (mem->type == NO_SWAP_DMA) {
15613                         acc_attr.devacc_attr_endian_flags = DDI_NEVERSWAP_ACC;
15614                 }
15615                 if (ddi_dma_mem_alloc(mem->dma_handle, mem->size, &acc_attr,
15616                     mem->flags, (sleep == KM_SLEEP) ? DDI_DMA_SLEEP :
15617                     DDI_DMA_DONTWAIT, NULL, (caddr_t *)&mem->bp, &rlen,
15618                     &mem->acc_handle) == DDI_SUCCESS) {
15619                         bzero(mem->bp, mem->size);
15620                         /* ensure we got what we asked for (32bit) */
15621                         if (dma_attr.dma_attr_addr_hi == NULL) {
15622                                 if (mem->cookie.dmac_notused != NULL) {
15623                                         EL(ha, "failed, ddi_dma_mem_alloc "
15624                                             "returned 64 bit DMA address\n");
15625                                         ql_free_phys(ha, mem);
15626                                         return (QL_MEMORY_ALLOC_FAILED);
15627                                 }
15628                         }
15629                 } else {
15630                         mem->acc_handle = NULL;
15631                         mem->bp = NULL;
15632                 }
15633                 break;
15634         default:
15635                 EL(ha, "failed, unknown type=%xh\n", mem->type);
15636                 mem->acc_handle = NULL;
15637                 mem->bp = NULL;
15638                 break;
15639         }
15640 
15641         if (mem->bp == NULL) {
15642                 EL(ha, "failed, ddi_dma_mem_alloc\n");
15643                 ddi_dma_free_handle(&mem->dma_handle);
15644                 mem->dma_handle = NULL;
15645                 return (QL_MEMORY_ALLOC_FAILED);
15646         }
15647 
15648         mem->flags |= DDI_DMA_RDWR;
15649 
15650         if (ql_bind_dma_buffer(ha, mem, sleep) != DDI_DMA_MAPPED) {
15651                 EL(ha, "failed, ddi_dma_addr_bind_handle\n");
15652                 ql_free_phys(ha, mem);
15653                 return (QL_MEMORY_ALLOC_FAILED);
15654         }
15655 
15656         QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
15657 
15658         return (QL_SUCCESS);
15659 }
15660 
15661 /*
15662  * ql_free_phys
15663  *      Function used to free physical memory.
15664  *
15665  * Input:
15666  *      ha:     adapter state pointer.
15667  *      mem:    pointer to dma memory object.
15668  *
15669  * Context:
15670  *      Kernel context.
15671  */
15672 void
15673 ql_free_phys(ql_adapter_state_t *ha, dma_mem_t *mem)
15674 {
15675         QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
15676 
15677         if (mem != NULL && mem->dma_handle != NULL) {
15678                 ql_unbind_dma_buffer(ha, mem);
15679                 switch (mem->type) {
15680                 case KERNEL_MEM:
15681                         if (mem->bp != NULL) {
15682                                 kmem_free(mem->bp, mem->size);
15683                         }
15684                         break;
15685                 case LITTLE_ENDIAN_DMA:
15686                 case BIG_ENDIAN_DMA:
15687                 case NO_SWAP_DMA:
15688                         if (mem->acc_handle != NULL) {
15689                                 ddi_dma_mem_free(&mem->acc_handle);
15690                                 mem->acc_handle = NULL;
15691                         }
15692                         break;
15693                 default:
15694                         break;
15695                 }
15696                 mem->bp = NULL;
15697                 ddi_dma_free_handle(&mem->dma_handle);
15698                 mem->dma_handle = NULL;
15699         }
15700 
15701         QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
15702 }
15703 
15704 /*
15705  * ql_alloc_dma_resouce.
15706  *      Allocates DMA resource for buffer.
15707  *
15708  * Input:
15709  *      ha:                     adapter state pointer.
15710  *      mem:                    pointer to dma memory object.
15711  *      sleep:                  KM_SLEEP/KM_NOSLEEP flag.
15712  *      mem->cookie_count    number of segments allowed.
15713  *      mem->type            memory allocation type.
15714  *      mem->size            memory size.
15715  *      mem->bp                      pointer to memory or struct buf
15716  *
15717  * Returns:
15718  *      qn local function return status code.
15719  *
15720  * Context:
15721  *      Kernel context.
15722  */
15723 int
15724 ql_alloc_dma_resouce(ql_adapter_state_t *ha, dma_mem_t *mem, int sleep)
15725 {
15726         ddi_dma_attr_t  dma_attr;
15727 
15728         QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
15729 
15730         dma_attr = CFG_IST(ha, CFG_ENABLE_64BIT_ADDRESSING) ?
15731             ql_64bit_io_dma_attr : ql_32bit_io_dma_attr;
15732         dma_attr.dma_attr_sgllen = (int)mem->cookie_count;
15733 
15734         /*
15735          * Allocate DMA handle for command.
15736          */
15737         if (ddi_dma_alloc_handle(ha->dip, &dma_attr, (sleep == KM_SLEEP) ?
15738             DDI_DMA_SLEEP : DDI_DMA_DONTWAIT, NULL, &mem->dma_handle) !=
15739             DDI_SUCCESS) {
15740                 EL(ha, "failed, ddi_dma_alloc_handle\n");
15741                 mem->dma_handle = NULL;
15742                 return (QL_MEMORY_ALLOC_FAILED);
15743         }
15744 
15745         mem->flags = DDI_DMA_RDWR | DDI_DMA_CONSISTENT;
15746 
15747         if (ql_bind_dma_buffer(ha, mem, sleep) != DDI_DMA_MAPPED) {
15748                 EL(ha, "failed, bind_dma_buffer\n");
15749                 ddi_dma_free_handle(&mem->dma_handle);
15750                 mem->dma_handle = NULL;
15751                 return (QL_MEMORY_ALLOC_FAILED);
15752         }
15753 
15754         QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
15755 
15756         return (QL_SUCCESS);
15757 }
15758 
15759 /*
15760  * ql_free_dma_resource
15761  *      Frees DMA resources.
15762  *
15763  * Input:
15764  *      ha:             adapter state pointer.
15765  *      mem:            pointer to dma memory object.
15766  *      mem->dma_handle      DMA memory handle.
15767  *
15768  * Context:
15769  *      Kernel context.
15770  */
15771 void
15772 ql_free_dma_resource(ql_adapter_state_t *ha, dma_mem_t *mem)
15773 {
15774         QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
15775 
15776         ql_free_phys(ha, mem);
15777 
15778         QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
15779 }
15780 
15781 /*
15782  * ql_bind_dma_buffer
15783  *      Binds DMA buffer.
15784  *
15785  * Input:
15786  *      ha:                     adapter state pointer.
15787  *      mem:                    pointer to dma memory object.
15788  *      sleep:                  KM_SLEEP or KM_NOSLEEP.
15789  *      mem->dma_handle              DMA memory handle.
15790  *      mem->cookie_count    number of segments allowed.
15791  *      mem->type            memory allocation type.
15792  *      mem->size            memory size.
15793  *      mem->bp                      pointer to memory or struct buf
15794  *
15795  * Returns:
15796  *      mem->cookies         pointer to list of cookies.
15797  *      mem->cookie_count    number of cookies.
15798  *      status                  success = DDI_DMA_MAPPED
15799  *                              DDI_DMA_PARTIAL_MAP, DDI_DMA_INUSE,
15800  *                              DDI_DMA_NORESOURCES, DDI_DMA_NOMAPPING or
15801  *                              DDI_DMA_TOOBIG
15802  *
15803  * Context:
15804  *      Kernel context.
15805  */
15806 static int
15807 ql_bind_dma_buffer(ql_adapter_state_t *ha, dma_mem_t *mem, int sleep)
15808 {
15809         int                     rval;
15810         ddi_dma_cookie_t        *cookiep;
15811         uint32_t                cnt = mem->cookie_count;
15812 
15813         QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
15814 
15815         if (mem->type == STRUCT_BUF_MEMORY) {
15816                 rval = ddi_dma_buf_bind_handle(mem->dma_handle, mem->bp,
15817                     mem->flags, (sleep == KM_SLEEP) ? DDI_DMA_SLEEP :
15818                     DDI_DMA_DONTWAIT, NULL, &mem->cookie, &mem->cookie_count);
15819         } else {
15820                 rval = ddi_dma_addr_bind_handle(mem->dma_handle, NULL, mem->bp,
15821                     mem->size, mem->flags, (sleep == KM_SLEEP) ?
15822                     DDI_DMA_SLEEP : DDI_DMA_DONTWAIT, NULL, &mem->cookie,
15823                     &mem->cookie_count);
15824         }
15825 
15826         if (rval == DDI_DMA_MAPPED) {
15827                 if (mem->cookie_count > cnt) {
15828                         (void) ddi_dma_unbind_handle(mem->dma_handle);
15829                         EL(ha, "failed, cookie_count %d > %d\n",
15830                             mem->cookie_count, cnt);
15831                         rval = DDI_DMA_TOOBIG;
15832                 } else {
15833                         if (mem->cookie_count > 1) {
15834                                 if (mem->cookies = kmem_zalloc(
15835                                     sizeof (ddi_dma_cookie_t) *
15836                                     mem->cookie_count, sleep)) {
15837                                         *mem->cookies = mem->cookie;
15838                                         cookiep = mem->cookies;
15839                                         for (cnt = 1; cnt < mem->cookie_count;
15840                                             cnt++) {
15841                                                 ddi_dma_nextcookie(
15842                                                     mem->dma_handle,
15843                                                     ++cookiep);
15844                                         }
15845                                 } else {
15846                                         (void) ddi_dma_unbind_handle(
15847                                             mem->dma_handle);
15848                                         EL(ha, "failed, kmem_zalloc\n");
15849                                         rval = DDI_DMA_NORESOURCES;
15850                                 }
15851                         } else {
15852                                 /*
15853                                  * It has been reported that dmac_size at times
15854                                  * may be incorrect on sparc machines so for
15855                                  * sparc machines that only have one segment
15856                                  * use the buffer size instead.
15857                                  */
15858                                 mem->cookies = &mem->cookie;
15859                                 mem->cookies->dmac_size = mem->size;
15860                         }
15861                 }
15862         }
15863 
15864         if (rval != DDI_DMA_MAPPED) {
15865                 EL(ha, "failed=%xh\n", rval);
15866         } else {
15867                 /*EMPTY*/
15868                 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
15869         }
15870 
15871         return (rval);
15872 }
15873 
15874 /*
15875  * ql_unbind_dma_buffer
15876  *      Unbinds DMA buffer.
15877  *
15878  * Input:
15879  *      ha:                     adapter state pointer.
15880  *      mem:                    pointer to dma memory object.
15881  *      mem->dma_handle              DMA memory handle.
15882  *      mem->cookies         pointer to cookie list.
15883  *      mem->cookie_count    number of cookies.
15884  *
15885  * Context:
15886  *      Kernel context.
15887  */
15888 /* ARGSUSED */
15889 static void
15890 ql_unbind_dma_buffer(ql_adapter_state_t *ha, dma_mem_t *mem)
15891 {
15892         QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
15893 
15894         (void) ddi_dma_unbind_handle(mem->dma_handle);
15895         if (mem->cookie_count > 1) {
15896                 kmem_free(mem->cookies, sizeof (ddi_dma_cookie_t) *
15897                     mem->cookie_count);
15898                 mem->cookies = NULL;
15899         }
15900         mem->cookie_count = 0;
15901 
15902         QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
15903 }
15904 
15905 static int
15906 ql_suspend_adapter(ql_adapter_state_t *ha)
15907 {
15908         clock_t timer = 32 * drv_usectohz(1000000);
15909 
15910         QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
15911 
15912         /*
15913          * First we will claim mbox ownership so that no
15914          * thread using mbox hangs when we disable the
15915          * interrupt in the middle of it.
15916          */
15917         MBX_REGISTER_LOCK(ha);
15918 
15919         /* Check for mailbox available, if not wait for signal. */
15920         while (ha->mailbox_flags & MBX_BUSY_FLG) {
15921                 ha->mailbox_flags = (uint8_t)
15922                     (ha->mailbox_flags | MBX_WANT_FLG);
15923 
15924                 /* 30 seconds from now */
15925                 if (cv_reltimedwait(&ha->cv_mbx_wait, &ha->mbx_mutex,
15926                     timer, TR_CLOCK_TICK) == -1) {
15927 
15928                         /* Release mailbox register lock. */
15929                         MBX_REGISTER_UNLOCK(ha);
15930                         EL(ha, "failed, Suspend mbox");
15931                         return (QL_FUNCTION_TIMEOUT);
15932                 }
15933         }
15934 
15935         /* Set busy flag. */
15936         ha->mailbox_flags = (uint8_t)(ha->mailbox_flags | MBX_BUSY_FLG);
15937         MBX_REGISTER_UNLOCK(ha);
15938 
15939         (void) ql_wait_outstanding(ha);
15940 
15941         /*
15942          * here we are sure that there will not be any mbox interrupt.
15943          * So, let's make sure that we return back all the outstanding
15944          * cmds as well as internally queued commands.
15945          */
15946         ql_halt(ha, PM_LEVEL_D0);
15947 
15948         if (ha->power_level != PM_LEVEL_D3) {
15949                 /* Disable ISP interrupts. */
15950                 WRT16_IO_REG(ha, ictrl, 0);
15951         }
15952 
15953         ADAPTER_STATE_LOCK(ha);
15954         ha->flags &= ~INTERRUPTS_ENABLED;
15955         ADAPTER_STATE_UNLOCK(ha);
15956 
15957         MBX_REGISTER_LOCK(ha);
15958         /* Reset busy status. */
15959         ha->mailbox_flags = (uint8_t)(ha->mailbox_flags & ~MBX_BUSY_FLG);
15960 
15961         /* If thread is waiting for mailbox go signal it to start. */
15962         if (ha->mailbox_flags & MBX_WANT_FLG) {
15963                 ha->mailbox_flags = (uint8_t)
15964                     (ha->mailbox_flags & ~MBX_WANT_FLG);
15965                 cv_broadcast(&ha->cv_mbx_wait);
15966         }
15967         /* Release mailbox register lock. */
15968         MBX_REGISTER_UNLOCK(ha);
15969 
15970         QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
15971 
15972         return (QL_SUCCESS);
15973 }
15974 
15975 /*
15976  * ql_add_link_b
15977  *      Add link to the end of the chain.
15978  *
15979  * Input:
15980  *      head = Head of link list.
15981  *      link = link to be added.
15982  *      LOCK must be already obtained.
15983  *
15984  * Context:
15985  *      Interrupt or Kernel context, no mailbox commands allowed.
15986  */
15987 void
15988 ql_add_link_b(ql_head_t *head, ql_link_t *link)
15989 {
15990         /* at the end there isn't a next */
15991         link->next = NULL;
15992 
15993         if ((link->prev = head->last) == NULL) {
15994                 head->first = link;
15995         } else {
15996                 head->last->next = link;
15997         }
15998 
15999         head->last = link;
16000         link->head = head;   /* the queue we're on */
16001 }
16002 
16003 /*
16004  * ql_add_link_t
16005  *      Add link to the beginning of the chain.
16006  *
16007  * Input:
16008  *      head = Head of link list.
16009  *      link = link to be added.
16010  *      LOCK must be already obtained.
16011  *
16012  * Context:
16013  *      Interrupt or Kernel context, no mailbox commands allowed.
16014  */
16015 void
16016 ql_add_link_t(ql_head_t *head, ql_link_t *link)
16017 {
16018         link->prev = NULL;
16019 
16020         if ((link->next = head->first) == NULL)   {
16021                 head->last = link;
16022         } else {
16023                 head->first->prev = link;
16024         }
16025 
16026         head->first = link;
16027         link->head = head;   /* the queue we're on */
16028 }
16029 
16030 /*
16031  * ql_remove_link
16032  *      Remove a link from the chain.
16033  *
16034  * Input:
16035  *      head = Head of link list.
16036  *      link = link to be removed.
16037  *      LOCK must be already obtained.
16038  *
16039  * Context:
16040  *      Interrupt or Kernel context, no mailbox commands allowed.
16041  */
16042 void
16043 ql_remove_link(ql_head_t *head, ql_link_t *link)
16044 {
16045         if (link->prev != NULL) {
16046                 if ((link->prev->next = link->next) == NULL) {
16047                         head->last = link->prev;
16048                 } else {
16049                         link->next->prev = link->prev;
16050                 }
16051         } else if ((head->first = link->next) == NULL) {
16052                 head->last = NULL;
16053         } else {
16054                 head->first->prev = NULL;
16055         }
16056 
16057         /* not on a queue any more */
16058         link->prev = link->next = NULL;
16059         link->head = NULL;
16060 }
16061 
16062 /*
16063  * ql_chg_endian
16064  *      Change endianess of byte array.
16065  *
16066  * Input:
16067  *      buf = array pointer.
16068  *      size = size of array in bytes.
16069  *
16070  * Context:
16071  *      Interrupt or Kernel context, no mailbox commands allowed.
16072  */
16073 void
16074 ql_chg_endian(uint8_t buf[], size_t size)
16075 {
16076         uint8_t byte;
16077         size_t  cnt1;
16078         size_t  cnt;
16079 
16080         cnt1 = size - 1;
16081         for (cnt = 0; cnt < size / 2; cnt++) {
16082                 byte = buf[cnt1];
16083                 buf[cnt1] = buf[cnt];
16084                 buf[cnt] = byte;
16085                 cnt1--;
16086         }
16087 }
16088 
16089 /*
16090  * ql_bstr_to_dec
16091  *      Convert decimal byte string to number.
16092  *
16093  * Input:
16094  *      s:      byte string pointer.
16095  *      ans:    interger pointer for number.
16096  *      size:   number of ascii bytes.
16097  *
16098  * Returns:
16099  *      success = number of ascii bytes processed.
16100  *
16101  * Context:
16102  *      Kernel/Interrupt context.
16103  */
16104 static int
16105 ql_bstr_to_dec(char *s, uint32_t *ans, uint32_t size)
16106 {
16107         int                     mul, num, cnt, pos;
16108         char                    *str;
16109 
16110         /* Calculate size of number. */
16111         if (size == 0) {
16112                 for (str = s; *str >= '0' && *str <= '9'; str++) {
16113                         size++;
16114                 }
16115         }
16116 
16117         *ans = 0;
16118         for (cnt = 0; *s != '\0' && size; size--, cnt++) {
16119                 if (*s >= '0' && *s <= '9') {
16120                         num = *s++ - '0';
16121                 } else {
16122                         break;
16123                 }
16124 
16125                 for (mul = 1, pos = 1; pos < size; pos++) {
16126                         mul *= 10;
16127                 }
16128                 *ans += num * mul;
16129         }
16130 
16131         return (cnt);
16132 }
16133 
16134 /*
16135  * ql_delay
16136  *      Calls delay routine if threads are not suspended, otherwise, busy waits
16137  *      Minimum = 1 tick = 10ms
16138  *
16139  * Input:
16140  *      dly = delay time in microseconds.
16141  *
16142  * Context:
16143  *      Kernel or Interrupt context, no mailbox commands allowed.
16144  */
16145 void
16146 ql_delay(ql_adapter_state_t *ha, clock_t usecs)
16147 {
16148         if (QL_DAEMON_SUSPENDED(ha) || ddi_in_panic()) {
16149                 drv_usecwait(usecs);
16150         } else {
16151                 delay(drv_usectohz(usecs));
16152         }
16153 }
16154 
16155 /*
16156  * ql_stall_drv
16157  *      Stalls one or all driver instances, waits for 30 seconds.
16158  *
16159  * Input:
16160  *      ha:             adapter state pointer or NULL for all.
16161  *      options:        BIT_0 --> leave driver stalled on exit if
16162  *                                failed.
16163  *
16164  * Returns:
16165  *      ql local function return status code.
16166  *
16167  * Context:
16168  *      Kernel context.
16169  */
16170 int
16171 ql_stall_driver(ql_adapter_state_t *ha, uint32_t options)
16172 {
16173         ql_link_t               *link;
16174         ql_adapter_state_t      *ha2;
16175         uint32_t                timer;
16176 
16177         QL_PRINT_3(CE_CONT, "started\n");
16178 
16179         /* Wait for 30 seconds for daemons unstall. */
16180         timer = 3000;
16181         link = ha == NULL ? ql_hba.first : &ha->hba;
16182         while (link != NULL && timer) {
16183                 ha2 = link->base_address;
16184 
16185                 ql_awaken_task_daemon(ha2, NULL, DRIVER_STALL, 0);
16186 
16187                 if ((ha2->task_daemon_flags & TASK_DAEMON_ALIVE_FLG) == 0 ||
16188                     (ha2->task_daemon_flags & TASK_DAEMON_STOP_FLG) != 0 ||
16189                     (ha2->task_daemon_flags & TASK_DAEMON_STALLED_FLG &&
16190                     ql_wait_outstanding(ha2) == MAX_OUTSTANDING_COMMANDS)) {
16191                         link = ha == NULL ? link->next : NULL;
16192                         continue;
16193                 }
16194 
16195                 ql_delay(ha2, 10000);
16196                 timer--;
16197                 link = ha == NULL ? ql_hba.first : &ha->hba;
16198         }
16199 
16200         if (ha2 != NULL && timer == 0) {
16201                 EL(ha2, "failed, tdf=%xh, exiting state is: %s\n",
16202                     ha2->task_daemon_flags, (options & BIT_0 ? "stalled" :
16203                     "unstalled"));
16204                 if (options & BIT_0) {
16205                         ql_awaken_task_daemon(ha2, NULL, 0, DRIVER_STALL);
16206                 }
16207                 return (QL_FUNCTION_TIMEOUT);
16208         }
16209 
16210         QL_PRINT_3(CE_CONT, "done\n");
16211 
16212         return (QL_SUCCESS);
16213 }
16214 
16215 /*
16216  * ql_restart_driver
16217  *      Restarts one or all driver instances.
16218  *
16219  * Input:
16220  *      ha:     adapter state pointer or NULL for all.
16221  *
16222  * Context:
16223  *      Kernel context.
16224  */
16225 void
16226 ql_restart_driver(ql_adapter_state_t *ha)
16227 {
16228         ql_link_t               *link;
16229         ql_adapter_state_t      *ha2;
16230         uint32_t                timer;
16231 
16232         QL_PRINT_3(CE_CONT, "started\n");
16233 
16234         /* Tell all daemons to unstall. */
16235         link = ha == NULL ? ql_hba.first : &ha->hba;
16236         while (link != NULL) {
16237                 ha2 = link->base_address;
16238 
16239                 ql_awaken_task_daemon(ha2, NULL, 0, DRIVER_STALL);
16240 
16241                 link = ha == NULL ? link->next : NULL;
16242         }
16243 
16244         /* Wait for 30 seconds for all daemons unstall. */
16245         timer = 3000;
16246         link = ha == NULL ? ql_hba.first : &ha->hba;
16247         while (link != NULL && timer) {
16248                 ha2 = link->base_address;
16249 
16250                 if ((ha2->task_daemon_flags & TASK_DAEMON_ALIVE_FLG) == 0 ||
16251                     (ha2->task_daemon_flags & TASK_DAEMON_STOP_FLG) != 0 ||
16252                     (ha2->task_daemon_flags & TASK_DAEMON_STALLED_FLG) == 0) {
16253                         QL_PRINT_2(CE_CONT, "(%d,%d): restarted\n",
16254                             ha2->instance, ha2->vp_index);
16255                         ql_restart_queues(ha2);
16256                         link = ha == NULL ? link->next : NULL;
16257                         continue;
16258                 }
16259 
16260                 QL_PRINT_2(CE_CONT, "(%d,%d): failed, tdf=%xh\n",
16261                     ha2->instance, ha2->vp_index, ha2->task_daemon_flags);
16262 
16263                 ql_delay(ha2, 10000);
16264                 timer--;
16265                 link = ha == NULL ? ql_hba.first : &ha->hba;
16266         }
16267 
16268         QL_PRINT_3(CE_CONT, "done\n");
16269 }
16270 
16271 /*
16272  * ql_setup_interrupts
16273  *      Sets up interrupts based on the HBA's and platform's
16274  *      capabilities (e.g., legacy / MSI / FIXED).
16275  *
16276  * Input:
16277  *      ha = adapter state pointer.
16278  *
16279  * Returns:
16280  *      DDI_SUCCESS or DDI_FAILURE.
16281  *
16282  * Context:
16283  *      Kernel context.
16284  */
16285 static int
16286 ql_setup_interrupts(ql_adapter_state_t *ha)
16287 {
16288         int32_t         rval = DDI_FAILURE;
16289         int32_t         i;
16290         int32_t         itypes = 0;
16291 
16292         QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
16293 
16294         /*
16295          * The Solaris Advanced Interrupt Functions (aif) are only
16296          * supported on s10U1 or greater.
16297          */
16298         if (ql_os_release_level < 10 || ql_disable_aif != 0) {
16299                 EL(ha, "interrupt framework is not supported or is "
16300                     "disabled, using legacy\n");
16301                 return (ql_legacy_intr(ha));
16302         } else if (ql_os_release_level == 10) {
16303                 /*
16304                  * See if the advanced interrupt functions (aif) are
16305                  * in the kernel
16306                  */
16307                 void    *fptr = (void *)&ddi_intr_get_supported_types;
16308 
16309                 if (fptr == NULL) {
16310                         EL(ha, "aif is not supported, using legacy "
16311                             "interrupts (rev)\n");
16312                         return (ql_legacy_intr(ha));
16313                 }
16314         }
16315 
16316         /* See what types of interrupts this HBA and platform support */
16317         if ((i = ddi_intr_get_supported_types(ha->dip, &itypes)) !=
16318             DDI_SUCCESS) {
16319                 EL(ha, "get supported types failed, rval=%xh, "
16320                     "assuming FIXED\n", i);
16321                 itypes = DDI_INTR_TYPE_FIXED;
16322         }
16323 
16324         EL(ha, "supported types are: %xh\n", itypes);
16325 
16326         if ((itypes & DDI_INTR_TYPE_MSIX) &&
16327             (rval = ql_setup_msix(ha)) == DDI_SUCCESS) {
16328                 EL(ha, "successful MSI-X setup\n");
16329         } else if ((itypes & DDI_INTR_TYPE_MSI) &&
16330             (rval = ql_setup_msi(ha)) == DDI_SUCCESS) {
16331                 EL(ha, "successful MSI setup\n");
16332         } else {
16333                 rval = ql_setup_fixed(ha);
16334         }
16335 
16336         if (rval != DDI_SUCCESS) {
16337                 EL(ha, "failed, aif, rval=%xh\n", rval);
16338         } else {
16339                 /*EMPTY*/
16340                 QL_PRINT_3(CE_CONT, "(%d): done\n");
16341         }
16342 
16343         return (rval);
16344 }
16345 
16346 /*
16347  * ql_setup_msi
16348  *      Set up aif MSI interrupts
16349  *
16350  * Input:
16351  *      ha = adapter state pointer.
16352  *
16353  * Returns:
16354  *      DDI_SUCCESS or DDI_FAILURE.
16355  *
16356  * Context:
16357  *      Kernel context.
16358  */
16359 static int
16360 ql_setup_msi(ql_adapter_state_t *ha)
16361 {
16362         int32_t         count = 0;
16363         int32_t         avail = 0;
16364         int32_t         actual = 0;
16365         int32_t         msitype = DDI_INTR_TYPE_MSI;
16366         int32_t         ret;
16367         ql_ifunc_t      itrfun[10] = {0};
16368 
16369         QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
16370 
16371         if (ql_disable_msi != 0) {
16372                 EL(ha, "MSI is disabled by user\n");
16373                 return (DDI_FAILURE);
16374         }
16375 
16376         /* MSI support is only suported on 24xx HBA's. */
16377         if (!(CFG_IST(ha, CFG_CTRL_24258081))) {
16378                 EL(ha, "HBA does not support MSI\n");
16379                 return (DDI_FAILURE);
16380         }
16381 
16382         /* Get number of MSI interrupts the system supports */
16383         if (((ret = ddi_intr_get_nintrs(ha->dip, msitype, &count)) !=
16384             DDI_SUCCESS) || count == 0) {
16385                 EL(ha, "failed, nintrs ret=%xh, cnt=%xh\n", ret, count);
16386                 return (DDI_FAILURE);
16387         }
16388 
16389         /* Get number of available MSI interrupts */
16390         if (((ret = ddi_intr_get_navail(ha->dip, msitype, &avail)) !=
16391             DDI_SUCCESS) || avail == 0) {
16392                 EL(ha, "failed, navail ret=%xh, avail=%xh\n", ret, avail);
16393                 return (DDI_FAILURE);
16394         }
16395 
16396         /* MSI requires only 1.  */
16397         count = 1;
16398         itrfun[0].ifunc = &ql_isr_aif;
16399 
16400         /* Allocate space for interrupt handles */
16401         ha->hsize = ((uint32_t)(sizeof (ddi_intr_handle_t)) * count);
16402         ha->htable = kmem_zalloc(ha->hsize, KM_SLEEP);
16403 
16404         ha->iflags |= IFLG_INTR_MSI;
16405 
16406         /* Allocate the interrupts */
16407         if ((ret = ddi_intr_alloc(ha->dip, ha->htable, msitype, 0, count,
16408             &actual, 0)) != DDI_SUCCESS || actual < count) {
16409                 EL(ha, "failed, intr_alloc ret=%xh, count = %xh, "
16410                     "actual=%xh\n", ret, count, actual);
16411                 ql_release_intr(ha);
16412                 return (DDI_FAILURE);
16413         }
16414 
16415         ha->intr_cnt = actual;
16416 
16417         /* Get interrupt priority */
16418         if ((ret = ddi_intr_get_pri(ha->htable[0], &ha->intr_pri)) !=
16419             DDI_SUCCESS) {
16420                 EL(ha, "failed, get_pri ret=%xh\n", ret);
16421                 ql_release_intr(ha);
16422                 return (ret);
16423         }
16424 
16425         /* Add the interrupt handler */
16426         if ((ret = ddi_intr_add_handler(ha->htable[0], itrfun[0].ifunc,
16427             (caddr_t)ha, (caddr_t)0)) != DDI_SUCCESS) {
16428                 EL(ha, "failed, intr_add ret=%xh\n", ret);
16429                 ql_release_intr(ha);
16430                 return (ret);
16431         }
16432 
16433         /* Setup mutexes */
16434         if ((ret = ql_init_mutex(ha)) != DDI_SUCCESS) {
16435                 EL(ha, "failed, mutex init ret=%xh\n", ret);
16436                 ql_release_intr(ha);
16437                 return (ret);
16438         }
16439 
16440         /* Get the capabilities */
16441         (void) ddi_intr_get_cap(ha->htable[0], &ha->intr_cap);
16442 
16443         /* Enable interrupts */
16444         if (ha->intr_cap & DDI_INTR_FLAG_BLOCK) {
16445                 if ((ret = ddi_intr_block_enable(ha->htable, ha->intr_cnt)) !=
16446                     DDI_SUCCESS) {
16447                         EL(ha, "failed, block enable, ret=%xh\n", ret);
16448                         ql_destroy_mutex(ha);
16449                         ql_release_intr(ha);
16450                         return (ret);
16451                 }
16452         } else {
16453                 if ((ret = ddi_intr_enable(ha->htable[0])) != DDI_SUCCESS) {
16454                         EL(ha, "failed, intr enable, ret=%xh\n", ret);
16455                         ql_destroy_mutex(ha);
16456                         ql_release_intr(ha);
16457                         return (ret);
16458                 }
16459         }
16460 
16461         QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
16462 
16463         return (DDI_SUCCESS);
16464 }
16465 
16466 /*
16467  * ql_setup_msix
16468  *      Set up aif MSI-X interrupts
16469  *
16470  * Input:
16471  *      ha = adapter state pointer.
16472  *
16473  * Returns:
16474  *      DDI_SUCCESS or DDI_FAILURE.
16475  *
16476  * Context:
16477  *      Kernel context.
16478  */
16479 static int
16480 ql_setup_msix(ql_adapter_state_t *ha)
16481 {
16482         uint16_t        hwvect;
16483         int32_t         count = 0;
16484         int32_t         avail = 0;
16485         int32_t         actual = 0;
16486         int32_t         msitype = DDI_INTR_TYPE_MSIX;
16487         int32_t         ret;
16488         uint32_t        i;
16489         ql_ifunc_t      itrfun[QL_MSIX_MAXAIF] = {0};
16490 
16491         QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
16492 
16493         if (ql_disable_msix != 0) {
16494                 EL(ha, "MSI-X is disabled by user\n");
16495                 return (DDI_FAILURE);
16496         }
16497 
16498         /*
16499          * MSI-X support is only available on 24xx HBA's that have
16500          * rev A2 parts (revid = 3) or greater.
16501          */
16502         if (!((ha->device_id == 0x2532) || (ha->device_id == 0x2432) ||
16503             (ha->device_id == 0x8432) || (ha->device_id == 0x8001) ||
16504             (ha->device_id == 0x8021))) {
16505                 EL(ha, "HBA does not support MSI-X\n");
16506                 return (DDI_FAILURE);
16507         }
16508 
16509         if (CFG_IST(ha, CFG_CTRL_2422) && (ha->rev_id < 3)) {
16510                 EL(ha, "HBA does not support MSI-X (revid)\n");
16511                 return (DDI_FAILURE);
16512         }
16513 
16514         /* Per HP, these HP branded HBA's are not supported with MSI-X */
16515         if (ha->ven_id == 0x103C && (ha->subsys_id == 0x7041 ||
16516             ha->subsys_id == 0x7040 || ha->subsys_id == 0x1705)) {
16517                 EL(ha, "HBA does not support MSI-X (subdevid)\n");
16518                 return (DDI_FAILURE);
16519         }
16520 
16521         /* Get the number of 24xx/25xx MSI-X h/w vectors */
16522         hwvect = (uint16_t)(((CFG_IST(ha, CFG_CTRL_2422) ?
16523             ql_pci_config_get16(ha, 0x7e) :
16524             ql_pci_config_get16(ha, 0xa2)) & 0x3ff) + 1);
16525 
16526         EL(ha, "pcie config space hwvect = %d\n", hwvect);
16527 
16528         if (hwvect < QL_MSIX_MAXAIF) {
16529                 EL(ha, "failed, min h/w vectors req'd: %d, avail: %d\n",
16530                     QL_MSIX_MAXAIF, hwvect);
16531                 return (DDI_FAILURE);
16532         }
16533 
16534         /* Get number of MSI-X interrupts the platform h/w supports */
16535         if (((ret = ddi_intr_get_nintrs(ha->dip, msitype, &count)) !=
16536             DDI_SUCCESS) || count == 0) {
16537                 EL(ha, "failed, nintrs ret=%xh, cnt=%xh\n", ret, count);
16538                 return (DDI_FAILURE);
16539         }
16540 
16541         /* Get number of available system interrupts */
16542         if (((ret = ddi_intr_get_navail(ha->dip, msitype, &avail)) !=
16543             DDI_SUCCESS) || avail == 0) {
16544                 EL(ha, "failed, navail ret=%xh, avail=%xh\n", ret, avail);
16545                 return (DDI_FAILURE);
16546         }
16547 
16548         /* Fill out the intr table */
16549         count = QL_MSIX_MAXAIF;
16550         itrfun[QL_MSIX_AIF].ifunc = &ql_isr_aif;
16551         itrfun[QL_MSIX_RSPQ].ifunc = &ql_isr_aif;
16552 
16553         /* Allocate space for interrupt handles */
16554         ha->hsize = ((uint32_t)(sizeof (ddi_intr_handle_t)) * hwvect);
16555         if ((ha->htable = kmem_zalloc(ha->hsize, KM_SLEEP)) == NULL) {
16556                 ha->hsize = 0;
16557                 EL(ha, "failed, unable to allocate htable space\n");
16558                 return (DDI_FAILURE);
16559         }
16560 
16561         ha->iflags |= IFLG_INTR_MSIX;
16562 
16563         /* Allocate the interrupts */
16564         if (((ret = ddi_intr_alloc(ha->dip, ha->htable, msitype,
16565             DDI_INTR_ALLOC_NORMAL, count, &actual, 0)) != DDI_SUCCESS) ||
16566             actual < QL_MSIX_MAXAIF) {
16567                 EL(ha, "failed, intr_alloc ret=%xh, count = %xh, "
16568                     "actual=%xh\n", ret, count, actual);
16569                 ql_release_intr(ha);
16570                 return (DDI_FAILURE);
16571         }
16572 
16573         ha->intr_cnt = actual;
16574 
16575         /* Get interrupt priority */
16576         if ((ret = ddi_intr_get_pri(ha->htable[0], &ha->intr_pri)) !=
16577             DDI_SUCCESS) {
16578                 EL(ha, "failed, get_pri ret=%xh\n", ret);
16579                 ql_release_intr(ha);
16580                 return (ret);
16581         }
16582 
16583         /* Add the interrupt handlers */
16584         for (i = 0; i < actual; i++) {
16585                 if ((ret = ddi_intr_add_handler(ha->htable[i], itrfun[i].ifunc,
16586                     (void *)ha, (void *)((ulong_t)i))) != DDI_SUCCESS) {
16587                         EL(ha, "failed, addh#=%xh, act=%xh, ret=%xh\n", i,
16588                             actual, ret);
16589                         ql_release_intr(ha);
16590                         return (ret);
16591                 }
16592         }
16593 
16594         /*
16595          * duplicate the rest of the intr's
16596          * ddi_intr_dup_handler() isn't working on x86 just yet...
16597          */
16598 #ifdef __sparc
16599         for (i = actual; i < hwvect; i++) {
16600                 if ((ret = ddi_intr_dup_handler(ha->htable[0], (int)i,
16601                     &ha->htable[i])) != DDI_SUCCESS) {
16602                         EL(ha, "failed, intr_dup#=%xh, act=%xh, ret=%xh\n",
16603                             i, actual, ret);
16604                         ql_release_intr(ha);
16605                         return (ret);
16606                 }
16607         }
16608 #endif
16609 
16610         /* Setup mutexes */
16611         if ((ret = ql_init_mutex(ha)) != DDI_SUCCESS) {
16612                 EL(ha, "failed, mutex init ret=%xh\n", ret);
16613                 ql_release_intr(ha);
16614                 return (ret);
16615         }
16616 
16617         /* Get the capabilities */
16618         (void) ddi_intr_get_cap(ha->htable[0], &ha->intr_cap);
16619 
16620         /* Enable interrupts */
16621         if (ha->intr_cap & DDI_INTR_FLAG_BLOCK) {
16622                 if ((ret = ddi_intr_block_enable(ha->htable, ha->intr_cnt)) !=
16623                     DDI_SUCCESS) {
16624                         EL(ha, "failed, block enable, ret=%xh\n", ret);
16625                         ql_destroy_mutex(ha);
16626                         ql_release_intr(ha);
16627                         return (ret);
16628                 }
16629         } else {
16630                 for (i = 0; i < ha->intr_cnt; i++) {
16631                         if ((ret = ddi_intr_enable(ha->htable[i])) !=
16632                             DDI_SUCCESS) {
16633                                 EL(ha, "failed, intr enable, ret=%xh\n", ret);
16634                                 ql_destroy_mutex(ha);
16635                                 ql_release_intr(ha);
16636                                 return (ret);
16637                         }
16638                 }
16639         }
16640 
16641         QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
16642 
16643         return (DDI_SUCCESS);
16644 }
16645 
16646 /*
16647  * ql_setup_fixed
16648  *      Sets up aif FIXED interrupts
16649  *
16650  * Input:
16651  *      ha = adapter state pointer.
16652  *
16653  * Returns:
16654  *      DDI_SUCCESS or DDI_FAILURE.
16655  *
16656  * Context:
16657  *      Kernel context.
16658  */
16659 static int
16660 ql_setup_fixed(ql_adapter_state_t *ha)
16661 {
16662         int32_t         count = 0;
16663         int32_t         actual = 0;
16664         int32_t         ret;
16665         uint32_t        i;
16666 
16667         QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
16668 
16669         /* Get number of fixed interrupts the system supports */
16670         if (((ret = ddi_intr_get_nintrs(ha->dip, DDI_INTR_TYPE_FIXED,
16671             &count)) != DDI_SUCCESS) || count == 0) {
16672                 EL(ha, "failed, nintrs ret=%xh, cnt=%xh\n", ret, count);
16673                 return (DDI_FAILURE);
16674         }
16675 
16676         ha->iflags |= IFLG_INTR_FIXED;
16677 
16678         /* Allocate space for interrupt handles */
16679         ha->hsize = ((uint32_t)(sizeof (ddi_intr_handle_t)) * count);
16680         ha->htable = kmem_zalloc(ha->hsize, KM_SLEEP);
16681 
16682         /* Allocate the interrupts */
16683         if (((ret = ddi_intr_alloc(ha->dip, ha->htable, DDI_INTR_TYPE_FIXED,
16684             0, count, &actual, DDI_INTR_ALLOC_STRICT)) != DDI_SUCCESS) ||
16685             actual < count) {
16686                 EL(ha, "failed, intr_alloc ret=%xh, count=%xh, "
16687                     "actual=%xh\n", ret, count, actual);
16688                 ql_release_intr(ha);
16689                 return (DDI_FAILURE);
16690         }
16691 
16692         ha->intr_cnt = actual;
16693 
16694         /* Get interrupt priority */
16695         if ((ret = ddi_intr_get_pri(ha->htable[0], &ha->intr_pri)) !=
16696             DDI_SUCCESS) {
16697                 EL(ha, "failed, get_pri ret=%xh\n", ret);
16698                 ql_release_intr(ha);
16699                 return (ret);
16700         }
16701 
16702         /* Add the interrupt handlers */
16703         for (i = 0; i < ha->intr_cnt; i++) {
16704                 if ((ret = ddi_intr_add_handler(ha->htable[i], &ql_isr_aif,
16705                     (void *)ha, (void *)((ulong_t)(i)))) != DDI_SUCCESS) {
16706                         EL(ha, "failed, intr_add ret=%xh\n", ret);
16707                         ql_release_intr(ha);
16708                         return (ret);
16709                 }
16710         }
16711 
16712         /* Setup mutexes */
16713         if ((ret = ql_init_mutex(ha)) != DDI_SUCCESS) {
16714                 EL(ha, "failed, mutex init ret=%xh\n", ret);
16715                 ql_release_intr(ha);
16716                 return (ret);
16717         }
16718 
16719         /* Enable interrupts */
16720         for (i = 0; i < ha->intr_cnt; i++) {
16721                 if ((ret = ddi_intr_enable(ha->htable[i])) != DDI_SUCCESS) {
16722                         EL(ha, "failed, intr enable, ret=%xh\n", ret);
16723                         ql_destroy_mutex(ha);
16724                         ql_release_intr(ha);
16725                         return (ret);
16726                 }
16727         }
16728 
16729         EL(ha, "using FIXED interupts\n");
16730 
16731         QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
16732 
16733         return (DDI_SUCCESS);
16734 }
16735 
16736 /*
16737  * ql_disable_intr
16738  *      Disables interrupts
16739  *
16740  * Input:
16741  *      ha = adapter state pointer.
16742  *
16743  * Returns:
16744  *
16745  * Context:
16746  *      Kernel context.
16747  */
16748 static void
16749 ql_disable_intr(ql_adapter_state_t *ha)
16750 {
16751         uint32_t        i, rval;
16752 
16753         QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
16754 
16755         if (!(ha->iflags & IFLG_INTR_AIF)) {
16756 
16757                 /* Disable legacy interrupts */
16758                 (void) ddi_remove_intr(ha->dip, 0, ha->iblock_cookie);
16759 
16760         } else if ((ha->intr_cap & DDI_INTR_FLAG_BLOCK) &&
16761             (ha->iflags & (IFLG_INTR_MSI | IFLG_INTR_MSIX))) {
16762 
16763                 /* Remove AIF block interrupts (MSI) */
16764                 if ((rval = ddi_intr_block_disable(ha->htable, ha->intr_cnt))
16765                     != DDI_SUCCESS) {
16766                         EL(ha, "failed intr block disable, rval=%x\n", rval);
16767                 }
16768 
16769         } else {
16770 
16771                 /* Remove AIF non-block interrupts (fixed).  */
16772                 for (i = 0; i < ha->intr_cnt; i++) {
16773                         if ((rval = ddi_intr_disable(ha->htable[i])) !=
16774                             DDI_SUCCESS) {
16775                                 EL(ha, "failed intr disable, intr#=%xh, "
16776                                     "rval=%xh\n", i, rval);
16777                         }
16778                 }
16779         }
16780 
16781         QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
16782 }
16783 
16784 /*
16785  * ql_release_intr
16786  *      Releases aif legacy interrupt resources
16787  *
16788  * Input:
16789  *      ha = adapter state pointer.
16790  *
16791  * Returns:
16792  *
16793  * Context:
16794  *      Kernel context.
16795  */
16796 static void
16797 ql_release_intr(ql_adapter_state_t *ha)
16798 {
16799         int32_t         i;
16800 
16801         QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
16802 
16803         if (!(ha->iflags & IFLG_INTR_AIF)) {
16804                 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
16805                 return;
16806         }
16807 
16808         ha->iflags &= ~(IFLG_INTR_AIF);
16809         if (ha->htable != NULL && ha->hsize > 0) {
16810                 i = (int32_t)ha->hsize / (int32_t)sizeof (ddi_intr_handle_t);
16811                 while (i-- > 0) {
16812                         if (ha->htable[i] == 0) {
16813                                 EL(ha, "htable[%x]=0h\n", i);
16814                                 continue;
16815                         }
16816 
16817                         (void) ddi_intr_disable(ha->htable[i]);
16818 
16819                         if (i < ha->intr_cnt) {
16820                                 (void) ddi_intr_remove_handler(ha->htable[i]);
16821                         }
16822 
16823                         (void) ddi_intr_free(ha->htable[i]);
16824                 }
16825 
16826                 kmem_free(ha->htable, ha->hsize);
16827                 ha->htable = NULL;
16828         }
16829 
16830         ha->hsize = 0;
16831         ha->intr_cnt = 0;
16832         ha->intr_pri = 0;
16833         ha->intr_cap = 0;
16834 
16835         QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
16836 }
16837 
16838 /*
16839  * ql_legacy_intr
16840  *      Sets up legacy interrupts.
16841  *
16842  *      NB: Only to be used if AIF (Advanced Interupt Framework)
16843  *          if NOT in the kernel.
16844  *
16845  * Input:
16846  *      ha = adapter state pointer.
16847  *
16848  * Returns:
16849  *      DDI_SUCCESS or DDI_FAILURE.
16850  *
16851  * Context:
16852  *      Kernel context.
16853  */
16854 static int
16855 ql_legacy_intr(ql_adapter_state_t *ha)
16856 {
16857         int     rval = DDI_SUCCESS;
16858 
16859         QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
16860 
16861         /* Setup mutexes */
16862         if (ql_init_mutex(ha) != DDI_SUCCESS) {
16863                 EL(ha, "failed, mutex init\n");
16864                 return (DDI_FAILURE);
16865         }
16866 
16867         /* Setup standard/legacy interrupt handler */
16868         if (ddi_add_intr(ha->dip, (uint_t)0, &ha->iblock_cookie,
16869             (ddi_idevice_cookie_t *)0, ql_isr, (caddr_t)ha) != DDI_SUCCESS) {
16870                 cmn_err(CE_WARN, "%s(%d): Failed to add legacy interrupt",
16871                     QL_NAME, ha->instance);
16872                 ql_destroy_mutex(ha);
16873                 rval = DDI_FAILURE;
16874         }
16875 
16876         if (rval == DDI_SUCCESS) {
16877                 ha->iflags |= IFLG_INTR_LEGACY;
16878                 EL(ha, "using legacy interrupts\n");
16879         }
16880 
16881         QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
16882 
16883         return (rval);
16884 }
16885 
16886 /*
16887  * ql_init_mutex
16888  *      Initializes mutex's
16889  *
16890  * Input:
16891  *      ha = adapter state pointer.
16892  *
16893  * Returns:
16894  *      DDI_SUCCESS or DDI_FAILURE.
16895  *
16896  * Context:
16897  *      Kernel context.
16898  */
16899 static int
16900 ql_init_mutex(ql_adapter_state_t *ha)
16901 {
16902         int     ret;
16903         void    *intr;
16904 
16905         QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
16906 
16907         if (ha->iflags & IFLG_INTR_AIF) {
16908                 intr = (void *)(uintptr_t)ha->intr_pri;
16909         } else {
16910                 /* Get iblock cookies to initialize mutexes */
16911                 if ((ret = ddi_get_iblock_cookie(ha->dip, 0,
16912                     &ha->iblock_cookie)) != DDI_SUCCESS) {
16913                         EL(ha, "failed, get_iblock: %xh\n", ret);
16914                         return (DDI_FAILURE);
16915                 }
16916                 intr = (void *)ha->iblock_cookie;
16917         }
16918 
16919         /* mutexes to protect the adapter state structure. */
16920         mutex_init(&ha->mutex, NULL, MUTEX_DRIVER, intr);
16921 
16922         /* mutex to protect the ISP response ring. */
16923         mutex_init(&ha->intr_mutex, NULL, MUTEX_DRIVER, intr);
16924 
16925         /* mutex to protect the mailbox registers. */
16926         mutex_init(&ha->mbx_mutex, NULL, MUTEX_DRIVER, intr);
16927 
16928         /* power management protection */
16929         mutex_init(&ha->pm_mutex, NULL, MUTEX_DRIVER, intr);
16930 
16931         /* Mailbox wait and interrupt conditional variable. */
16932         cv_init(&ha->cv_mbx_wait, NULL, CV_DRIVER, NULL);
16933         cv_init(&ha->cv_mbx_intr, NULL, CV_DRIVER, NULL);
16934 
16935         /* mutex to protect the ISP request ring. */
16936         mutex_init(&ha->req_ring_mutex, NULL, MUTEX_DRIVER, intr);
16937 
16938         /* Unsolicited buffer conditional variable. */
16939         cv_init(&ha->cv_ub, NULL, CV_DRIVER, NULL);
16940 
16941         mutex_init(&ha->ub_mutex, NULL, MUTEX_DRIVER, intr);
16942         mutex_init(&ha->cache_mutex, NULL, MUTEX_DRIVER, intr);
16943 
16944         /* Suspended conditional variable. */
16945         cv_init(&ha->cv_dr_suspended, NULL, CV_DRIVER, NULL);
16946 
16947         /* mutex to protect task daemon context. */
16948         mutex_init(&ha->task_daemon_mutex, NULL, MUTEX_DRIVER, intr);
16949 
16950         /* Task_daemon thread conditional variable. */
16951         cv_init(&ha->cv_task_daemon, NULL, CV_DRIVER, NULL);
16952 
16953         /* mutex to protect diag port manage interface */
16954         mutex_init(&ha->portmutex, NULL, MUTEX_DRIVER, intr);
16955 
16956         /* mutex to protect per instance f/w dump flags and buffer */
16957         mutex_init(&ha->dump_mutex, NULL, MUTEX_DRIVER, intr);
16958 
16959         QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
16960 
16961         return (DDI_SUCCESS);
16962 }
16963 
16964 /*
16965  * ql_destroy_mutex
16966  *      Destroys mutex's
16967  *
16968  * Input:
16969  *      ha = adapter state pointer.
16970  *
16971  * Returns:
16972  *
16973  * Context:
16974  *      Kernel context.
16975  */
16976 static void
16977 ql_destroy_mutex(ql_adapter_state_t *ha)
16978 {
16979         QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
16980 
16981         mutex_destroy(&ha->dump_mutex);
16982         mutex_destroy(&ha->portmutex);
16983         cv_destroy(&ha->cv_task_daemon);
16984         mutex_destroy(&ha->task_daemon_mutex);
16985         cv_destroy(&ha->cv_dr_suspended);
16986         mutex_destroy(&ha->cache_mutex);
16987         mutex_destroy(&ha->ub_mutex);
16988         cv_destroy(&ha->cv_ub);
16989         mutex_destroy(&ha->req_ring_mutex);
16990         cv_destroy(&ha->cv_mbx_intr);
16991         cv_destroy(&ha->cv_mbx_wait);
16992         mutex_destroy(&ha->pm_mutex);
16993         mutex_destroy(&ha->mbx_mutex);
16994         mutex_destroy(&ha->intr_mutex);
16995         mutex_destroy(&ha->mutex);
16996 
16997         QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
16998 }
16999 
17000 /*
17001  * ql_fwmodule_resolve
17002  *      Loads and resolves external firmware module and symbols
17003  *
17004  * Input:
17005  *      ha:             adapter state pointer.
17006  *
17007  * Returns:
17008  *      ql local function return status code:
17009  *              QL_SUCCESS - external f/w module module and symbols resolved
17010  *              QL_FW_NOT_SUPPORTED - Driver does not support ISP type
17011  *              QL_FWMODLOAD_FAILED - Could not load f/w module (ddi failed)
17012  *              QL_FWSYM_NOT_FOUND - Unable to resolve internal f/w symbol
17013  * Context:
17014  *      Kernel context.
17015  *
17016  * NOTE: We currently ddi_modopen/ddi_modclose at attach/detach time.  We
17017  * could switch to a tighter scope around acutal download (and add an extra
17018  * ddi_modopen for module opens that occur before root is mounted).
17019  *
17020  */
17021 uint32_t
17022 ql_fwmodule_resolve(ql_adapter_state_t *ha)
17023 {
17024         int8_t                  module[128];
17025         int8_t                  fw_version[128];
17026         uint32_t                rval = QL_SUCCESS;
17027         caddr_t                 code, code02;
17028         uint8_t                 *p_ucfw;
17029         uint16_t                *p_usaddr, *p_uslen;
17030         uint32_t                *p_uiaddr, *p_uilen, *p_uifw;
17031         uint32_t                *p_uiaddr02, *p_uilen02;
17032         struct fw_table         *fwt;
17033         extern struct fw_table  fw_table[];
17034 
17035         QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
17036 
17037         if (ha->fw_module != NULL) {
17038                 EL(ha, "%x f/w module %d.%02d.%02d is already loaded\n",
17039                     ha->fw_class, ha->fw_major_version, ha->fw_minor_version,
17040                     ha->fw_subminor_version);
17041                 return (rval);
17042         }
17043 
17044         /* make sure the fw_class is in the fw_table of supported classes */
17045         for (fwt = &fw_table[0]; fwt->fw_version; fwt++) {
17046                 if (fwt->fw_class == ha->fw_class)
17047                         break;                  /* match */
17048         }
17049         if (fwt->fw_version == NULL) {
17050                 cmn_err(CE_WARN, "%s(%d): can't find f/w class %x "
17051                     "in driver's fw_table", QL_NAME, ha->instance,
17052                     ha->fw_class);
17053                 return (QL_FW_NOT_SUPPORTED);
17054         }
17055 
17056         /*
17057          * open the module related to the fw_class
17058          */
17059         (void) snprintf(module, sizeof (module), "misc/qlc/qlc_fw_%x",
17060             ha->fw_class);
17061 
17062         ha->fw_module = ddi_modopen(module, KRTLD_MODE_FIRST, NULL);
17063         if (ha->fw_module == NULL) {
17064                 cmn_err(CE_WARN, "%s(%d): can't load firmware file %s",
17065                     QL_NAME, ha->instance, module);
17066                 return (QL_FWMODLOAD_FAILED);
17067         }
17068 
17069         /*
17070          * resolve the fw module symbols, data types depend on fw_class
17071          */
17072 
17073         switch (ha->fw_class) {
17074         case 0x2200:
17075         case 0x2300:
17076         case 0x6322:
17077 
17078                 if ((code = ddi_modsym(ha->fw_module, "risc_code01",
17079                     NULL)) == NULL) {
17080                         rval = QL_FWSYM_NOT_FOUND;
17081                         EL(ha, "failed, f/w module %d rc01 symbol\n", module);
17082                 } else if ((p_usaddr = ddi_modsym(ha->fw_module,
17083                     "risc_code_addr01", NULL)) == NULL) {
17084                         rval = QL_FWSYM_NOT_FOUND;
17085                         EL(ha, "failed, f/w module %d rca01 symbol\n", module);
17086                 } else if ((p_uslen = ddi_modsym(ha->fw_module,
17087                     "risc_code_length01", NULL)) == NULL) {
17088                         rval = QL_FWSYM_NOT_FOUND;
17089                         EL(ha, "failed, f/w module %d rcl01 symbol\n", module);
17090                 } else if ((p_ucfw = ddi_modsym(ha->fw_module,
17091                     "firmware_version", NULL)) == NULL) {
17092                         rval = QL_FWSYM_NOT_FOUND;
17093                         EL(ha, "failed, f/w module %d fwver symbol\n", module);
17094                 }
17095 
17096                 if (rval == QL_SUCCESS) {
17097                         ha->risc_fw[0].code = code;
17098                         ha->risc_fw[0].addr = *p_usaddr;
17099                         ha->risc_fw[0].length = *p_uslen;
17100 
17101                         (void) snprintf(fw_version, sizeof (fw_version),
17102                             "%d.%02d.%02d", p_ucfw[0], p_ucfw[1], p_ucfw[2]);
17103                 }
17104                 break;
17105 
17106         case 0x2400:
17107         case 0x2500:
17108         case 0x8100:
17109 
17110                 if ((code = ddi_modsym(ha->fw_module, "risc_code01",
17111                     NULL)) == NULL) {
17112                         rval = QL_FWSYM_NOT_FOUND;
17113                         EL(ha, "failed, f/w module %d rc01 symbol\n", module);
17114                 } else if ((p_uiaddr = ddi_modsym(ha->fw_module,
17115                     "risc_code_addr01", NULL)) == NULL) {
17116                         rval = QL_FWSYM_NOT_FOUND;
17117                         EL(ha, "failed, f/w module %d rca01 symbol\n", module);
17118                 } else if ((p_uilen = ddi_modsym(ha->fw_module,
17119                     "risc_code_length01", NULL)) == NULL) {
17120                         rval = QL_FWSYM_NOT_FOUND;
17121                         EL(ha, "failed, f/w module %d rcl01 symbol\n", module);
17122                 } else if ((p_uifw = ddi_modsym(ha->fw_module,
17123                     "firmware_version", NULL)) == NULL) {
17124                         rval = QL_FWSYM_NOT_FOUND;
17125                         EL(ha, "failed, f/w module %d fwver symbol\n", module);
17126                 }
17127 
17128                 if ((code02 = ddi_modsym(ha->fw_module, "risc_code02",
17129                     NULL)) == NULL) {
17130                         rval = QL_FWSYM_NOT_FOUND;
17131                         EL(ha, "failed, f/w module %d rc02 symbol\n", module);
17132                 } else if ((p_uiaddr02 = ddi_modsym(ha->fw_module,
17133                     "risc_code_addr02", NULL)) == NULL) {
17134                         rval = QL_FWSYM_NOT_FOUND;
17135                         EL(ha, "failed, f/w module %d rca02 symbol\n", module);
17136                 } else if ((p_uilen02 = ddi_modsym(ha->fw_module,
17137                     "risc_code_length02", NULL)) == NULL) {
17138                         rval = QL_FWSYM_NOT_FOUND;
17139                         EL(ha, "failed, f/w module %d rcl02 symbol\n", module);
17140                 }
17141 
17142                 if (rval == QL_SUCCESS) {
17143                         ha->risc_fw[0].code = code;
17144                         ha->risc_fw[0].addr = *p_uiaddr;
17145                         ha->risc_fw[0].length = *p_uilen;
17146                         ha->risc_fw[1].code = code02;
17147                         ha->risc_fw[1].addr = *p_uiaddr02;
17148                         ha->risc_fw[1].length = *p_uilen02;
17149 
17150                         (void) snprintf(fw_version, sizeof (fw_version),
17151                             "%d.%02d.%02d", p_uifw[0], p_uifw[1], p_uifw[2]);
17152                 }
17153                 break;
17154 
17155         default:
17156                 EL(ha, "fw_class: '%x' is not supported\n", ha->fw_class);
17157                 rval = QL_FW_NOT_SUPPORTED;
17158         }
17159 
17160         if (rval != QL_SUCCESS) {
17161                 cmn_err(CE_WARN, "%s(%d): can't resolve firmware "
17162                     "module %s (%x)", QL_NAME, ha->instance, module, rval);
17163                 if (ha->fw_module != NULL) {
17164                         (void) ddi_modclose(ha->fw_module);
17165                         ha->fw_module = NULL;
17166                 }
17167         } else {
17168                 /*
17169                  * check for firmware version mismatch between module and
17170                  * compiled in fw_table version.
17171                  */
17172 
17173                 if (strcmp(fwt->fw_version, fw_version) != 0) {
17174 
17175                         /*
17176                          * If f/w / driver version mismatches then
17177                          * return a successful status -- however warn
17178                          * the user that this is NOT recommended.
17179                          */
17180 
17181                         cmn_err(CE_WARN, "%s(%d): driver / f/w version "
17182                             "mismatch for %x: driver-%s module-%s", QL_NAME,
17183                             ha->instance, ha->fw_class, fwt->fw_version,
17184                             fw_version);
17185 
17186                         ha->cfg_flags |= CFG_FW_MISMATCH;
17187                 } else {
17188                         ha->cfg_flags &= ~CFG_FW_MISMATCH;
17189                 }
17190         }
17191 
17192         QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
17193 
17194         return (rval);
17195 }
17196 
17197 /*
17198  * ql_port_state
17199  *      Set the state on all adapter ports.
17200  *
17201  * Input:
17202  *      ha:     parent adapter state pointer.
17203  *      state:  port state.
17204  *      flags:  task daemon flags to set.
17205  *
17206  * Context:
17207  *      Interrupt or Kernel context, no mailbox commands allowed.
17208  */
17209 void
17210 ql_port_state(ql_adapter_state_t *ha, uint32_t state, uint32_t flags)
17211 {
17212         ql_adapter_state_t      *vha;
17213 
17214         QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
17215 
17216         TASK_DAEMON_LOCK(ha);
17217         for (vha = ha->pha; vha != NULL; vha = vha->vp_next) {
17218                 if (FC_PORT_STATE_MASK(vha->state) != state) {
17219                         vha->state = state != FC_STATE_OFFLINE ?
17220                             (FC_PORT_SPEED_MASK(vha->state) | state) : state;
17221                         vha->task_daemon_flags |= flags;
17222                 }
17223         }
17224         ha->pha->task_daemon_flags |= flags & LOOP_DOWN;
17225         TASK_DAEMON_UNLOCK(ha);
17226 
17227         QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
17228 }
17229 
17230 /*
17231  * ql_el_trace_desc_ctor - Construct an extended logging trace descriptor.
17232  *
17233  * Input:       Pointer to the adapter state structure.
17234  * Returns:     Success or Failure.
17235  * Context:     Kernel context.
17236  */
17237 int
17238 ql_el_trace_desc_ctor(ql_adapter_state_t *ha)
17239 {
17240         int     rval = DDI_SUCCESS;
17241 
17242         QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
17243 
17244         ha->el_trace_desc =
17245             (el_trace_desc_t *)kmem_zalloc(sizeof (el_trace_desc_t), KM_SLEEP);
17246 
17247         if (ha->el_trace_desc == NULL) {
17248                 cmn_err(CE_WARN, "%s(%d): can't construct trace descriptor",
17249                     QL_NAME, ha->instance);
17250                 rval = DDI_FAILURE;
17251         } else {
17252                 ha->el_trace_desc->next           = 0;
17253                 ha->el_trace_desc->trace_buffer =
17254                     (char *)kmem_zalloc(EL_TRACE_BUF_SIZE, KM_SLEEP);
17255 
17256                 if (ha->el_trace_desc->trace_buffer == NULL) {
17257                         cmn_err(CE_WARN, "%s(%d): can't get trace buffer",
17258                             QL_NAME, ha->instance);
17259                         kmem_free(ha->el_trace_desc, sizeof (el_trace_desc_t));
17260                         rval = DDI_FAILURE;
17261                 } else {
17262                         ha->el_trace_desc->trace_buffer_size =
17263                             EL_TRACE_BUF_SIZE;
17264                         mutex_init(&ha->el_trace_desc->mutex, NULL,
17265                             MUTEX_DRIVER, NULL);
17266                 }
17267         }
17268 
17269         QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
17270 
17271         return (rval);
17272 }
17273 
17274 /*
17275  * ql_el_trace_desc_dtor - Destroy an extended logging trace descriptor.
17276  *
17277  * Input:       Pointer to the adapter state structure.
17278  * Returns:     Success or Failure.
17279  * Context:     Kernel context.
17280  */
17281 int
17282 ql_el_trace_desc_dtor(ql_adapter_state_t *ha)
17283 {
17284         int     rval = DDI_SUCCESS;
17285 
17286         QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
17287 
17288         if (ha->el_trace_desc == NULL) {
17289                 cmn_err(CE_WARN, "%s(%d): can't destroy el trace descriptor",
17290                     QL_NAME, ha->instance);
17291                 rval = DDI_FAILURE;
17292         } else {
17293                 if (ha->el_trace_desc->trace_buffer != NULL) {
17294                         kmem_free(ha->el_trace_desc->trace_buffer,
17295                             ha->el_trace_desc->trace_buffer_size);
17296                 }
17297                 mutex_destroy(&ha->el_trace_desc->mutex);
17298                 kmem_free(ha->el_trace_desc, sizeof (el_trace_desc_t));
17299         }
17300 
17301         QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
17302 
17303         return (rval);
17304 }
17305 
17306 /*
17307  * els_cmd_text - Return a pointer to a string describing the command
17308  *
17309  * Input:       els_cmd = the els command opcode.
17310  * Returns:     pointer to a string.
17311  * Context:     Kernel context.
17312  */
17313 char *
17314 els_cmd_text(int els_cmd)
17315 {
17316         cmd_table_t *entry = &els_cmd_tbl[0];
17317 
17318         return (cmd_text(entry, els_cmd));
17319 }
17320 
17321 /*
17322  * mbx_cmd_text - Return a pointer to a string describing the command
17323  *
17324  * Input:       mbx_cmd = the mailbox command opcode.
17325  * Returns:     pointer to a string.
17326  * Context:     Kernel context.
17327  */
17328 char *
17329 mbx_cmd_text(int mbx_cmd)
17330 {
17331         cmd_table_t *entry = &mbox_cmd_tbl[0];
17332 
17333         return (cmd_text(entry, mbx_cmd));
17334 }
17335 
17336 /*
17337  * cmd_text     Return a pointer to a string describing the command
17338  *
17339  * Input:       entry = the command table
17340  *              cmd = the command.
17341  * Returns:     pointer to a string.
17342  * Context:     Kernel context.
17343  */
17344 char *
17345 cmd_text(cmd_table_t *entry, int cmd)
17346 {
17347         for (; entry->cmd != 0; entry++) {
17348                 if (entry->cmd == cmd) {
17349                         break;
17350                 }
17351         }
17352         return (entry->string);
17353 }
17354 
17355 /*
17356  * ql_els_24xx_mbox_cmd_iocb - els request indication.
17357  *
17358  * Input:       ha = adapter state pointer.
17359  *              srb = scsi request block pointer.
17360  *              arg = els passthru entry iocb pointer.
17361  * Returns:
17362  * Context:     Kernel context.
17363  */
17364 void
17365 ql_els_24xx_iocb(ql_adapter_state_t *ha, ql_srb_t *srb, void *arg)
17366 {
17367         els_descriptor_t        els_desc;
17368 
17369         /* Extract the ELS information */
17370         ql_fca_isp_els_request(ha, (fc_packet_t *)srb->pkt, &els_desc);
17371 
17372         /* Construct the passthru entry */
17373         ql_isp_els_request_ctor(&els_desc, (els_passthru_entry_t *)arg);
17374 
17375         /* Ensure correct endianness */
17376         ql_isp_els_handle_cmd_endian(ha, srb);
17377 }
17378 
17379 /*
17380  * ql_fca_isp_els_request - Extract into an els descriptor the info required
17381  *                          to build an els_passthru iocb from an fc packet.
17382  *
17383  * Input:       ha = adapter state pointer.
17384  *              pkt = fc packet pointer
17385  *              els_desc = els descriptor pointer
17386  * Returns:
17387  * Context:     Kernel context.
17388  */
17389 static void
17390 ql_fca_isp_els_request(ql_adapter_state_t *ha, fc_packet_t *pkt,
17391     els_descriptor_t *els_desc)
17392 {
17393         ls_code_t       els;
17394 
17395         ddi_rep_get8(pkt->pkt_cmd_acc, (uint8_t *)&els,
17396             (uint8_t *)pkt->pkt_cmd, sizeof (els), DDI_DEV_AUTOINCR);
17397 
17398         els_desc->els = els.ls_code;
17399 
17400         els_desc->els_handle = ha->hba_buf.acc_handle;
17401         els_desc->d_id.b24 = pkt->pkt_cmd_fhdr.d_id;
17402         els_desc->s_id.b24 = pkt->pkt_cmd_fhdr.s_id;
17403         /* if n_port_handle is not < 0x7d use 0 */
17404         if (LOCAL_LOOP_ID(ha->n_port->n_port_handle)) {
17405                 els_desc->n_port_handle = ha->n_port->n_port_handle;
17406         } else {
17407                 els_desc->n_port_handle = 0;
17408         }
17409         els_desc->control_flags = 0;
17410         els_desc->cmd_byte_count = pkt->pkt_cmdlen;
17411         /*
17412          * Transmit DSD. This field defines the Fibre Channel Frame payload
17413          * (without the frame header) in system memory.
17414          */
17415         els_desc->tx_dsd.addr[0] = LSD(pkt->pkt_cmd_cookie->dmac_laddress);
17416         els_desc->tx_dsd.addr[1] = MSD(pkt->pkt_cmd_cookie->dmac_laddress);
17417         els_desc->tx_dsd.length = (uint32_t)pkt->pkt_cmd_cookie->dmac_size;
17418 
17419         els_desc->rsp_byte_count = pkt->pkt_rsplen;
17420         /*
17421          * Receive DSD. This field defines the ELS response payload buffer
17422          * for the ISP24xx firmware transferring the received ELS
17423          * response frame to a location in host memory.
17424          */
17425         els_desc->rx_dsd.addr[0] = LSD(pkt->pkt_resp_cookie->dmac_laddress);
17426         els_desc->rx_dsd.addr[1] = MSD(pkt->pkt_resp_cookie->dmac_laddress);
17427         els_desc->rx_dsd.length = (uint32_t)pkt->pkt_resp_cookie->dmac_size;
17428 }
17429 
17430 /*
17431  * ql_isp_els_request_ctor - Construct an els_passthru_entry iocb
17432  * using the els descriptor.
17433  *
17434  * Input:       ha = adapter state pointer.
17435  *              els_desc = els descriptor pointer.
17436  *              els_entry = els passthru entry iocb pointer.
17437  * Returns:
17438  * Context:     Kernel context.
17439  */
17440 static void
17441 ql_isp_els_request_ctor(els_descriptor_t *els_desc,
17442     els_passthru_entry_t *els_entry)
17443 {
17444         uint32_t        *ptr32;
17445 
17446         /*
17447          * Construct command packet.
17448          */
17449         ddi_put8(els_desc->els_handle, &els_entry->entry_type,
17450             (uint8_t)ELS_PASSTHRU_TYPE);
17451         ddi_put16(els_desc->els_handle, &els_entry->n_port_hdl,
17452             els_desc->n_port_handle);
17453         ddi_put8(els_desc->els_handle, &els_entry->sof_type, (uint8_t)BIT_4);
17454         ddi_put32(els_desc->els_handle, &els_entry->rcv_exch_address,
17455             (uint32_t)0);
17456         ddi_put8(els_desc->els_handle, &els_entry->els_cmd_opcode,
17457             els_desc->els);
17458         ddi_put8(els_desc->els_handle, &els_entry->d_id_7_0,
17459             els_desc->d_id.b.al_pa);
17460         ddi_put8(els_desc->els_handle, &els_entry->d_id_15_8,
17461             els_desc->d_id.b.area);
17462         ddi_put8(els_desc->els_handle, &els_entry->d_id_23_16,
17463             els_desc->d_id.b.domain);
17464         ddi_put8(els_desc->els_handle, &els_entry->s_id_7_0,
17465             els_desc->s_id.b.al_pa);
17466         ddi_put8(els_desc->els_handle, &els_entry->s_id_15_8,
17467             els_desc->s_id.b.area);
17468         ddi_put8(els_desc->els_handle, &els_entry->s_id_23_16,
17469             els_desc->s_id.b.domain);
17470         ddi_put16(els_desc->els_handle, &els_entry->control_flags,
17471             els_desc->control_flags);
17472         ddi_put32(els_desc->els_handle, &els_entry->rcv_payld_data_bcnt,
17473             els_desc->rsp_byte_count);
17474         ddi_put32(els_desc->els_handle, &els_entry->xmt_payld_data_bcnt,
17475             els_desc->cmd_byte_count);
17476         /* Load transmit data segments and count. */
17477         ptr32 = (uint32_t *)&els_entry->xmt_dseg_0_address;
17478         ddi_put16(els_desc->els_handle, &els_entry->xmt_dseg_count, 1);
17479         ddi_put32(els_desc->els_handle, ptr32++, els_desc->tx_dsd.addr[0]);
17480         ddi_put32(els_desc->els_handle, ptr32++, els_desc->tx_dsd.addr[1]);
17481         ddi_put32(els_desc->els_handle, ptr32++, els_desc->tx_dsd.length);
17482         ddi_put16(els_desc->els_handle, &els_entry->rcv_dseg_count, 1);
17483         ddi_put32(els_desc->els_handle, ptr32++, els_desc->rx_dsd.addr[0]);
17484         ddi_put32(els_desc->els_handle, ptr32++, els_desc->rx_dsd.addr[1]);
17485         ddi_put32(els_desc->els_handle, ptr32++, els_desc->rx_dsd.length);
17486 }
17487 
17488 /*
17489  * ql_isp_els_handle_cmd_endian - els requests must be in big endian
17490  *                                in host memory.
17491  *
17492  * Input:       ha = adapter state pointer.
17493  *              srb = scsi request block
17494  * Returns:
17495  * Context:     Kernel context.
17496  */
17497 void
17498 ql_isp_els_handle_cmd_endian(ql_adapter_state_t *ha, ql_srb_t *srb)
17499 {
17500         ls_code_t       els;
17501         fc_packet_t     *pkt;
17502         uint8_t         *ptr;
17503 
17504         pkt = srb->pkt;
17505 
17506         ddi_rep_get8(pkt->pkt_cmd_acc, (uint8_t *)&els,
17507             (uint8_t *)pkt->pkt_cmd, sizeof (els), DDI_DEV_AUTOINCR);
17508 
17509         ptr = (uint8_t *)pkt->pkt_cmd;
17510 
17511         ql_isp_els_handle_endian(ha, ptr, els.ls_code);
17512 }
17513 
17514 /*
17515  * ql_isp_els_handle_rsp_endian - els responses must be in big endian
17516  *                                in host memory.
17517  * Input:       ha = adapter state pointer.
17518  *              srb = scsi request block
17519  * Returns:
17520  * Context:     Kernel context.
17521  */
17522 void
17523 ql_isp_els_handle_rsp_endian(ql_adapter_state_t *ha, ql_srb_t *srb)
17524 {
17525         ls_code_t       els;
17526         fc_packet_t     *pkt;
17527         uint8_t         *ptr;
17528 
17529         pkt = srb->pkt;
17530 
17531         ddi_rep_get8(pkt->pkt_cmd_acc, (uint8_t *)&els,
17532             (uint8_t *)pkt->pkt_cmd, sizeof (els), DDI_DEV_AUTOINCR);
17533 
17534         ptr = (uint8_t *)pkt->pkt_resp;
17535         BIG_ENDIAN_32(&els);
17536         ql_isp_els_handle_endian(ha, ptr, els.ls_code);
17537 }
17538 
17539 /*
17540  * ql_isp_els_handle_endian - els requests/responses must be in big endian
17541  *                            in host memory.
17542  * Input:       ha = adapter state pointer.
17543  *              ptr = els request/response buffer pointer.
17544  *              ls_code = els command code.
17545  * Returns:
17546  * Context:     Kernel context.
17547  */
17548 void
17549 ql_isp_els_handle_endian(ql_adapter_state_t *ha, uint8_t *ptr, uint8_t ls_code)
17550 {
17551         switch (ls_code) {
17552         case LA_ELS_PLOGI: {
17553                 BIG_ENDIAN_32(ptr);     /* Command Code */
17554                 ptr += 4;
17555                 BIG_ENDIAN_16(ptr);     /* FC-PH version */
17556                 ptr += 2;
17557                 BIG_ENDIAN_16(ptr);     /* b2b credit */
17558                 ptr += 2;
17559                 BIG_ENDIAN_16(ptr);     /* Cmn Feature flags */
17560                 ptr += 2;
17561                 BIG_ENDIAN_16(ptr);     /* Rcv data size */
17562                 ptr += 2;
17563                 BIG_ENDIAN_16(ptr);     /* Concurrent Seq */
17564                 ptr += 2;
17565                 BIG_ENDIAN_16(ptr);     /* Rel offset */
17566                 ptr += 2;
17567                 BIG_ENDIAN_32(ptr);     /* E_D_TOV */
17568                 ptr += 4;               /* Port Name */
17569                 ptr += 8;               /* Node Name */
17570                 ptr += 8;               /* Class 1 */
17571                 ptr += 16;              /* Class 2 */
17572                 ptr += 16;              /* Class 3 */
17573                 BIG_ENDIAN_16(ptr);     /* Service options */
17574                 ptr += 2;
17575                 BIG_ENDIAN_16(ptr);     /* Initiator control */
17576                 ptr += 2;
17577                 BIG_ENDIAN_16(ptr);     /* Recipient Control */
17578                 ptr += 2;
17579                 BIG_ENDIAN_16(ptr);     /* Rcv size */
17580                 ptr += 2;
17581                 BIG_ENDIAN_16(ptr);     /* Concurrent Seq */
17582                 ptr += 2;
17583                 BIG_ENDIAN_16(ptr);     /* N_Port e2e credit */
17584                 ptr += 2;
17585                 BIG_ENDIAN_16(ptr);     /* Open Seq/Exch */
17586                 break;
17587         }
17588         case LA_ELS_PRLI: {
17589                 BIG_ENDIAN_32(ptr);     /* Command Code/Page length */
17590                 ptr += 4;               /* Type */
17591                 ptr += 2;
17592                 BIG_ENDIAN_16(ptr);     /* Flags */
17593                 ptr += 2;
17594                 BIG_ENDIAN_32(ptr);     /* Originator Process associator  */
17595                 ptr += 4;
17596                 BIG_ENDIAN_32(ptr);     /* Responder Process associator */
17597                 ptr += 4;
17598                 BIG_ENDIAN_32(ptr);     /* Flags */
17599                 break;
17600         }
17601         default:
17602                 EL(ha, "can't handle els code %x\n", ls_code);
17603                 break;
17604         }
17605 }
17606 
17607 /*
17608  * ql_n_port_plogi
17609  *      In N port 2 N port topology where an N Port has logged in with the
17610  *      firmware because it has the N_Port login initiative, we send up
17611  *      a plogi by proxy which stimulates the login procedure to continue.
17612  *
17613  * Input:
17614  *      ha = adapter state pointer.
17615  * Returns:
17616  *
17617  * Context:
17618  *      Kernel context.
17619  */
17620 static int
17621 ql_n_port_plogi(ql_adapter_state_t *ha)
17622 {
17623         int             rval;
17624         ql_tgt_t        *tq;
17625         ql_head_t done_q = { NULL, NULL };
17626 
17627         rval = QL_SUCCESS;
17628 
17629         if (ha->topology & QL_N_PORT) {
17630                 /* if we're doing this the n_port_handle must be good */
17631                 if (LOCAL_LOOP_ID(ha->n_port->n_port_handle)) {
17632                         tq = ql_loop_id_to_queue(ha,
17633                             ha->n_port->n_port_handle);
17634                         if (tq != NULL) {
17635                                 (void) ql_send_plogi(ha, tq, &done_q);
17636                         } else {
17637                                 EL(ha, "n_port_handle = %x, tq = %x\n",
17638                                     ha->n_port->n_port_handle, tq);
17639                         }
17640                 } else {
17641                         EL(ha, "n_port_handle = %x, tq = %x\n",
17642                             ha->n_port->n_port_handle, tq);
17643                 }
17644                 if (done_q.first != NULL) {
17645                         ql_done(done_q.first);
17646                 }
17647         }
17648         return (rval);
17649 }
17650 
17651 /*
17652  * Compare two WWNs. The NAA is omitted for comparison.
17653  *
17654  * Note particularly that the indentation used in this
17655  * function  isn't according to Sun recommendations. It
17656  * is indented to make reading a bit easy.
17657  *
17658  * Return Values:
17659  *   if first == second return  0
17660  *   if first > second  return  1
17661  *   if first < second  return -1
17662  */
17663 int
17664 ql_wwn_cmp(ql_adapter_state_t *ha, la_wwn_t *first, la_wwn_t *second)
17665 {
17666         la_wwn_t t1, t2;
17667         int rval;
17668 
17669         EL(ha, "WWPN=%08x%08x\n",
17670             BE_32(first->i_wwn[0]), BE_32(first->i_wwn[1]));
17671         EL(ha, "WWPN=%08x%08x\n",
17672             BE_32(second->i_wwn[0]), BE_32(second->i_wwn[1]));
17673         /*
17674          * Fibre Channel protocol is big endian, so compare
17675          * as big endian values
17676          */
17677         t1.i_wwn[0] = BE_32(first->i_wwn[0]);
17678         t1.i_wwn[1] = BE_32(first->i_wwn[1]);
17679 
17680         t2.i_wwn[0] = BE_32(second->i_wwn[0]);
17681         t2.i_wwn[1] = BE_32(second->i_wwn[1]);
17682 
17683         if (t1.i_wwn[0] == t2.i_wwn[0]) {
17684                 if (t1.i_wwn[1] == t2.i_wwn[1]) {
17685                         rval = 0;
17686                 } else if (t1.i_wwn[1] > t2.i_wwn[1]) {
17687                         rval = 1;
17688                 } else {
17689                         rval = -1;
17690                 }
17691         } else {
17692                 if (t1.i_wwn[0] > t2.i_wwn[0]) {
17693                         rval = 1;
17694                 } else {
17695                         rval = -1;
17696                 }
17697         }
17698         return (rval);
17699 }
17700 
17701 /*
17702  * ql_wait_for_td_stop
17703  *      Wait for task daemon to stop running.  Internal command timeout
17704  *      is approximately 30 seconds, so it may help in some corner
17705  *      cases to wait that long
17706  *
17707  * Input:
17708  *      ha = adapter state pointer.
17709  *
17710  * Returns:
17711  *      DDI_SUCCESS or DDI_FAILURE.
17712  *
17713  * Context:
17714  *      Kernel context.
17715  */
17716 
17717 static int
17718 ql_wait_for_td_stop(ql_adapter_state_t *ha)
17719 {
17720         int     rval = DDI_FAILURE;
17721         UINT16  wait_cnt;
17722 
17723         for (wait_cnt = 0; wait_cnt < 3000; wait_cnt++) {
17724                 /* The task daemon clears the stop flag on exit. */
17725                 if (ha->task_daemon_flags & TASK_DAEMON_STOP_FLG) {
17726                         if (ha->cprinfo.cc_events & CALLB_CPR_START ||
17727                             ddi_in_panic()) {
17728                                 drv_usecwait(10000);
17729                         } else {
17730                                 delay(drv_usectohz(10000));
17731                         }
17732                 } else {
17733                         rval = DDI_SUCCESS;
17734                         break;
17735                 }
17736         }
17737         return (rval);
17738 }
17739 
17740 /*
17741  * ql_nvram_cache_desc_ctor - Construct an nvram cache descriptor.
17742  *
17743  * Input:       Pointer to the adapter state structure.
17744  * Returns:     Success or Failure.
17745  * Context:     Kernel context.
17746  */
17747 int
17748 ql_nvram_cache_desc_ctor(ql_adapter_state_t *ha)
17749 {
17750         int     rval = DDI_SUCCESS;
17751 
17752         QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
17753 
17754         ha->nvram_cache =
17755             (nvram_cache_desc_t *)kmem_zalloc(sizeof (nvram_cache_desc_t),
17756             KM_SLEEP);
17757 
17758         if (ha->nvram_cache == NULL) {
17759                 cmn_err(CE_WARN, "%s(%d): can't construct nvram cache"
17760                     " descriptor", QL_NAME, ha->instance);
17761                 rval = DDI_FAILURE;
17762         } else {
17763                 if (CFG_IST(ha, CFG_CTRL_24258081)) {
17764                         ha->nvram_cache->size = sizeof (nvram_24xx_t);
17765                 } else {
17766                         ha->nvram_cache->size = sizeof (nvram_t);
17767                 }
17768                 ha->nvram_cache->cache =
17769                     (void *)kmem_zalloc(ha->nvram_cache->size, KM_SLEEP);
17770                 if (ha->nvram_cache->cache == NULL) {
17771                         cmn_err(CE_WARN, "%s(%d): can't get nvram cache buffer",
17772                             QL_NAME, ha->instance);
17773                         kmem_free(ha->nvram_cache,
17774                             sizeof (nvram_cache_desc_t));
17775                         ha->nvram_cache = 0;
17776                         rval = DDI_FAILURE;
17777                 } else {
17778                         mutex_init(&ha->nvram_cache->mutex, NULL,
17779                             MUTEX_DRIVER, NULL);
17780                         ha->nvram_cache->valid = 0;
17781                 }
17782         }
17783 
17784         QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
17785 
17786         return (rval);
17787 }
17788 
17789 /*
17790  * ql_nvram_cache_desc_dtor - Destroy an nvram cache descriptor.
17791  *
17792  * Input:       Pointer to the adapter state structure.
17793  * Returns:     Success or Failure.
17794  * Context:     Kernel context.
17795  */
17796 int
17797 ql_nvram_cache_desc_dtor(ql_adapter_state_t *ha)
17798 {
17799         int     rval = DDI_SUCCESS;
17800 
17801         QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
17802 
17803         if (ha->nvram_cache == NULL) {
17804                 cmn_err(CE_WARN, "%s(%d): can't destroy nvram descriptor",
17805                     QL_NAME, ha->instance);
17806                 rval = DDI_FAILURE;
17807         } else {
17808                 if (ha->nvram_cache->cache != NULL) {
17809                         kmem_free(ha->nvram_cache->cache,
17810                             ha->nvram_cache->size);
17811                 }
17812                 mutex_destroy(&ha->nvram_cache->mutex);
17813                 kmem_free(ha->nvram_cache, sizeof (nvram_cache_desc_t));
17814         }
17815 
17816         QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
17817 
17818         return (rval);
17819 }
17820 
17821 /*
17822  * ql_process_idc_event - Handle an Inter-Driver Communication async event.
17823  *
17824  * Input:       Pointer to the adapter state structure.
17825  * Returns:     void
17826  * Context:     Kernel context.
17827  */
17828 static void
17829 ql_process_idc_event(ql_adapter_state_t *ha)
17830 {
17831         int     rval;
17832 
17833         switch (ha->idc_mb[0]) {
17834         case MBA_IDC_NOTIFICATION:
17835                 /*
17836                  * The informational opcode (idc_mb[2]) can be a
17837                  * defined value or the mailbox command being executed
17838                  * on another function which stimulated this IDC message.
17839                  */
17840                 ADAPTER_STATE_LOCK(ha);
17841                 switch (ha->idc_mb[2]) {
17842                 case IDC_OPC_DRV_START:
17843                         if (ha->idc_flash_acc != 0) {
17844                                 ha->idc_flash_acc--;
17845                                 if (ha->idc_flash_acc == 0) {
17846                                         ha->idc_flash_acc_timer = 0;
17847                                         GLOBAL_HW_UNLOCK();
17848                                 }
17849                         }
17850                         if (ha->idc_restart_cnt != 0) {
17851                                 ha->idc_restart_cnt--;
17852                                 if (ha->idc_restart_cnt == 0) {
17853                                         ha->idc_restart_timer = 0;
17854                                         ADAPTER_STATE_UNLOCK(ha);
17855                                         TASK_DAEMON_LOCK(ha);
17856                                         ha->task_daemon_flags &= ~DRIVER_STALL;
17857                                         TASK_DAEMON_UNLOCK(ha);
17858                                         ql_restart_queues(ha);
17859                                 } else {
17860                                         ADAPTER_STATE_UNLOCK(ha);
17861                                 }
17862                         } else {
17863                                 ADAPTER_STATE_UNLOCK(ha);
17864                         }
17865                         break;
17866                 case IDC_OPC_FLASH_ACC:
17867                         ha->idc_flash_acc_timer = 30;
17868                         if (ha->idc_flash_acc == 0) {
17869                                 GLOBAL_HW_LOCK();
17870                         }
17871                         ha->idc_flash_acc++;
17872                         ADAPTER_STATE_UNLOCK(ha);
17873                         break;
17874                 case IDC_OPC_RESTART_MPI:
17875                         ha->idc_restart_timer = 30;
17876                         ha->idc_restart_cnt++;
17877                         ADAPTER_STATE_UNLOCK(ha);
17878                         TASK_DAEMON_LOCK(ha);
17879                         ha->task_daemon_flags |= DRIVER_STALL;
17880                         TASK_DAEMON_UNLOCK(ha);
17881                         break;
17882                 case IDC_OPC_PORT_RESET_MBC:
17883                 case IDC_OPC_SET_PORT_CONFIG_MBC:
17884                         ha->idc_restart_timer = 30;
17885                         ha->idc_restart_cnt++;
17886                         ADAPTER_STATE_UNLOCK(ha);
17887                         TASK_DAEMON_LOCK(ha);
17888                         ha->task_daemon_flags |= DRIVER_STALL;
17889                         TASK_DAEMON_UNLOCK(ha);
17890                         (void) ql_wait_outstanding(ha);
17891                         break;
17892                 default:
17893                         ADAPTER_STATE_UNLOCK(ha);
17894                         EL(ha, "Unknown IDC opcode=%xh %xh\n", ha->idc_mb[0],
17895                             ha->idc_mb[2]);
17896                         break;
17897                 }
17898                 /*
17899                  * If there is a timeout value associated with this IDC
17900                  * notification then there is an implied requirement
17901                  * that we return an ACK.
17902                  */
17903                 if (ha->idc_mb[1] & IDC_TIMEOUT_MASK) {
17904                         rval = ql_idc_ack(ha);
17905                         if (rval != QL_SUCCESS) {
17906                                 EL(ha, "idc_ack status=%xh %xh\n", rval,
17907                                     ha->idc_mb[2]);
17908                         }
17909                 }
17910                 break;
17911         case MBA_IDC_COMPLETE:
17912                 /*
17913                  * We don't ACK completions, only these require action.
17914                  */
17915                 switch (ha->idc_mb[2]) {
17916                 case IDC_OPC_PORT_RESET_MBC:
17917                 case IDC_OPC_SET_PORT_CONFIG_MBC:
17918                         ADAPTER_STATE_LOCK(ha);
17919                         if (ha->idc_restart_cnt != 0) {
17920                                 ha->idc_restart_cnt--;
17921                                 if (ha->idc_restart_cnt == 0) {
17922                                         ha->idc_restart_timer = 0;
17923                                         ADAPTER_STATE_UNLOCK(ha);
17924                                         TASK_DAEMON_LOCK(ha);
17925                                         ha->task_daemon_flags &= ~DRIVER_STALL;
17926                                         TASK_DAEMON_UNLOCK(ha);
17927                                         ql_restart_queues(ha);
17928                                 } else {
17929                                         ADAPTER_STATE_UNLOCK(ha);
17930                                 }
17931                         } else {
17932                                 ADAPTER_STATE_UNLOCK(ha);
17933                         }
17934                         break;
17935                 default:
17936                         break; /* Don't care... */
17937                 }
17938                 break;
17939         case MBA_IDC_TIME_EXTENDED:
17940                 QL_PRINT_10(CE_CONT, "(%d): MBA_IDC_TIME_EXTENDED="
17941                     "%xh\n", ha->instance, ha->idc_mb[2]);
17942                 break;
17943         default:
17944                 EL(ha, "Inconsistent IDC event =%xh %xh\n", ha->idc_mb[0],
17945                     ha->idc_mb[2]);
17946                 ADAPTER_STATE_UNLOCK(ha);
17947                 break;
17948         }
17949 }