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 2009 QLogic Corporation */ 23 24 /* 25 * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 26 * Use is subject to license terms. 27 */ 28 29 #pragma ident "Copyright 2009 QLogic Corporation; ql_api.c" 30 31 /* 32 * ISP2xxx Solaris Fibre Channel Adapter (FCA) driver source file. 33 * 34 * *********************************************************************** 35 * * ** 36 * * NOTICE ** 37 * * COPYRIGHT (C) 1996-2009 QLOGIC CORPORATION ** 38 * * ALL RIGHTS RESERVED ** 39 * * ** 40 * *********************************************************************** 41 * 42 */ 43 44 #include <ql_apps.h> 45 #include <ql_api.h> 46 #include <ql_debug.h> 47 #include <ql_init.h> 48 #include <ql_iocb.h> 49 #include <ql_ioctl.h> 50 #include <ql_isr.h> 51 #include <ql_mbx.h> 52 #include <ql_xioctl.h> 53 54 /* 55 * Solaris external defines. 56 */ 57 extern pri_t minclsyspri; 58 extern pri_t maxclsyspri; 59 60 /* 61 * dev_ops functions prototypes 62 */ 63 static int ql_getinfo(dev_info_t *, ddi_info_cmd_t, void *, void **); 64 static int ql_attach(dev_info_t *, ddi_attach_cmd_t); 65 static int ql_detach(dev_info_t *, ddi_detach_cmd_t); 66 static int ql_power(dev_info_t *, int, int); 67 static int ql_quiesce(dev_info_t *); 68 69 /* 70 * FCA functions prototypes exported by means of the transport table 71 */ 72 static opaque_t ql_bind_port(dev_info_t *, fc_fca_port_info_t *, 73 fc_fca_bind_info_t *); 74 static void ql_unbind_port(opaque_t); 75 static int ql_init_pkt(opaque_t, fc_packet_t *, int); 76 static int ql_un_init_pkt(opaque_t, fc_packet_t *); 77 static int ql_els_send(opaque_t, fc_packet_t *); 78 static int ql_get_cap(opaque_t, char *, void *); 79 static int ql_set_cap(opaque_t, char *, void *); 80 static int ql_getmap(opaque_t, fc_lilpmap_t *); 81 static int ql_transport(opaque_t, fc_packet_t *); 82 static int ql_ub_alloc(opaque_t, uint64_t *, uint32_t, uint32_t *, uint32_t); 83 static int ql_ub_free(opaque_t, uint32_t, uint64_t *); 84 static int ql_ub_release(opaque_t, uint32_t, uint64_t *); 85 static int ql_abort(opaque_t, fc_packet_t *, int); 86 static int ql_reset(opaque_t, uint32_t); 87 static int ql_port_manage(opaque_t, fc_fca_pm_t *); 88 static opaque_t ql_get_device(opaque_t, fc_portid_t); 89 90 /* 91 * FCA Driver Support Function Prototypes. 92 */ 93 static uint16_t ql_wait_outstanding(ql_adapter_state_t *); 94 static void ql_task_mgmt(ql_adapter_state_t *, ql_tgt_t *, fc_packet_t *, 95 ql_srb_t *); 96 static void ql_task_daemon(void *); 97 static void ql_task_thread(ql_adapter_state_t *); 98 static void ql_unsol_callback(ql_srb_t *); 99 static void ql_free_unsolicited_buffer(ql_adapter_state_t *, 100 fc_unsol_buf_t *); 101 static void ql_timer(void *); 102 static void ql_watchdog(ql_adapter_state_t *, uint32_t *, uint32_t *); 103 static void ql_cmd_timeout(ql_adapter_state_t *, ql_tgt_t *q, ql_srb_t *, 104 uint32_t *, uint32_t *); 105 static void ql_halt(ql_adapter_state_t *, int); 106 static int ql_els_plogi(ql_adapter_state_t *, fc_packet_t *); 107 static int ql_els_flogi(ql_adapter_state_t *, fc_packet_t *); 108 static int ql_els_logo(ql_adapter_state_t *, fc_packet_t *); 109 static int ql_els_prli(ql_adapter_state_t *, fc_packet_t *); 110 static int ql_els_prlo(ql_adapter_state_t *, fc_packet_t *); 111 static int ql_els_adisc(ql_adapter_state_t *, fc_packet_t *); 112 static int ql_els_linit(ql_adapter_state_t *, fc_packet_t *); 113 static int ql_els_lpc(ql_adapter_state_t *, fc_packet_t *); 114 static int ql_els_lsts(ql_adapter_state_t *, fc_packet_t *); 115 static int ql_els_scr(ql_adapter_state_t *, fc_packet_t *); 116 static int ql_els_rscn(ql_adapter_state_t *, fc_packet_t *); 117 static int ql_els_farp_req(ql_adapter_state_t *, fc_packet_t *); 118 static int ql_els_farp_reply(ql_adapter_state_t *, fc_packet_t *); 119 static int ql_els_rls(ql_adapter_state_t *, fc_packet_t *); 120 static int ql_els_rnid(ql_adapter_state_t *, fc_packet_t *); 121 static int ql_login_port(ql_adapter_state_t *, port_id_t); 122 static int ql_login_fabric_port(ql_adapter_state_t *, ql_tgt_t *, uint16_t); 123 static int ql_logout_port(ql_adapter_state_t *, port_id_t); 124 static ql_lun_t *ql_lun_queue(ql_adapter_state_t *, ql_tgt_t *, uint16_t); 125 static int ql_fcp_scsi_cmd(ql_adapter_state_t *, fc_packet_t *, ql_srb_t *); 126 static int ql_fcp_ip_cmd(ql_adapter_state_t *, fc_packet_t *, ql_srb_t *); 127 static int ql_fc_services(ql_adapter_state_t *, fc_packet_t *); 128 static int ql_poll_cmd(ql_adapter_state_t *, ql_srb_t *, time_t); 129 static int ql_start_cmd(ql_adapter_state_t *, ql_tgt_t *, fc_packet_t *, 130 ql_srb_t *); 131 static int ql_kstat_update(kstat_t *, int); 132 static ql_adapter_state_t *ql_fca_handle_to_state(opaque_t); 133 static ql_adapter_state_t *ql_cmd_setup(opaque_t, fc_packet_t *, int *); 134 static int ql_program_flash_address(ql_adapter_state_t *, uint32_t, uint8_t); 135 static void ql_rst_aen(ql_adapter_state_t *); 136 static void ql_restart_queues(ql_adapter_state_t *); 137 static void ql_abort_queues(ql_adapter_state_t *); 138 static void ql_abort_device_queues(ql_adapter_state_t *ha, ql_tgt_t *tq); 139 static void ql_idle_check(ql_adapter_state_t *); 140 static int ql_loop_resync(ql_adapter_state_t *); 141 static size_t ql_24xx_ascii_fw_dump(ql_adapter_state_t *, caddr_t); 142 static size_t ql_25xx_ascii_fw_dump(ql_adapter_state_t *, caddr_t); 143 static int ql_save_config_regs(dev_info_t *); 144 static int ql_restore_config_regs(dev_info_t *); 145 static int ql_process_rscn(ql_adapter_state_t *, fc_affected_id_t *); 146 static int ql_handle_rscn_update(ql_adapter_state_t *); 147 static int ql_send_plogi(ql_adapter_state_t *, ql_tgt_t *, ql_head_t *); 148 static int ql_process_rscn_for_device(ql_adapter_state_t *, ql_tgt_t *); 149 static int ql_dump_firmware(ql_adapter_state_t *); 150 static int ql_process_logo_for_device(ql_adapter_state_t *, ql_tgt_t *); 151 static int ql_2200_binary_fw_dump(ql_adapter_state_t *, ql_fw_dump_t *); 152 static int ql_2300_binary_fw_dump(ql_adapter_state_t *, ql_fw_dump_t *); 153 static int ql_24xx_binary_fw_dump(ql_adapter_state_t *, ql_24xx_fw_dump_t *); 154 static int ql_25xx_binary_fw_dump(ql_adapter_state_t *, ql_25xx_fw_dump_t *); 155 static int ql_read_risc_ram(ql_adapter_state_t *, uint32_t, uint32_t, 156 void *); 157 static void *ql_read_regs(ql_adapter_state_t *, void *, void *, uint32_t, 158 uint8_t); 159 static int ql_busy_plogi(ql_adapter_state_t *, fc_packet_t *, ql_tgt_t *); 160 static int ql_suspend_adapter(ql_adapter_state_t *); 161 static int ql_bstr_to_dec(char *, uint32_t *, uint32_t); 162 static void ql_update_rscn(ql_adapter_state_t *, fc_affected_id_t *); 163 int ql_alloc_dma_resouce(ql_adapter_state_t *, dma_mem_t *, int); 164 static int ql_bind_dma_buffer(ql_adapter_state_t *, dma_mem_t *, int); 165 static void ql_unbind_dma_buffer(ql_adapter_state_t *, dma_mem_t *); 166 static void ql_timeout_insert(ql_adapter_state_t *, ql_tgt_t *, ql_srb_t *); 167 static int ql_setup_interrupts(ql_adapter_state_t *); 168 static int ql_setup_msi(ql_adapter_state_t *); 169 static int ql_setup_msix(ql_adapter_state_t *); 170 static int ql_setup_fixed(ql_adapter_state_t *); 171 static void ql_release_intr(ql_adapter_state_t *); 172 static void ql_disable_intr(ql_adapter_state_t *); 173 static int ql_legacy_intr(ql_adapter_state_t *); 174 static int ql_init_mutex(ql_adapter_state_t *); 175 static void ql_destroy_mutex(ql_adapter_state_t *); 176 static void ql_iidma(ql_adapter_state_t *); 177 178 static int ql_n_port_plogi(ql_adapter_state_t *); 179 static void ql_fca_isp_els_request(ql_adapter_state_t *, fc_packet_t *, 180 els_descriptor_t *); 181 static void ql_isp_els_request_ctor(els_descriptor_t *, 182 els_passthru_entry_t *); 183 static int ql_p2p_plogi(ql_adapter_state_t *, fc_packet_t *); 184 /* 185 * Global data 186 */ 187 static uint8_t ql_enable_pm = 1; 188 static int ql_flash_sbus_fpga = 0; 189 uint32_t ql_os_release_level; 190 uint32_t ql_disable_aif = 0; 191 uint32_t ql_disable_msi = 0; 192 uint32_t ql_disable_msix = 0; 193 194 /* Timer routine variables. */ 195 static timeout_id_t ql_timer_timeout_id = NULL; 196 static clock_t ql_timer_ticks; 197 198 /* Soft state head pointer. */ 199 void *ql_state = NULL; 200 201 /* Head adapter link. */ 202 ql_head_t ql_hba = { 203 NULL, 204 NULL 205 }; 206 207 /* Global hba index */ 208 uint32_t ql_gfru_hba_index = 1; 209 210 /* 211 * Some IP defines and globals 212 */ 213 uint32_t ql_ip_buffer_count = 128; 214 uint32_t ql_ip_low_water = 10; 215 uint8_t ql_ip_fast_post_count = 5; 216 static int ql_ip_mtu = 65280; /* equivalent to FCIPMTU */ 217 218 /* Device AL_PA to Device Head Queue index array. */ 219 uint8_t ql_alpa_to_index[] = { 220 0x7e, 0x7d, 0x7c, 0x00, 0x7b, 0x01, 0x02, 0x03, 0x7a, 0x04, 221 0x05, 0x06, 0x07, 0x08, 0x09, 0x79, 0x78, 0x0a, 0x0b, 0x0c, 222 0x0d, 0x0e, 0x0f, 0x77, 0x76, 0x10, 0x11, 0x75, 0x12, 0x74, 223 0x73, 0x72, 0x13, 0x14, 0x15, 0x71, 0x16, 0x70, 0x6f, 0x6e, 224 0x17, 0x6d, 0x6c, 0x6b, 0x6a, 0x69, 0x68, 0x18, 0x19, 0x67, 225 0x66, 0x65, 0x64, 0x63, 0x62, 0x20, 0x21, 0x61, 0x60, 0x23, 226 0x5f, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x5e, 0x2a, 0x5d, 227 0x5c, 0x5b, 0x2b, 0x5a, 0x59, 0x58, 0x57, 0x56, 0x55, 0x2c, 228 0x2d, 0x54, 0x53, 0x52, 0x51, 0x50, 0x4f, 0x2e, 0x2f, 0x4e, 229 0x4d, 0x30, 0x4c, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x4b, 230 0x37, 0x4a, 0x49, 0x48, 0x38, 0x47, 0x46, 0x45, 0x44, 0x43, 231 0x42, 0x39, 0x3a, 0x41, 0x40, 0x3f, 0x3e, 0x3d, 0x3c, 0x3b, 232 0x3c, 0x3b, 0x3a, 0x3d, 0x39, 0x3e, 0x3f, 0x40, 0x38, 0x37, 233 0x36, 0x41, 0x35, 0x42, 0x43, 0x44, 0x34, 0x45, 0x46, 0x47, 234 0x48, 0x49, 0x4a, 0x33, 0x32, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, 235 0x50, 0x31, 0x30, 0x51, 0x52, 0x2f, 0x53, 0x2e, 0x2d, 0x2c, 236 0x54, 0x55, 0x56, 0x2b, 0x57, 0x2a, 0x29, 0x28, 0x58, 0x27, 237 0x26, 0x25, 0x24, 0x23, 0x22, 0x59, 0x5a, 0x21, 0x20, 0x1f, 238 0x1e, 0x1d, 0x1c, 0x5b, 0x5c, 0x1b, 0x1a, 0x5d, 0x19, 0x5e, 239 0x5f, 0x60, 0x61, 0x62, 0x63, 0x18, 0x64, 0x17, 0x16, 0x15, 240 0x65, 0x14, 0x13, 0x12, 0x11, 0x10, 0x0f, 0x66, 0x67, 0x0e, 241 0x0d, 0x0c, 0x0b, 0x0a, 0x09, 0x68, 0x69, 0x08, 0x07, 0x6a, 242 0x06, 0x6b, 0x6c, 0x6d, 0x05, 0x04, 0x03, 0x6e, 0x02, 0x6f, 243 0x70, 0x71, 0x01, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x00, 244 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7f, 0x80, 0x00, 0x01, 245 0x02, 0x03, 0x80, 0x7f, 0x7e, 0x04 246 }; 247 248 /* Device loop_id to ALPA array. */ 249 static uint8_t ql_index_to_alpa[] = { 250 0xef, 0xe8, 0xe4, 0xe2, 0xe1, 0xe0, 0xdc, 0xda, 0xd9, 0xd6, 251 0xd5, 0xd4, 0xd3, 0xd2, 0xd1, 0xce, 0xcd, 0xcc, 0xcb, 0xca, 252 0xc9, 0xc7, 0xc6, 0xc5, 0xc3, 0xbc, 0xba, 0xb9, 0xb6, 0xb5, 253 0xb4, 0xb3, 0xb2, 0xb1, 0xae, 0xad, 0xac, 0xab, 0xaa, 0xa9, 254 0xa7, 0xa6, 0xa5, 0xa3, 0x9f, 0x9e, 0x9d, 0x9b, 0x98, 0x97, 255 0x90, 0x8f, 0x88, 0x84, 0x82, 0x81, 0x80, 0x7c, 0x7a, 0x79, 256 0x76, 0x75, 0x74, 0x73, 0x72, 0x71, 0x6e, 0x6d, 0x6c, 0x6b, 257 0x6a, 0x69, 0x67, 0x66, 0x65, 0x63, 0x5c, 0x5a, 0x59, 0x56, 258 0x55, 0x54, 0x53, 0x52, 0x51, 0x4e, 0x4d, 0x4c, 0x4b, 0x4a, 259 0x49, 0x47, 0x46, 0x45, 0x43, 0x3c, 0x3a, 0x39, 0x36, 0x35, 260 0x34, 0x33, 0x32, 0x31, 0x2e, 0x2d, 0x2c, 0x2b, 0x2a, 0x29, 261 0x27, 0x26, 0x25, 0x23, 0x1f, 0x1e, 0x1d, 0x1b, 0x18, 0x17, 262 0x10, 0x0f, 0x08, 0x04, 0x02, 0x01 263 }; 264 265 /* 2200 register offsets */ 266 static reg_off_t reg_off_2200 = { 267 0x00, 0x02, 0x06, 0x08, 0x0a, 0x0c, 0x0e, 268 0x18, 0x18, 0x1A, 0x1A, /* req in, out, resp in, out */ 269 0x00, 0x00, /* intr info lo, hi */ 270 24, /* Number of mailboxes */ 271 /* Mailbox register offsets */ 272 0x10, 0x12, 0x14, 0x16, 0x18, 0x1a, 0x1c, 0x1e, 273 0xe0, 0xe2, 0xe4, 0xe6, 0xe8, 0xea, 0xec, 0xee, 274 0xf0, 0xf2, 0xf4, 0xf6, 0xf8, 0xfa, 0xfc, 0xfe, 275 /* 2200 does not have mailbox 24-31 */ 276 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 277 0x96, 0xa4, 0xb0, 0xb8, 0xc0, 0xcc, 0xce, 278 /* host to host sema */ 279 0x00, 280 /* 2200 does not have pri_req_in, pri_req_out, */ 281 /* atio_req_in, atio_req_out, io_base_addr */ 282 0xff, 0xff, 0xff, 0xff, 0xff 283 }; 284 285 /* 2300 register offsets */ 286 static reg_off_t reg_off_2300 = { 287 0x00, 0x02, 0x06, 0x08, 0x0a, 0x0c, 0x0e, 288 0x10, 0x12, 0x14, 0x16, /* req in, out, resp in, out */ 289 0x18, 0x1A, /* intr info lo, hi */ 290 32, /* Number of mailboxes */ 291 /* Mailbox register offsets */ 292 0x40, 0x42, 0x44, 0x46, 0x48, 0x4a, 0x4c, 0x4e, 293 0x50, 0x52, 0x54, 0x56, 0x58, 0x5a, 0x5c, 0x5e, 294 0x60, 0x62, 0x64, 0x66, 0x68, 0x6a, 0x6c, 0x6e, 295 0x70, 0x72, 0x74, 0x76, 0x78, 0x7a, 0x7c, 0x7e, 296 0x96, 0xa4, 0xb0, 0x80, 0xc0, 0xcc, 0xce, 297 /* host to host sema */ 298 0x1c, 299 /* 2300 does not have pri_req_in, pri_req_out, */ 300 /* atio_req_in, atio_req_out, io_base_addr */ 301 0xff, 0xff, 0xff, 0xff, 0xff 302 }; 303 304 /* 2400/2500 register offsets */ 305 reg_off_t reg_off_2400_2500 = { 306 0x00, 0x04, /* flash_address, flash_data */ 307 0x08, 0x0c, 0x10, /* ctrl_status, ictrl, istatus */ 308 /* 2400 does not have semaphore, nvram */ 309 0x14, 0x18, 310 0x1c, 0x20, 0x24, 0x28, /* req_in, req_out, resp_in, resp_out */ 311 0x44, 0x46, /* intr info lo, hi */ 312 32, /* Number of mailboxes */ 313 /* Mailbox register offsets */ 314 0x80, 0x82, 0x84, 0x86, 0x88, 0x8a, 0x8c, 0x8e, 315 0x90, 0x92, 0x94, 0x96, 0x98, 0x9a, 0x9c, 0x9e, 316 0xa0, 0xa2, 0xa4, 0xa6, 0xa8, 0xaa, 0xac, 0xae, 317 0xb0, 0xb2, 0xb4, 0xb6, 0xb8, 0xba, 0xbc, 0xbe, 318 /* 2400 does not have fpm_diag_config, pcr, mctr, fb_cmd */ 319 0xff, 0xff, 0xff, 0xff, 320 0x48, 0x4c, 0x50, /* hccr, gpiod, gpioe */ 321 0xff, /* host to host sema */ 322 0x2c, 0x30, /* pri_req_in, pri_req_out */ 323 0x3c, 0x40, /* atio_req_in, atio_req_out */ 324 0x54 /* io_base_addr */ 325 }; 326 327 /* mutex for protecting variables shared by all instances of the driver */ 328 kmutex_t ql_global_mutex; 329 kmutex_t ql_global_hw_mutex; 330 kmutex_t ql_global_el_mutex; 331 332 /* DMA access attribute structure. */ 333 static ddi_device_acc_attr_t ql_dev_acc_attr = { 334 DDI_DEVICE_ATTR_V0, 335 DDI_STRUCTURE_LE_ACC, 336 DDI_STRICTORDER_ACC 337 }; 338 339 /* I/O DMA attributes structures. */ 340 static ddi_dma_attr_t ql_64bit_io_dma_attr = { 341 DMA_ATTR_V0, /* dma_attr_version */ 342 QL_DMA_LOW_ADDRESS, /* low DMA address range */ 343 QL_DMA_HIGH_64BIT_ADDRESS, /* high DMA address range */ 344 QL_DMA_XFER_COUNTER, /* DMA counter register */ 345 QL_DMA_ADDRESS_ALIGNMENT, /* DMA address alignment */ 346 QL_DMA_BURSTSIZES, /* DMA burstsizes */ 347 QL_DMA_MIN_XFER_SIZE, /* min effective DMA size */ 348 QL_DMA_MAX_XFER_SIZE, /* max DMA xfer size */ 349 QL_DMA_SEGMENT_BOUNDARY, /* segment boundary */ 350 QL_DMA_SG_LIST_LENGTH, /* s/g list length */ 351 QL_DMA_GRANULARITY, /* granularity of device */ 352 QL_DMA_XFER_FLAGS /* DMA transfer flags */ 353 }; 354 355 static ddi_dma_attr_t ql_32bit_io_dma_attr = { 356 DMA_ATTR_V0, /* dma_attr_version */ 357 QL_DMA_LOW_ADDRESS, /* low DMA address range */ 358 QL_DMA_HIGH_32BIT_ADDRESS, /* high DMA address range */ 359 QL_DMA_XFER_COUNTER, /* DMA counter register */ 360 QL_DMA_ADDRESS_ALIGNMENT, /* DMA address alignment */ 361 QL_DMA_BURSTSIZES, /* DMA burstsizes */ 362 QL_DMA_MIN_XFER_SIZE, /* min effective DMA size */ 363 QL_DMA_MAX_XFER_SIZE, /* max DMA xfer size */ 364 QL_DMA_SEGMENT_BOUNDARY, /* segment boundary */ 365 QL_DMA_SG_LIST_LENGTH, /* s/g list length */ 366 QL_DMA_GRANULARITY, /* granularity of device */ 367 QL_DMA_XFER_FLAGS /* DMA transfer flags */ 368 }; 369 370 /* Load the default dma attributes */ 371 static ddi_dma_attr_t ql_32fcsm_cmd_dma_attr; 372 static ddi_dma_attr_t ql_64fcsm_cmd_dma_attr; 373 static ddi_dma_attr_t ql_32fcsm_rsp_dma_attr; 374 static ddi_dma_attr_t ql_64fcsm_rsp_dma_attr; 375 static ddi_dma_attr_t ql_32fcip_cmd_dma_attr; 376 static ddi_dma_attr_t ql_64fcip_cmd_dma_attr; 377 static ddi_dma_attr_t ql_32fcip_rsp_dma_attr; 378 static ddi_dma_attr_t ql_64fcip_rsp_dma_attr; 379 static ddi_dma_attr_t ql_32fcp_cmd_dma_attr; 380 static ddi_dma_attr_t ql_64fcp_cmd_dma_attr; 381 static ddi_dma_attr_t ql_32fcp_rsp_dma_attr; 382 static ddi_dma_attr_t ql_64fcp_rsp_dma_attr; 383 static ddi_dma_attr_t ql_32fcp_data_dma_attr; 384 static ddi_dma_attr_t ql_64fcp_data_dma_attr; 385 386 /* Static declarations of cb_ops entry point functions... */ 387 static struct cb_ops ql_cb_ops = { 388 ql_open, /* b/c open */ 389 ql_close, /* b/c close */ 390 nodev, /* b strategy */ 391 nodev, /* b print */ 392 nodev, /* b dump */ 393 nodev, /* c read */ 394 nodev, /* c write */ 395 ql_ioctl, /* c ioctl */ 396 nodev, /* c devmap */ 397 nodev, /* c mmap */ 398 nodev, /* c segmap */ 399 nochpoll, /* c poll */ 400 nodev, /* cb_prop_op */ 401 NULL, /* streamtab */ 402 D_MP | D_NEW | D_HOTPLUG, /* Driver compatibility flag */ 403 CB_REV, /* cb_ops revision */ 404 nodev, /* c aread */ 405 nodev /* c awrite */ 406 }; 407 408 /* Static declarations of dev_ops entry point functions... */ 409 static struct dev_ops ql_devops = { 410 DEVO_REV, /* devo_rev */ 411 0, /* refcnt */ 412 ql_getinfo, /* getinfo */ 413 nulldev, /* identify */ 414 nulldev, /* probe */ 415 ql_attach, /* attach */ 416 ql_detach, /* detach */ 417 nodev, /* reset */ 418 &ql_cb_ops, /* char/block ops */ 419 NULL, /* bus operations */ 420 ql_power, /* power management */ 421 ql_quiesce /* quiesce device */ 422 }; 423 424 /* ELS command code to text converter */ 425 cmd_table_t els_cmd_tbl[] = ELS_CMD_TABLE(); 426 /* Mailbox command code to text converter */ 427 cmd_table_t mbox_cmd_tbl[] = MBOX_CMD_TABLE(); 428 429 char qlc_driver_version[] = QL_VERSION; 430 431 /* 432 * Loadable Driver Interface Structures. 433 * Declare and initialize the module configuration section... 434 */ 435 static struct modldrv modldrv = { 436 &mod_driverops, /* type of module: driver */ 437 "SunFC Qlogic FCA v" QL_VERSION, /* name of module */ 438 &ql_devops /* driver dev_ops */ 439 }; 440 441 static struct modlinkage modlinkage = { 442 MODREV_1, 443 &modldrv, 444 NULL 445 }; 446 447 /* ************************************************************************ */ 448 /* Loadable Module Routines. */ 449 /* ************************************************************************ */ 450 451 /* 452 * _init 453 * Initializes a loadable module. It is called before any other 454 * routine in a loadable module. 455 * 456 * Returns: 457 * 0 = success 458 * 459 * Context: 460 * Kernel context. 461 */ 462 int 463 _init(void) 464 { 465 uint16_t w16; 466 int rval = 0; 467 468 /* Get OS major release level. */ 469 for (w16 = 0; w16 < sizeof (utsname.release); w16++) { 470 if (utsname.release[w16] == '.') { 471 w16++; 472 break; 473 } 474 } 475 if (w16 < sizeof (utsname.release)) { 476 (void) ql_bstr_to_dec(&utsname.release[w16], 477 &ql_os_release_level, 0); 478 } else { 479 ql_os_release_level = 0; 480 } 481 if (ql_os_release_level < 6) { 482 cmn_err(CE_WARN, "%s Unsupported OS release level = %d", 483 QL_NAME, ql_os_release_level); 484 rval = EINVAL; 485 } 486 if (ql_os_release_level == 6) { 487 ql_32bit_io_dma_attr.dma_attr_count_max = 0x00ffffff; 488 ql_64bit_io_dma_attr.dma_attr_count_max = 0x00ffffff; 489 } 490 491 if (rval == 0) { 492 rval = ddi_soft_state_init(&ql_state, 493 sizeof (ql_adapter_state_t), 0); 494 } 495 if (rval == 0) { 496 /* allow the FC Transport to tweak the dev_ops */ 497 fc_fca_init(&ql_devops); 498 499 mutex_init(&ql_global_mutex, NULL, MUTEX_DRIVER, NULL); 500 mutex_init(&ql_global_hw_mutex, NULL, MUTEX_DRIVER, NULL); 501 mutex_init(&ql_global_el_mutex, NULL, MUTEX_DRIVER, NULL); 502 rval = mod_install(&modlinkage); 503 if (rval != 0) { 504 mutex_destroy(&ql_global_hw_mutex); 505 mutex_destroy(&ql_global_mutex); 506 mutex_destroy(&ql_global_el_mutex); 507 ddi_soft_state_fini(&ql_state); 508 } else { 509 /*EMPTY*/ 510 ql_32fcsm_cmd_dma_attr = ql_32bit_io_dma_attr; 511 ql_64fcsm_cmd_dma_attr = ql_64bit_io_dma_attr; 512 ql_32fcsm_rsp_dma_attr = ql_32bit_io_dma_attr; 513 ql_64fcsm_rsp_dma_attr = ql_64bit_io_dma_attr; 514 ql_32fcip_cmd_dma_attr = ql_32bit_io_dma_attr; 515 ql_64fcip_cmd_dma_attr = ql_64bit_io_dma_attr; 516 ql_32fcip_rsp_dma_attr = ql_32bit_io_dma_attr; 517 ql_64fcip_rsp_dma_attr = ql_64bit_io_dma_attr; 518 ql_32fcp_cmd_dma_attr = ql_32bit_io_dma_attr; 519 ql_64fcp_cmd_dma_attr = ql_64bit_io_dma_attr; 520 ql_32fcp_rsp_dma_attr = ql_32bit_io_dma_attr; 521 ql_64fcp_rsp_dma_attr = ql_64bit_io_dma_attr; 522 ql_32fcp_data_dma_attr = ql_32bit_io_dma_attr; 523 ql_64fcp_data_dma_attr = ql_64bit_io_dma_attr; 524 ql_32fcsm_cmd_dma_attr.dma_attr_sgllen = 525 ql_64fcsm_cmd_dma_attr.dma_attr_sgllen = 526 QL_FCSM_CMD_SGLLEN; 527 ql_32fcsm_rsp_dma_attr.dma_attr_sgllen = 528 ql_64fcsm_rsp_dma_attr.dma_attr_sgllen = 529 QL_FCSM_RSP_SGLLEN; 530 ql_32fcip_cmd_dma_attr.dma_attr_sgllen = 531 ql_64fcip_cmd_dma_attr.dma_attr_sgllen = 532 QL_FCIP_CMD_SGLLEN; 533 ql_32fcip_rsp_dma_attr.dma_attr_sgllen = 534 ql_64fcip_rsp_dma_attr.dma_attr_sgllen = 535 QL_FCIP_RSP_SGLLEN; 536 ql_32fcp_cmd_dma_attr.dma_attr_sgllen = 537 ql_64fcp_cmd_dma_attr.dma_attr_sgllen = 538 QL_FCP_CMD_SGLLEN; 539 ql_32fcp_rsp_dma_attr.dma_attr_sgllen = 540 ql_64fcp_rsp_dma_attr.dma_attr_sgllen = 541 QL_FCP_RSP_SGLLEN; 542 } 543 } 544 545 if (rval != 0) { 546 cmn_err(CE_CONT, "?Unable to install/attach driver '%s'", 547 QL_NAME); 548 } 549 550 return (rval); 551 } 552 553 /* 554 * _fini 555 * Prepares a module for unloading. It is called when the system 556 * wants to unload a module. If the module determines that it can 557 * be unloaded, then _fini() returns the value returned by 558 * mod_remove(). Upon successful return from _fini() no other 559 * routine in the module will be called before _init() is called. 560 * 561 * Returns: 562 * 0 = success 563 * 564 * Context: 565 * Kernel context. 566 */ 567 int 568 _fini(void) 569 { 570 int rval; 571 572 rval = mod_remove(&modlinkage); 573 if (rval == 0) { 574 mutex_destroy(&ql_global_hw_mutex); 575 mutex_destroy(&ql_global_mutex); 576 mutex_destroy(&ql_global_el_mutex); 577 ddi_soft_state_fini(&ql_state); 578 } 579 580 return (rval); 581 } 582 583 /* 584 * _info 585 * Returns information about loadable module. 586 * 587 * Input: 588 * modinfo = pointer to module information structure. 589 * 590 * Returns: 591 * Value returned by mod_info(). 592 * 593 * Context: 594 * Kernel context. 595 */ 596 int 597 _info(struct modinfo *modinfop) 598 { 599 return (mod_info(&modlinkage, modinfop)); 600 } 601 602 /* ************************************************************************ */ 603 /* dev_ops functions */ 604 /* ************************************************************************ */ 605 606 /* 607 * ql_getinfo 608 * Returns the pointer associated with arg when cmd is 609 * set to DDI_INFO_DEVT2DEVINFO, or it should return the 610 * instance number associated with arg when cmd is set 611 * to DDI_INFO_DEV2INSTANCE. 612 * 613 * Input: 614 * dip = Do not use. 615 * cmd = command argument. 616 * arg = command specific argument. 617 * resultp = pointer to where request information is stored. 618 * 619 * Returns: 620 * DDI_SUCCESS or DDI_FAILURE. 621 * 622 * Context: 623 * Kernel context. 624 */ 625 /* ARGSUSED */ 626 static int 627 ql_getinfo(dev_info_t *dip, ddi_info_cmd_t cmd, void *arg, void **resultp) 628 { 629 ql_adapter_state_t *ha; 630 int minor; 631 int rval = DDI_FAILURE; 632 633 minor = (int)(getminor((dev_t)arg)); 634 ha = ddi_get_soft_state(ql_state, minor); 635 if (ha == NULL) { 636 QL_PRINT_2(CE_CONT, "failed, unknown minor=%d\n", 637 getminor((dev_t)arg)); 638 *resultp = NULL; 639 return (rval); 640 } 641 642 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance); 643 644 switch (cmd) { 645 case DDI_INFO_DEVT2DEVINFO: 646 *resultp = ha->dip; 647 rval = DDI_SUCCESS; 648 break; 649 case DDI_INFO_DEVT2INSTANCE: 650 *resultp = (void *)(uintptr_t)(ha->instance); 651 rval = DDI_SUCCESS; 652 break; 653 default: 654 EL(ha, "failed, unsupported cmd=%d\n", cmd); 655 rval = DDI_FAILURE; 656 break; 657 } 658 659 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance); 660 661 return (rval); 662 } 663 664 /* 665 * ql_attach 666 * Configure and attach an instance of the driver 667 * for a port. 668 * 669 * Input: 670 * dip = pointer to device information structure. 671 * cmd = attach type. 672 * 673 * Returns: 674 * DDI_SUCCESS or DDI_FAILURE. 675 * 676 * Context: 677 * Kernel context. 678 */ 679 static int 680 ql_attach(dev_info_t *dip, ddi_attach_cmd_t cmd) 681 { 682 uint32_t size; 683 int rval; 684 int instance; 685 uint_t progress = 0; 686 char *buf; 687 ushort_t caps_ptr, cap; 688 fc_fca_tran_t *tran; 689 ql_adapter_state_t *ha = NULL; 690 691 static char *pmcomps[] = { 692 NULL, 693 PM_LEVEL_D3_STR, /* Device OFF */ 694 PM_LEVEL_D0_STR, /* Device ON */ 695 }; 696 697 QL_PRINT_3(CE_CONT, "(%d): started, cmd=%xh\n", 698 ddi_get_instance(dip), cmd); 699 700 buf = (char *)(kmem_zalloc(MAXPATHLEN, KM_SLEEP)); 701 702 switch (cmd) { 703 case DDI_ATTACH: 704 /* first get the instance */ 705 instance = ddi_get_instance(dip); 706 707 cmn_err(CE_CONT, "!Qlogic %s(%d) FCA Driver v%s\n", 708 QL_NAME, instance, QL_VERSION); 709 710 /* Correct OS version? */ 711 if (ql_os_release_level != 11) { 712 cmn_err(CE_WARN, "%s(%d): This driver is for Solaris " 713 "11", QL_NAME, instance); 714 goto attach_failed; 715 } 716 717 /* Hardware is installed in a DMA-capable slot? */ 718 if (ddi_slaveonly(dip) == DDI_SUCCESS) { 719 cmn_err(CE_WARN, "%s(%d): slave only", QL_NAME, 720 instance); 721 goto attach_failed; 722 } 723 724 /* No support for high-level interrupts */ 725 if (ddi_intr_hilevel(dip, 0) != 0) { 726 cmn_err(CE_WARN, "%s(%d): High level interrupt" 727 " not supported", QL_NAME, instance); 728 goto attach_failed; 729 } 730 731 /* Allocate our per-device-instance structure */ 732 if (ddi_soft_state_zalloc(ql_state, 733 instance) != DDI_SUCCESS) { 734 cmn_err(CE_WARN, "%s(%d): soft state alloc failed", 735 QL_NAME, instance); 736 goto attach_failed; 737 } 738 progress |= QL_SOFT_STATE_ALLOCED; 739 740 ha = ddi_get_soft_state(ql_state, instance); 741 if (ha == NULL) { 742 cmn_err(CE_WARN, "%s(%d): can't get soft state", 743 QL_NAME, instance); 744 goto attach_failed; 745 } 746 ha->dip = dip; 747 ha->instance = instance; 748 ha->hba.base_address = ha; 749 ha->pha = ha; 750 751 if (ql_el_trace_desc_ctor(ha) != DDI_SUCCESS) { 752 cmn_err(CE_WARN, "%s(%d): can't setup el tracing", 753 QL_NAME, instance); 754 goto attach_failed; 755 } 756 757 /* Get extended logging and dump flags. */ 758 ql_common_properties(ha); 759 760 if (strcmp(ddi_driver_name(ddi_get_parent(dip)), 761 "sbus") == 0) { 762 EL(ha, "%s SBUS card detected", QL_NAME); 763 ha->cfg_flags |= CFG_SBUS_CARD; 764 } 765 766 ha->dev = kmem_zalloc(sizeof (*ha->dev) * 767 DEVICE_HEAD_LIST_SIZE, KM_SLEEP); 768 769 ha->outstanding_cmds = kmem_zalloc( 770 sizeof (*ha->outstanding_cmds) * MAX_OUTSTANDING_COMMANDS, 771 KM_SLEEP); 772 773 ha->ub_array = kmem_zalloc(sizeof (*ha->ub_array) * 774 QL_UB_LIMIT, KM_SLEEP); 775 776 ha->adapter_stats = kmem_zalloc(sizeof (*ha->adapter_stats), 777 KM_SLEEP); 778 779 (void) ddi_pathname(dip, buf); 780 ha->devpath = kmem_zalloc(strlen(buf)+1, KM_SLEEP); 781 if (ha->devpath == NULL) { 782 EL(ha, "devpath mem alloc failed\n"); 783 } else { 784 (void) strcpy(ha->devpath, buf); 785 EL(ha, "devpath is: %s\n", ha->devpath); 786 } 787 788 if (CFG_IST(ha, CFG_SBUS_CARD)) { 789 /* 790 * For cards where PCI is mapped to sbus e.g. Ivory. 791 * 792 * 0x00 : 0x000 - 0x0FF PCI Config Space for 2200 793 * : 0x100 - 0x3FF PCI IO space for 2200 794 * 0x01 : 0x000 - 0x0FF PCI Config Space for fpga 795 * : 0x100 - 0x3FF PCI IO Space for fpga 796 */ 797 if (ddi_regs_map_setup(dip, 0, (caddr_t *)&ha->iobase, 798 0x100, 0x300, &ql_dev_acc_attr, &ha->dev_handle) 799 != DDI_SUCCESS) { 800 cmn_err(CE_WARN, "%s(%d): Unable to map device" 801 " registers", QL_NAME, instance); 802 goto attach_failed; 803 } 804 if (ddi_regs_map_setup(dip, 1, 805 (caddr_t *)&ha->sbus_fpga_iobase, 0, 0x400, 806 &ql_dev_acc_attr, &ha->sbus_fpga_dev_handle) 807 != DDI_SUCCESS) { 808 /* We should not fail attach here */ 809 cmn_err(CE_WARN, "%s(%d): Unable to map FPGA", 810 QL_NAME, instance); 811 ha->sbus_fpga_iobase = NULL; 812 } 813 progress |= QL_REGS_MAPPED; 814 } else { 815 /* 816 * Setup the ISP2200 registers address mapping to be 817 * accessed by this particular driver. 818 * 0x0 Configuration Space 819 * 0x1 I/O Space 820 * 0x2 32-bit Memory Space address 821 * 0x3 64-bit Memory Space address 822 */ 823 if (ddi_regs_map_setup(dip, 2, (caddr_t *)&ha->iobase, 824 0, 0x100, &ql_dev_acc_attr, 825 &ha->dev_handle) != DDI_SUCCESS) { 826 cmn_err(CE_WARN, "%s(%d): regs_map_setup " 827 "failed", QL_NAME, instance); 828 goto attach_failed; 829 } 830 progress |= QL_REGS_MAPPED; 831 832 /* 833 * We need I/O space mappings for 23xx HBAs for 834 * loading flash (FCode). The chip has a bug due to 835 * which loading flash fails through mem space 836 * mappings in PCI-X mode. 837 */ 838 if (ddi_regs_map_setup(dip, 1, 839 (caddr_t *)&ha->iomap_iobase, 0, 0x100, 840 &ql_dev_acc_attr, 841 &ha->iomap_dev_handle) != DDI_SUCCESS) { 842 cmn_err(CE_WARN, "%s(%d): regs_map_setup(I/O)" 843 " failed", QL_NAME, instance); 844 goto attach_failed; 845 } 846 progress |= QL_IOMAP_IOBASE_MAPPED; 847 } 848 849 /* 850 * We should map config space before adding interrupt 851 * So that the chip type (2200 or 2300) can be determined 852 * before the interrupt routine gets a chance to execute. 853 */ 854 if (CFG_IST(ha, CFG_SBUS_CARD)) { 855 if (ddi_regs_map_setup(dip, 0, 856 (caddr_t *)&ha->sbus_config_base, 0, 0x100, 857 &ql_dev_acc_attr, &ha->sbus_config_handle) != 858 DDI_SUCCESS) { 859 cmn_err(CE_WARN, "%s(%d): Unable to map sbus " 860 "config registers", QL_NAME, instance); 861 goto attach_failed; 862 } 863 } else { 864 if (pci_config_setup(ha->dip, &ha->pci_handle) != 865 DDI_SUCCESS) { 866 cmn_err(CE_WARN, "%s(%d): can't setup PCI " 867 "config space", QL_NAME, instance); 868 goto attach_failed; 869 } 870 } 871 progress |= QL_CONFIG_SPACE_SETUP; 872 873 ha->subsys_id = (uint16_t)ql_pci_config_get16(ha, 874 PCI_CONF_SUBSYSID); 875 ha->subven_id = (uint16_t)ql_pci_config_get16(ha, 876 PCI_CONF_SUBVENID); 877 ha->ven_id = (uint16_t)ql_pci_config_get16(ha, 878 PCI_CONF_VENID); 879 ha->device_id = (uint16_t)ql_pci_config_get16(ha, 880 PCI_CONF_DEVID); 881 ha->rev_id = (uint8_t)ql_pci_config_get8(ha, 882 PCI_CONF_REVID); 883 884 EL(ha, "ISP%x chip detected (RevID=%x, VenID=%x, SVenID=%x, " 885 "SSysID=%x)\n", ha->device_id, ha->rev_id, ha->ven_id, 886 ha->subven_id, ha->subsys_id); 887 888 switch (ha->device_id) { 889 case 0x2300: 890 case 0x2312: 891 #if !defined(__sparc) || defined(QL_DEBUG_ROUTINES) 892 /* 893 * per marketing, fibre-lite HBA's are not supported 894 * on sparc platforms 895 */ 896 case 0x6312: 897 case 0x6322: 898 #endif /* !defined(__sparc) || defined(QL_DEBUG_ROUTINES) */ 899 if (ql_pci_config_get8(ha, PCI_CONF_IPIN) == 2) { 900 ha->flags |= FUNCTION_1; 901 } 902 if (ha->device_id == 0x6322) { 903 ha->cfg_flags |= CFG_CTRL_6322; 904 ha->fw_class = 0x6322; 905 ha->risc_dump_size = QL_6322_FW_DUMP_SIZE; 906 } else { 907 ha->cfg_flags |= CFG_CTRL_2300; 908 ha->fw_class = 0x2300; 909 ha->risc_dump_size = QL_2300_FW_DUMP_SIZE; 910 } 911 ha->reg_off = ®_off_2300; 912 if (ql_fwmodule_resolve(ha) != QL_SUCCESS) { 913 goto attach_failed; 914 } 915 ha->fcp_cmd = ql_command_iocb; 916 ha->ip_cmd = ql_ip_iocb; 917 ha->ms_cmd = ql_ms_iocb; 918 if (CFG_IST(ha, CFG_SBUS_CARD)) { 919 ha->cmd_segs = CMD_TYPE_2_DATA_SEGMENTS; 920 ha->cmd_cont_segs = CONT_TYPE_0_DATA_SEGMENTS; 921 } else { 922 ha->cmd_segs = CMD_TYPE_3_DATA_SEGMENTS; 923 ha->cmd_cont_segs = CONT_TYPE_1_DATA_SEGMENTS; 924 } 925 break; 926 927 case 0x2200: 928 ha->cfg_flags |= CFG_CTRL_2200; 929 ha->reg_off = ®_off_2200; 930 ha->fw_class = 0x2200; 931 if (ql_fwmodule_resolve(ha) != QL_SUCCESS) { 932 goto attach_failed; 933 } 934 ha->risc_dump_size = QL_2200_FW_DUMP_SIZE; 935 ha->fcp_cmd = ql_command_iocb; 936 ha->ip_cmd = ql_ip_iocb; 937 ha->ms_cmd = ql_ms_iocb; 938 if (CFG_IST(ha, CFG_SBUS_CARD)) { 939 ha->cmd_segs = CMD_TYPE_2_DATA_SEGMENTS; 940 ha->cmd_cont_segs = CONT_TYPE_0_DATA_SEGMENTS; 941 } else { 942 ha->cmd_segs = CMD_TYPE_3_DATA_SEGMENTS; 943 ha->cmd_cont_segs = CONT_TYPE_1_DATA_SEGMENTS; 944 } 945 break; 946 947 case 0x2422: 948 case 0x2432: 949 case 0x5422: 950 case 0x5432: 951 case 0x8432: 952 #ifdef __sparc 953 /* 954 * Per marketing, the QLA/QLE-2440's (which 955 * also use the 2422 & 2432) are only for the 956 * x86 platform (SMB market). 957 */ 958 if (ha->subsys_id == 0x145 || ha->subsys_id == 0x147 || 959 ha->subsys_id == 0x13e) { 960 cmn_err(CE_WARN, 961 "%s(%d): Unsupported HBA ssid: %x", 962 QL_NAME, instance, ha->subsys_id); 963 goto attach_failed; 964 } 965 #endif /* __sparc */ 966 if (ql_pci_config_get8(ha, PCI_CONF_IPIN) == 2) { 967 ha->flags |= FUNCTION_1; 968 } 969 ha->cfg_flags |= CFG_CTRL_2422; 970 if (ha->device_id == 0x8432) { 971 ha->cfg_flags |= CFG_CTRL_MENLO; 972 } else { 973 ha->flags |= VP_ENABLED; 974 } 975 976 ha->reg_off = ®_off_2400_2500; 977 ha->fw_class = 0x2400; 978 if (ql_fwmodule_resolve(ha) != QL_SUCCESS) { 979 goto attach_failed; 980 } 981 ha->risc_dump_size = QL_24XX_FW_DUMP_SIZE; 982 ha->fcp_cmd = ql_command_24xx_iocb; 983 ha->ip_cmd = ql_ip_24xx_iocb; 984 ha->ms_cmd = ql_ms_24xx_iocb; 985 ha->els_cmd = ql_els_24xx_iocb; 986 ha->cmd_segs = CMD_TYPE_7_DATA_SEGMENTS; 987 ha->cmd_cont_segs = CONT_TYPE_1_DATA_SEGMENTS; 988 break; 989 990 case 0x2522: 991 case 0x2532: 992 if (ql_pci_config_get8(ha, PCI_CONF_IPIN) == 2) { 993 ha->flags |= FUNCTION_1; 994 } 995 ha->cfg_flags |= CFG_CTRL_25XX; 996 ha->flags |= VP_ENABLED; 997 ha->fw_class = 0x2500; 998 ha->reg_off = ®_off_2400_2500; 999 if (ql_fwmodule_resolve(ha) != QL_SUCCESS) { 1000 goto attach_failed; 1001 } 1002 ha->risc_dump_size = QL_25XX_FW_DUMP_SIZE; 1003 ha->fcp_cmd = ql_command_24xx_iocb; 1004 ha->ip_cmd = ql_ip_24xx_iocb; 1005 ha->ms_cmd = ql_ms_24xx_iocb; 1006 ha->els_cmd = ql_els_24xx_iocb; 1007 ha->cmd_segs = CMD_TYPE_7_DATA_SEGMENTS; 1008 ha->cmd_cont_segs = CONT_TYPE_1_DATA_SEGMENTS; 1009 break; 1010 1011 case 0x8001: 1012 if (ql_pci_config_get8(ha, PCI_CONF_IPIN) == 4) { 1013 ha->flags |= FUNCTION_1; 1014 } 1015 ha->cfg_flags |= CFG_CTRL_81XX; 1016 ha->flags |= VP_ENABLED; 1017 ha->fw_class = 0x8100; 1018 ha->reg_off = ®_off_2400_2500; 1019 if (ql_fwmodule_resolve(ha) != QL_SUCCESS) { 1020 goto attach_failed; 1021 } 1022 ha->risc_dump_size = QL_25XX_FW_DUMP_SIZE; 1023 ha->fcp_cmd = ql_command_24xx_iocb; 1024 ha->ip_cmd = ql_ip_24xx_iocb; 1025 ha->ms_cmd = ql_ms_24xx_iocb; 1026 ha->cmd_segs = CMD_TYPE_7_DATA_SEGMENTS; 1027 ha->cmd_cont_segs = CONT_TYPE_1_DATA_SEGMENTS; 1028 break; 1029 1030 default: 1031 cmn_err(CE_WARN, "%s(%d): Unsupported device id: %x", 1032 QL_NAME, instance, ha->device_id); 1033 goto attach_failed; 1034 } 1035 1036 /* Setup hba buffer. */ 1037 1038 size = CFG_IST(ha, CFG_CTRL_242581) ? 1039 (REQUEST_QUEUE_SIZE + RESPONSE_QUEUE_SIZE) : 1040 (REQUEST_QUEUE_SIZE + RESPONSE_QUEUE_SIZE + 1041 RCVBUF_QUEUE_SIZE); 1042 1043 if (ql_get_dma_mem(ha, &ha->hba_buf, size, LITTLE_ENDIAN_DMA, 1044 QL_DMA_RING_ALIGN) != QL_SUCCESS) { 1045 cmn_err(CE_WARN, "%s(%d): request queue DMA memory " 1046 "alloc failed", QL_NAME, instance); 1047 goto attach_failed; 1048 } 1049 progress |= QL_HBA_BUFFER_SETUP; 1050 1051 /* Setup buffer pointers. */ 1052 ha->request_dvma = ha->hba_buf.cookie.dmac_laddress + 1053 REQUEST_Q_BUFFER_OFFSET; 1054 ha->request_ring_bp = (struct cmd_entry *) 1055 ((caddr_t)ha->hba_buf.bp + REQUEST_Q_BUFFER_OFFSET); 1056 1057 ha->response_dvma = ha->hba_buf.cookie.dmac_laddress + 1058 RESPONSE_Q_BUFFER_OFFSET; 1059 ha->response_ring_bp = (struct sts_entry *) 1060 ((caddr_t)ha->hba_buf.bp + RESPONSE_Q_BUFFER_OFFSET); 1061 1062 ha->rcvbuf_dvma = ha->hba_buf.cookie.dmac_laddress + 1063 RCVBUF_Q_BUFFER_OFFSET; 1064 ha->rcvbuf_ring_bp = (struct rcvbuf *) 1065 ((caddr_t)ha->hba_buf.bp + RCVBUF_Q_BUFFER_OFFSET); 1066 1067 /* Allocate resource for QLogic IOCTL */ 1068 (void) ql_alloc_xioctl_resource(ha); 1069 1070 /* Setup interrupts */ 1071 if ((rval = ql_setup_interrupts(ha)) != DDI_SUCCESS) { 1072 cmn_err(CE_WARN, "%s(%d): Failed to add interrupt, " 1073 "rval=%xh", QL_NAME, instance, rval); 1074 goto attach_failed; 1075 } 1076 1077 progress |= (QL_INTR_ADDED | QL_MUTEX_CV_INITED); 1078 1079 /* 1080 * Allocate an N Port information structure 1081 * for use when in P2P topology. 1082 */ 1083 ha->n_port = (ql_n_port_info_t *) 1084 kmem_zalloc(sizeof (ql_n_port_info_t), KM_SLEEP); 1085 if (ha->n_port == NULL) { 1086 cmn_err(CE_WARN, "%s(%d): Failed to create N Port info", 1087 QL_NAME, instance); 1088 goto attach_failed; 1089 } 1090 1091 progress |= QL_N_PORT_INFO_CREATED; 1092 1093 /* 1094 * Determine support for Power Management 1095 */ 1096 caps_ptr = (uint8_t)ql_pci_config_get8(ha, PCI_CONF_CAP_PTR); 1097 1098 while (caps_ptr != PCI_CAP_NEXT_PTR_NULL) { 1099 cap = (uint8_t)ql_pci_config_get8(ha, caps_ptr); 1100 if (cap == PCI_CAP_ID_PM) { 1101 ha->pm_capable = 1; 1102 break; 1103 } 1104 caps_ptr = (uint8_t)ql_pci_config_get8(ha, caps_ptr + 1105 PCI_CAP_NEXT_PTR); 1106 } 1107 1108 if (ha->pm_capable) { 1109 /* 1110 * Enable PM for 2200 based HBAs only. 1111 */ 1112 if (ha->device_id != 0x2200) { 1113 ha->pm_capable = 0; 1114 } 1115 } 1116 1117 if (ha->pm_capable) { 1118 ha->pm_capable = ql_enable_pm; 1119 } 1120 1121 if (ha->pm_capable) { 1122 /* 1123 * Initialize power management bookkeeping; 1124 * components are created idle. 1125 */ 1126 (void) sprintf(buf, "NAME=%s(%d)", QL_NAME, instance); 1127 pmcomps[0] = buf; 1128 1129 /*LINTED [Solaris DDI_DEV_T_NONE Lint warning]*/ 1130 if (ddi_prop_update_string_array(DDI_DEV_T_NONE, 1131 dip, "pm-components", pmcomps, 1132 sizeof (pmcomps) / sizeof (pmcomps[0])) != 1133 DDI_PROP_SUCCESS) { 1134 cmn_err(CE_WARN, "%s(%d): failed to create" 1135 " pm-components property", QL_NAME, 1136 instance); 1137 1138 /* Initialize adapter. */ 1139 ha->power_level = PM_LEVEL_D0; 1140 if (ql_initialize_adapter(ha) != QL_SUCCESS) { 1141 cmn_err(CE_WARN, "%s(%d): failed to" 1142 " initialize adapter", QL_NAME, 1143 instance); 1144 goto attach_failed; 1145 } 1146 } else { 1147 ha->power_level = PM_LEVEL_D3; 1148 if (pm_raise_power(dip, QL_POWER_COMPONENT, 1149 PM_LEVEL_D0) != DDI_SUCCESS) { 1150 cmn_err(CE_WARN, "%s(%d): failed to" 1151 " raise power or initialize" 1152 " adapter", QL_NAME, instance); 1153 } 1154 ASSERT(ha->power_level == PM_LEVEL_D0); 1155 } 1156 } else { 1157 /* Initialize adapter. */ 1158 ha->power_level = PM_LEVEL_D0; 1159 if (ql_initialize_adapter(ha) != QL_SUCCESS) { 1160 cmn_err(CE_WARN, "%s(%d): failed to initialize" 1161 " adapter", QL_NAME, instance); 1162 } 1163 } 1164 1165 if (ha->fw_major_version == 0 && ha->fw_minor_version == 0 && 1166 ha->fw_subminor_version == 0) { 1167 cmn_err(CE_NOTE, "!%s(%d): Firmware not loaded", 1168 QL_NAME, ha->instance); 1169 } else { 1170 int rval; 1171 char ver_fmt[256]; 1172 1173 rval = (int)snprintf(ver_fmt, (size_t)sizeof (ver_fmt), 1174 "Firmware version %d.%d.%d", ha->fw_major_version, 1175 ha->fw_minor_version, ha->fw_subminor_version); 1176 1177 if (CFG_IST(ha, CFG_CTRL_81XX)) { 1178 rval = (int)snprintf(ver_fmt + rval, 1179 (size_t)sizeof (ver_fmt), 1180 ", MPI fw version %d.%d.%d", 1181 ha->mpi_fw_major_version, 1182 ha->mpi_fw_minor_version, 1183 ha->mpi_fw_subminor_version); 1184 1185 if (ha->subsys_id == 0x17B || 1186 ha->subsys_id == 0x17D) { 1187 (void) snprintf(ver_fmt + rval, 1188 (size_t)sizeof (ver_fmt), 1189 ", PHY fw version %d.%d.%d", 1190 ha->phy_fw_major_version, 1191 ha->phy_fw_minor_version, 1192 ha->phy_fw_subminor_version); 1193 } 1194 } 1195 cmn_err(CE_NOTE, "!%s(%d): %s", 1196 QL_NAME, ha->instance, ver_fmt); 1197 } 1198 1199 ha->k_stats = kstat_create(QL_NAME, instance, "statistics", 1200 "controller", KSTAT_TYPE_RAW, 1201 (uint32_t)sizeof (ql_adapter_stat_t), KSTAT_FLAG_VIRTUAL); 1202 if (ha->k_stats == NULL) { 1203 cmn_err(CE_WARN, "%s(%d): Failed to create kstat", 1204 QL_NAME, instance); 1205 goto attach_failed; 1206 } 1207 progress |= QL_KSTAT_CREATED; 1208 1209 ha->adapter_stats->version = 1; 1210 ha->k_stats->ks_data = (void *)ha->adapter_stats; 1211 ha->k_stats->ks_private = ha; 1212 ha->k_stats->ks_update = ql_kstat_update; 1213 ha->k_stats->ks_ndata = 1; 1214 ha->k_stats->ks_data_size = sizeof (ql_adapter_stat_t); 1215 kstat_install(ha->k_stats); 1216 1217 if (ddi_create_minor_node(dip, "devctl", S_IFCHR, 1218 instance, DDI_NT_NEXUS, 0) != DDI_SUCCESS) { 1219 cmn_err(CE_WARN, "%s(%d): failed to create minor node", 1220 QL_NAME, instance); 1221 goto attach_failed; 1222 } 1223 progress |= QL_MINOR_NODE_CREATED; 1224 1225 /* Allocate a transport structure for this instance */ 1226 tran = kmem_zalloc(sizeof (fc_fca_tran_t), KM_SLEEP); 1227 ASSERT(tran != NULL); 1228 1229 progress |= QL_FCA_TRAN_ALLOCED; 1230 1231 /* fill in the structure */ 1232 tran->fca_numports = 1; 1233 tran->fca_version = FCTL_FCA_MODREV_5; 1234 if (CFG_IST(ha, CFG_CTRL_2422)) { 1235 tran->fca_num_npivports = MAX_24_VIRTUAL_PORTS; 1236 } else if (CFG_IST(ha, CFG_CTRL_2581)) { 1237 tran->fca_num_npivports = MAX_25_VIRTUAL_PORTS; 1238 } 1239 bcopy(ha->loginparams.node_ww_name.raw_wwn, 1240 tran->fca_perm_pwwn.raw_wwn, 8); 1241 1242 EL(ha, "FCA version %d\n", tran->fca_version); 1243 1244 /* Specify the amount of space needed in each packet */ 1245 tran->fca_pkt_size = sizeof (ql_srb_t); 1246 1247 /* command limits are usually dictated by hardware */ 1248 tran->fca_cmd_max = MAX_OUTSTANDING_COMMANDS; 1249 1250 /* dmaattr are static, set elsewhere. */ 1251 if (CFG_IST(ha, CFG_ENABLE_64BIT_ADDRESSING)) { 1252 tran->fca_dma_attr = &ql_64bit_io_dma_attr; 1253 tran->fca_dma_fcp_cmd_attr = &ql_64fcp_cmd_dma_attr; 1254 tran->fca_dma_fcp_rsp_attr = &ql_64fcp_rsp_dma_attr; 1255 tran->fca_dma_fcp_data_attr = &ql_64fcp_data_dma_attr; 1256 tran->fca_dma_fcsm_cmd_attr = &ql_64fcsm_cmd_dma_attr; 1257 tran->fca_dma_fcsm_rsp_attr = &ql_64fcsm_rsp_dma_attr; 1258 tran->fca_dma_fcip_cmd_attr = &ql_64fcip_cmd_dma_attr; 1259 tran->fca_dma_fcip_rsp_attr = &ql_64fcip_rsp_dma_attr; 1260 } else { 1261 tran->fca_dma_attr = &ql_32bit_io_dma_attr; 1262 tran->fca_dma_fcp_cmd_attr = &ql_32fcp_cmd_dma_attr; 1263 tran->fca_dma_fcp_rsp_attr = &ql_32fcp_rsp_dma_attr; 1264 tran->fca_dma_fcp_data_attr = &ql_32fcp_data_dma_attr; 1265 tran->fca_dma_fcsm_cmd_attr = &ql_32fcsm_cmd_dma_attr; 1266 tran->fca_dma_fcsm_rsp_attr = &ql_32fcsm_rsp_dma_attr; 1267 tran->fca_dma_fcip_cmd_attr = &ql_32fcip_cmd_dma_attr; 1268 tran->fca_dma_fcip_rsp_attr = &ql_32fcip_rsp_dma_attr; 1269 } 1270 1271 tran->fca_acc_attr = &ql_dev_acc_attr; 1272 tran->fca_iblock = &(ha->iblock_cookie); 1273 1274 /* the remaining values are simply function vectors */ 1275 tran->fca_bind_port = ql_bind_port; 1276 tran->fca_unbind_port = ql_unbind_port; 1277 tran->fca_init_pkt = ql_init_pkt; 1278 tran->fca_un_init_pkt = ql_un_init_pkt; 1279 tran->fca_els_send = ql_els_send; 1280 tran->fca_get_cap = ql_get_cap; 1281 tran->fca_set_cap = ql_set_cap; 1282 tran->fca_getmap = ql_getmap; 1283 tran->fca_transport = ql_transport; 1284 tran->fca_ub_alloc = ql_ub_alloc; 1285 tran->fca_ub_free = ql_ub_free; 1286 tran->fca_ub_release = ql_ub_release; 1287 tran->fca_abort = ql_abort; 1288 tran->fca_reset = ql_reset; 1289 tran->fca_port_manage = ql_port_manage; 1290 tran->fca_get_device = ql_get_device; 1291 1292 /* give it to the FC transport */ 1293 if (fc_fca_attach(dip, tran) != DDI_SUCCESS) { 1294 cmn_err(CE_WARN, "%s(%d): FCA attach failed", QL_NAME, 1295 instance); 1296 goto attach_failed; 1297 } 1298 progress |= QL_FCA_ATTACH_DONE; 1299 1300 /* Stash the structure so it can be freed at detach */ 1301 ha->tran = tran; 1302 1303 /* Acquire global state lock. */ 1304 GLOBAL_STATE_LOCK(); 1305 1306 /* Add adapter structure to link list. */ 1307 ql_add_link_b(&ql_hba, &ha->hba); 1308 1309 /* Start one second driver timer. */ 1310 if (ql_timer_timeout_id == NULL) { 1311 ql_timer_ticks = drv_usectohz(1000000); 1312 ql_timer_timeout_id = timeout(ql_timer, (void *)0, 1313 ql_timer_ticks); 1314 } 1315 1316 /* Release global state lock. */ 1317 GLOBAL_STATE_UNLOCK(); 1318 1319 /* Determine and populate HBA fru info */ 1320 ql_setup_fruinfo(ha); 1321 1322 /* Setup task_daemon thread. */ 1323 (void) thread_create(NULL, 0, (void (*)())ql_task_daemon, ha, 1324 0, &p0, TS_RUN, minclsyspri); 1325 1326 progress |= QL_TASK_DAEMON_STARTED; 1327 1328 ddi_report_dev(dip); 1329 1330 /* Disable link reset in panic path */ 1331 ha->lip_on_panic = 1; 1332 1333 rval = DDI_SUCCESS; 1334 break; 1335 1336 attach_failed: 1337 if (progress & QL_FCA_ATTACH_DONE) { 1338 (void) fc_fca_detach(dip); 1339 progress &= ~QL_FCA_ATTACH_DONE; 1340 } 1341 1342 if (progress & QL_FCA_TRAN_ALLOCED) { 1343 kmem_free(tran, sizeof (fc_fca_tran_t)); 1344 progress &= ~QL_FCA_TRAN_ALLOCED; 1345 } 1346 1347 if (progress & QL_MINOR_NODE_CREATED) { 1348 ddi_remove_minor_node(dip, "devctl"); 1349 progress &= ~QL_MINOR_NODE_CREATED; 1350 } 1351 1352 if (progress & QL_KSTAT_CREATED) { 1353 kstat_delete(ha->k_stats); 1354 progress &= ~QL_KSTAT_CREATED; 1355 } 1356 1357 if (progress & QL_N_PORT_INFO_CREATED) { 1358 kmem_free(ha->n_port, sizeof (ql_n_port_info_t)); 1359 progress &= ~QL_N_PORT_INFO_CREATED; 1360 } 1361 1362 if (progress & QL_TASK_DAEMON_STARTED) { 1363 TASK_DAEMON_LOCK(ha); 1364 1365 ha->task_daemon_flags |= TASK_DAEMON_STOP_FLG; 1366 1367 cv_signal(&ha->cv_task_daemon); 1368 1369 /* Release task daemon lock. */ 1370 TASK_DAEMON_UNLOCK(ha); 1371 1372 /* Wait for for task daemon to stop running. */ 1373 while (ha->task_daemon_flags & TASK_DAEMON_STOP_FLG) { 1374 ql_delay(ha, 10000); 1375 } 1376 progress &= ~QL_TASK_DAEMON_STARTED; 1377 } 1378 1379 if (progress & QL_IOMAP_IOBASE_MAPPED) { 1380 ddi_regs_map_free(&ha->iomap_dev_handle); 1381 progress &= ~QL_IOMAP_IOBASE_MAPPED; 1382 } 1383 1384 if (progress & QL_CONFIG_SPACE_SETUP) { 1385 if (CFG_IST(ha, CFG_SBUS_CARD)) { 1386 ddi_regs_map_free(&ha->sbus_config_handle); 1387 } else { 1388 pci_config_teardown(&ha->pci_handle); 1389 } 1390 progress &= ~QL_CONFIG_SPACE_SETUP; 1391 } 1392 1393 if (progress & QL_INTR_ADDED) { 1394 ql_disable_intr(ha); 1395 ql_release_intr(ha); 1396 progress &= ~QL_INTR_ADDED; 1397 } 1398 1399 if (progress & QL_MUTEX_CV_INITED) { 1400 ql_destroy_mutex(ha); 1401 progress &= ~QL_MUTEX_CV_INITED; 1402 } 1403 1404 if (progress & QL_HBA_BUFFER_SETUP) { 1405 ql_free_phys(ha, &ha->hba_buf); 1406 progress &= ~QL_HBA_BUFFER_SETUP; 1407 } 1408 1409 if (progress & QL_REGS_MAPPED) { 1410 ddi_regs_map_free(&ha->dev_handle); 1411 if (ha->sbus_fpga_iobase != NULL) { 1412 ddi_regs_map_free(&ha->sbus_fpga_dev_handle); 1413 } 1414 progress &= ~QL_REGS_MAPPED; 1415 } 1416 1417 if (progress & QL_SOFT_STATE_ALLOCED) { 1418 1419 ql_fcache_rel(ha->fcache); 1420 1421 ASSERT(ha->dev && ha->outstanding_cmds && 1422 ha->ub_array && ha->adapter_stats); 1423 1424 kmem_free(ha->adapter_stats, 1425 sizeof (*ha->adapter_stats)); 1426 1427 kmem_free(ha->ub_array, sizeof (*ha->ub_array) * 1428 QL_UB_LIMIT); 1429 1430 kmem_free(ha->outstanding_cmds, 1431 sizeof (*ha->outstanding_cmds) * 1432 MAX_OUTSTANDING_COMMANDS); 1433 1434 if (ha->devpath != NULL) { 1435 kmem_free(ha->devpath, 1436 strlen(ha->devpath) + 1); 1437 } 1438 1439 kmem_free(ha->dev, sizeof (*ha->dev) * 1440 DEVICE_HEAD_LIST_SIZE); 1441 1442 if (ha->xioctl != NULL) { 1443 ql_free_xioctl_resource(ha); 1444 } 1445 1446 if (ha->fw_module != NULL) { 1447 (void) ddi_modclose(ha->fw_module); 1448 } 1449 1450 ddi_soft_state_free(ql_state, instance); 1451 progress &= ~QL_SOFT_STATE_ALLOCED; 1452 } 1453 ASSERT(progress == 0); 1454 1455 ddi_prop_remove_all(dip); 1456 rval = DDI_FAILURE; 1457 break; 1458 1459 case DDI_RESUME: 1460 rval = DDI_FAILURE; 1461 1462 ha = ddi_get_soft_state(ql_state, ddi_get_instance(dip)); 1463 if (ha == NULL) { 1464 cmn_err(CE_WARN, "%s(%d): can't get soft state", 1465 QL_NAME, instance); 1466 break; 1467 } 1468 1469 ha->power_level = PM_LEVEL_D3; 1470 if (ha->pm_capable) { 1471 /* 1472 * Get ql_power to do power on initialization 1473 */ 1474 if (pm_raise_power(dip, QL_POWER_COMPONENT, 1475 PM_LEVEL_D0) != DDI_SUCCESS) { 1476 cmn_err(CE_WARN, "%s(%d): can't raise adapter" 1477 " power", QL_NAME, instance); 1478 } 1479 } 1480 1481 /* 1482 * There is a bug in DR that prevents PM framework 1483 * from calling ql_power. 1484 */ 1485 if (ha->power_level == PM_LEVEL_D3) { 1486 ha->power_level = PM_LEVEL_D0; 1487 1488 if (ql_initialize_adapter(ha) != QL_SUCCESS) { 1489 cmn_err(CE_WARN, "%s(%d): can't initialize the" 1490 " adapter", QL_NAME, instance); 1491 } 1492 1493 /* Wake up task_daemon. */ 1494 ql_awaken_task_daemon(ha, NULL, TASK_DAEMON_ALIVE_FLG, 1495 0); 1496 } 1497 1498 /* Acquire global state lock. */ 1499 GLOBAL_STATE_LOCK(); 1500 1501 /* Restart driver timer. */ 1502 if (ql_timer_timeout_id == NULL) { 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 /* Wake up command start routine. */ 1511 ADAPTER_STATE_LOCK(ha); 1512 ha->flags &= ~ADAPTER_SUSPENDED; 1513 ADAPTER_STATE_UNLOCK(ha); 1514 1515 /* 1516 * Transport doesn't make FC discovery in polled 1517 * mode; So we need the daemon thread's services 1518 * right here. 1519 */ 1520 (void) callb_generic_cpr(&ha->cprinfo, CB_CODE_CPR_RESUME); 1521 1522 rval = DDI_SUCCESS; 1523 1524 /* Restart IP if it was running. */ 1525 if (ha->flags & IP_ENABLED && !(ha->flags & IP_INITIALIZED)) { 1526 (void) ql_initialize_ip(ha); 1527 ql_isp_rcvbuf(ha); 1528 } 1529 break; 1530 1531 default: 1532 cmn_err(CE_WARN, "%s(%d): attach, unknown code:" 1533 " %x", QL_NAME, ddi_get_instance(dip), cmd); 1534 rval = DDI_FAILURE; 1535 break; 1536 } 1537 1538 kmem_free(buf, MAXPATHLEN); 1539 1540 if (rval != DDI_SUCCESS) { 1541 /*EMPTY*/ 1542 QL_PRINT_2(CE_CONT, "(%d): failed, rval = %xh\n", 1543 ddi_get_instance(dip), rval); 1544 } else { 1545 /*EMPTY*/ 1546 QL_PRINT_3(CE_CONT, "(%d): done\n", ddi_get_instance(dip)); 1547 } 1548 1549 return (rval); 1550 } 1551 1552 /* 1553 * ql_detach 1554 * Used to remove all the states associated with a given 1555 * instances of a device node prior to the removal of that 1556 * instance from the system. 1557 * 1558 * Input: 1559 * dip = pointer to device information structure. 1560 * cmd = type of detach. 1561 * 1562 * Returns: 1563 * DDI_SUCCESS or DDI_FAILURE. 1564 * 1565 * Context: 1566 * Kernel context. 1567 */ 1568 static int 1569 ql_detach(dev_info_t *dip, ddi_detach_cmd_t cmd) 1570 { 1571 ql_adapter_state_t *ha, *vha; 1572 ql_tgt_t *tq; 1573 int try; 1574 uint16_t index; 1575 ql_link_t *link; 1576 char *buf; 1577 timeout_id_t timer_id = NULL; 1578 int rval = DDI_SUCCESS; 1579 1580 ha = ddi_get_soft_state(ql_state, ddi_get_instance(dip)); 1581 if (ha == NULL) { 1582 QL_PRINT_2(CE_CONT, "(%d): no adapter\n", 1583 ddi_get_instance(dip)); 1584 return (DDI_FAILURE); 1585 } 1586 1587 QL_PRINT_3(CE_CONT, "(%d): started, cmd=%xh\n", ha->instance, cmd); 1588 1589 buf = (char *)(kmem_zalloc(MAXPATHLEN, KM_SLEEP)); 1590 1591 switch (cmd) { 1592 case DDI_DETACH: 1593 ADAPTER_STATE_LOCK(ha); 1594 ha->flags |= (ADAPTER_SUSPENDED | ABORT_CMDS_LOOP_DOWN_TMO); 1595 ADAPTER_STATE_UNLOCK(ha); 1596 1597 /* Acquire task daemon lock. */ 1598 TASK_DAEMON_LOCK(ha); 1599 1600 ha->task_daemon_flags |= TASK_DAEMON_STOP_FLG; 1601 cv_signal(&ha->cv_task_daemon); 1602 1603 /* Release task daemon lock. */ 1604 TASK_DAEMON_UNLOCK(ha); 1605 1606 /* 1607 * Wait for task daemon to stop running. 1608 * Internal command timeout is approximately 1609 * 30 seconds, so it would help in some corner 1610 * cases to wait that long 1611 */ 1612 try = 0; 1613 while ((ha->task_daemon_flags & TASK_DAEMON_STOP_FLG) && 1614 try < 3000) { 1615 ql_delay(ha, 10000); 1616 try++; 1617 } 1618 1619 TASK_DAEMON_LOCK(ha); 1620 if (ha->task_daemon_flags & TASK_DAEMON_STOP_FLG) { 1621 ha->task_daemon_flags &= ~TASK_DAEMON_STOP_FLG; 1622 TASK_DAEMON_UNLOCK(ha); 1623 EL(ha, "failed, could not stop task daemon\n"); 1624 return (DDI_FAILURE); 1625 } 1626 TASK_DAEMON_UNLOCK(ha); 1627 1628 /* Acquire global state lock. */ 1629 GLOBAL_STATE_LOCK(); 1630 1631 /* Disable driver timer if no adapters. */ 1632 if (ql_timer_timeout_id && ql_hba.first == &ha->hba && 1633 ql_hba.last == &ha->hba) { 1634 timer_id = ql_timer_timeout_id; 1635 ql_timer_timeout_id = NULL; 1636 } 1637 ql_remove_link(&ql_hba, &ha->hba); 1638 1639 GLOBAL_STATE_UNLOCK(); 1640 1641 if (timer_id) { 1642 (void) untimeout(timer_id); 1643 } 1644 1645 if (ha->pm_capable) { 1646 if (pm_lower_power(dip, QL_POWER_COMPONENT, 1647 PM_LEVEL_D3) != DDI_SUCCESS) { 1648 cmn_err(CE_WARN, "%s(%d): failed to lower the" 1649 " power", QL_NAME, ha->instance); 1650 } 1651 } 1652 1653 /* 1654 * If pm_lower_power shutdown the adapter, there 1655 * isn't much else to do 1656 */ 1657 if (ha->power_level != PM_LEVEL_D3) { 1658 ql_halt(ha, PM_LEVEL_D3); 1659 } 1660 1661 /* Remove virtual ports. */ 1662 while ((vha = ha->vp_next) != NULL) { 1663 ql_vport_destroy(vha); 1664 } 1665 1666 /* Free target queues. */ 1667 for (index = 0; index < DEVICE_HEAD_LIST_SIZE; index++) { 1668 link = ha->dev[index].first; 1669 while (link != NULL) { 1670 tq = link->base_address; 1671 link = link->next; 1672 ql_dev_free(ha, tq); 1673 } 1674 } 1675 1676 /* 1677 * Free unsolicited buffers. 1678 * If we are here then there are no ULPs still 1679 * alive that wish to talk to ql so free up 1680 * any SRB_IP_UB_UNUSED buffers that are 1681 * lingering around 1682 */ 1683 QL_UB_LOCK(ha); 1684 for (index = 0; index < QL_UB_LIMIT; index++) { 1685 fc_unsol_buf_t *ubp = ha->ub_array[index]; 1686 1687 if (ubp != NULL) { 1688 ql_srb_t *sp = ubp->ub_fca_private; 1689 1690 sp->flags |= SRB_UB_FREE_REQUESTED; 1691 1692 while (!(sp->flags & SRB_UB_IN_FCA) || 1693 (sp->flags & (SRB_UB_CALLBACK | 1694 SRB_UB_ACQUIRED))) { 1695 QL_UB_UNLOCK(ha); 1696 delay(drv_usectohz(100000)); 1697 QL_UB_LOCK(ha); 1698 } 1699 ha->ub_array[index] = NULL; 1700 1701 QL_UB_UNLOCK(ha); 1702 ql_free_unsolicited_buffer(ha, ubp); 1703 QL_UB_LOCK(ha); 1704 } 1705 } 1706 QL_UB_UNLOCK(ha); 1707 1708 /* Free any saved RISC code. */ 1709 if (ha->risc_code != NULL) { 1710 kmem_free(ha->risc_code, ha->risc_code_size); 1711 ha->risc_code = NULL; 1712 ha->risc_code_size = 0; 1713 } 1714 1715 if (ha->fw_module != NULL) { 1716 (void) ddi_modclose(ha->fw_module); 1717 ha->fw_module = NULL; 1718 } 1719 1720 /* Free resources. */ 1721 ddi_prop_remove_all(dip); 1722 (void) fc_fca_detach(dip); 1723 kmem_free(ha->tran, sizeof (fc_fca_tran_t)); 1724 ddi_remove_minor_node(dip, "devctl"); 1725 if (ha->k_stats != NULL) { 1726 kstat_delete(ha->k_stats); 1727 } 1728 1729 if (CFG_IST(ha, CFG_SBUS_CARD)) { 1730 ddi_regs_map_free(&ha->sbus_config_handle); 1731 } else { 1732 ddi_regs_map_free(&ha->iomap_dev_handle); 1733 pci_config_teardown(&ha->pci_handle); 1734 } 1735 1736 ql_disable_intr(ha); 1737 ql_release_intr(ha); 1738 1739 ql_free_xioctl_resource(ha); 1740 1741 ql_destroy_mutex(ha); 1742 1743 ql_free_phys(ha, &ha->hba_buf); 1744 ql_free_phys(ha, &ha->fwexttracebuf); 1745 ql_free_phys(ha, &ha->fwfcetracebuf); 1746 1747 ddi_regs_map_free(&ha->dev_handle); 1748 if (ha->sbus_fpga_iobase != NULL) { 1749 ddi_regs_map_free(&ha->sbus_fpga_dev_handle); 1750 } 1751 1752 ql_fcache_rel(ha->fcache); 1753 if (ha->vcache != NULL) { 1754 kmem_free(ha->vcache, QL_24XX_VPD_SIZE); 1755 } 1756 1757 if (ha->pi_attrs != NULL) { 1758 kmem_free(ha->pi_attrs, sizeof (fca_port_attrs_t)); 1759 } 1760 1761 ASSERT(ha->dev && ha->outstanding_cmds && ha->ub_array && 1762 ha->adapter_stats); 1763 1764 kmem_free(ha->adapter_stats, sizeof (*ha->adapter_stats)); 1765 1766 kmem_free(ha->ub_array, sizeof (*ha->ub_array) * QL_UB_LIMIT); 1767 1768 kmem_free(ha->outstanding_cmds, 1769 sizeof (*ha->outstanding_cmds) * MAX_OUTSTANDING_COMMANDS); 1770 1771 if (ha->n_port != NULL) { 1772 kmem_free(ha->n_port, sizeof (ql_n_port_info_t)); 1773 } 1774 1775 if (ha->devpath != NULL) { 1776 kmem_free(ha->devpath, strlen(ha->devpath) + 1); 1777 } 1778 1779 kmem_free(ha->dev, sizeof (*ha->dev) * DEVICE_HEAD_LIST_SIZE); 1780 1781 EL(ha, "detached\n"); 1782 1783 ddi_soft_state_free(ql_state, (int)ha->instance); 1784 1785 break; 1786 1787 case DDI_SUSPEND: 1788 ADAPTER_STATE_LOCK(ha); 1789 1790 try = 0; 1791 ha->flags |= ADAPTER_SUSPENDED; 1792 while (ha->flags & ADAPTER_TIMER_BUSY && try++ < 10) { 1793 ADAPTER_STATE_UNLOCK(ha); 1794 delay(drv_usectohz(1000000)); 1795 ADAPTER_STATE_LOCK(ha); 1796 } 1797 if (ha->busy || ha->flags & ADAPTER_TIMER_BUSY) { 1798 ha->flags &= ~ADAPTER_SUSPENDED; 1799 ADAPTER_STATE_UNLOCK(ha); 1800 rval = DDI_FAILURE; 1801 cmn_err(CE_WARN, "!%s(%d): Fail suspend" 1802 " busy %xh flags %xh", QL_NAME, ha->instance, 1803 ha->busy, ha->flags); 1804 break; 1805 } 1806 1807 ADAPTER_STATE_UNLOCK(ha); 1808 1809 if (ha->flags & IP_INITIALIZED) { 1810 (void) ql_shutdown_ip(ha); 1811 } 1812 1813 try = ql_suspend_adapter(ha); 1814 if (try != QL_SUCCESS) { 1815 ADAPTER_STATE_LOCK(ha); 1816 ha->flags &= ~ADAPTER_SUSPENDED; 1817 ADAPTER_STATE_UNLOCK(ha); 1818 cmn_err(CE_WARN, "%s(%d): Fail suspend rval %xh", 1819 QL_NAME, ha->instance, try); 1820 1821 /* Restart IP if it was running. */ 1822 if (ha->flags & IP_ENABLED && 1823 !(ha->flags & IP_INITIALIZED)) { 1824 (void) ql_initialize_ip(ha); 1825 ql_isp_rcvbuf(ha); 1826 } 1827 rval = DDI_FAILURE; 1828 break; 1829 } 1830 1831 /* Acquire global state lock. */ 1832 GLOBAL_STATE_LOCK(); 1833 1834 /* Disable driver timer if last adapter. */ 1835 if (ql_timer_timeout_id && ql_hba.first == &ha->hba && 1836 ql_hba.last == &ha->hba) { 1837 timer_id = ql_timer_timeout_id; 1838 ql_timer_timeout_id = NULL; 1839 } 1840 GLOBAL_STATE_UNLOCK(); 1841 1842 if (timer_id) { 1843 (void) untimeout(timer_id); 1844 } 1845 1846 break; 1847 1848 default: 1849 rval = DDI_FAILURE; 1850 break; 1851 } 1852 1853 kmem_free(buf, MAXPATHLEN); 1854 1855 if (rval != DDI_SUCCESS) { 1856 if (ha != NULL) { 1857 EL(ha, "failed, rval = %xh\n", rval); 1858 } else { 1859 /*EMPTY*/ 1860 QL_PRINT_2(CE_CONT, "(%d): failed, rval = %xh\n", 1861 ddi_get_instance(dip), rval); 1862 } 1863 } else { 1864 /*EMPTY*/ 1865 QL_PRINT_3(CE_CONT, "(%d): done\n", ddi_get_instance(dip)); 1866 } 1867 1868 return (rval); 1869 } 1870 1871 /* 1872 * ql_power 1873 * Power a device attached to the system. 1874 * 1875 * Input: 1876 * dip = pointer to device information structure. 1877 * component = device. 1878 * level = power level. 1879 * 1880 * Returns: 1881 * DDI_SUCCESS or DDI_FAILURE. 1882 * 1883 * Context: 1884 * Kernel context. 1885 */ 1886 /* ARGSUSED */ 1887 static int 1888 ql_power(dev_info_t *dip, int component, int level) 1889 { 1890 int rval = DDI_FAILURE; 1891 off_t csr; 1892 uint8_t saved_pm_val; 1893 ql_adapter_state_t *ha; 1894 char *buf; 1895 char *path; 1896 1897 ha = ddi_get_soft_state(ql_state, ddi_get_instance(dip)); 1898 if (ha == NULL || ha->pm_capable == 0) { 1899 QL_PRINT_2(CE_CONT, "(%d): no hba or PM not supported\n", 1900 ddi_get_instance(dip)); 1901 return (rval); 1902 } 1903 1904 QL_PRINT_10(CE_CONT, "(%d,%d): started\n", ha->instance, ha->vp_index); 1905 1906 buf = (char *)(kmem_zalloc(MAXPATHLEN, KM_SLEEP)); 1907 path = (char *)(kmem_zalloc(MAXPATHLEN, KM_SLEEP)); 1908 1909 if (component != QL_POWER_COMPONENT || (level != PM_LEVEL_D0 && 1910 level != PM_LEVEL_D3)) { 1911 EL(ha, "invalid, component=%xh or level=%xh\n", 1912 component, level); 1913 return (rval); 1914 } 1915 1916 GLOBAL_HW_LOCK(); 1917 csr = (uint8_t)ql_pci_config_get8(ha, PCI_CONF_CAP_PTR) + PCI_PMCSR; 1918 GLOBAL_HW_UNLOCK(); 1919 1920 ASSERT(csr == QL_PM_CS_REG); 1921 1922 (void) snprintf(buf, sizeof (buf), 1923 "Qlogic %s(%d): %s\n\t", QL_NAME, ddi_get_instance(dip), 1924 ddi_pathname(dip, path)); 1925 1926 switch (level) { 1927 case PM_LEVEL_D0: /* power up to D0 state - fully on */ 1928 1929 QL_PM_LOCK(ha); 1930 if (ha->power_level == PM_LEVEL_D0) { 1931 QL_PM_UNLOCK(ha); 1932 rval = DDI_SUCCESS; 1933 break; 1934 } 1935 1936 /* 1937 * Enable interrupts now 1938 */ 1939 saved_pm_val = ha->power_level; 1940 ha->power_level = PM_LEVEL_D0; 1941 QL_PM_UNLOCK(ha); 1942 1943 GLOBAL_HW_LOCK(); 1944 1945 ql_pci_config_put16(ha, csr, PCI_PMCSR_D0); 1946 1947 /* 1948 * Delay after reset, for chip to recover. 1949 * Otherwise causes system PANIC 1950 */ 1951 drv_usecwait(200000); 1952 1953 GLOBAL_HW_UNLOCK(); 1954 1955 if (ha->config_saved) { 1956 ha->config_saved = 0; 1957 if (QL_RESTORE_CONFIG_REGS(dip) != DDI_SUCCESS) { 1958 QL_PM_LOCK(ha); 1959 ha->power_level = saved_pm_val; 1960 QL_PM_UNLOCK(ha); 1961 cmn_err(CE_WARN, "%s failed to restore " 1962 "config regs", buf); 1963 break; 1964 } 1965 } 1966 1967 if (ql_initialize_adapter(ha) != QL_SUCCESS) { 1968 cmn_err(CE_WARN, "%s adapter initialization failed", 1969 buf); 1970 } 1971 1972 /* Wake up task_daemon. */ 1973 ql_awaken_task_daemon(ha, NULL, TASK_DAEMON_ALIVE_FLG | 1974 TASK_DAEMON_SLEEPING_FLG, 0); 1975 1976 /* Restart IP if it was running. */ 1977 if (ha->flags & IP_ENABLED && !(ha->flags & IP_INITIALIZED)) { 1978 (void) ql_initialize_ip(ha); 1979 ql_isp_rcvbuf(ha); 1980 } 1981 1982 cmn_err(CE_NOTE, QL_BANG "ql_power(%d): %s is powered ON\n", 1983 ha->instance, QL_NAME); 1984 1985 rval = DDI_SUCCESS; 1986 break; 1987 1988 case PM_LEVEL_D3: /* power down to D3 state - off */ 1989 1990 QL_PM_LOCK(ha); 1991 1992 if (ha->busy || ((ha->task_daemon_flags & 1993 TASK_DAEMON_SLEEPING_FLG) == 0)) { 1994 QL_PM_UNLOCK(ha); 1995 break; 1996 } 1997 1998 if (ha->power_level == PM_LEVEL_D3) { 1999 rval = DDI_SUCCESS; 2000 QL_PM_UNLOCK(ha); 2001 break; 2002 } 2003 QL_PM_UNLOCK(ha); 2004 2005 if (QL_SAVE_CONFIG_REGS(dip) != DDI_SUCCESS) { 2006 cmn_err(CE_WARN, "!Qlogic %s(%d): %s failed to save" 2007 " config regs", QL_NAME, ha->instance, buf); 2008 break; 2009 } 2010 ha->config_saved = 1; 2011 2012 /* 2013 * Don't enable interrupts. Running mailbox commands with 2014 * interrupts enabled could cause hangs since pm_run_scan() 2015 * runs out of a callout thread and on single cpu systems 2016 * cv_timedwait(), called from ql_mailbox_command(), would 2017 * not get to run. 2018 */ 2019 TASK_DAEMON_LOCK(ha); 2020 ha->task_daemon_flags |= TASK_DAEMON_POWERING_DOWN; 2021 TASK_DAEMON_UNLOCK(ha); 2022 2023 ql_halt(ha, PM_LEVEL_D3); 2024 2025 /* 2026 * Setup ql_intr to ignore interrupts from here on. 2027 */ 2028 QL_PM_LOCK(ha); 2029 ha->power_level = PM_LEVEL_D3; 2030 QL_PM_UNLOCK(ha); 2031 2032 /* 2033 * Wait for ISR to complete. 2034 */ 2035 INTR_LOCK(ha); 2036 ql_pci_config_put16(ha, csr, PCI_PMCSR_D3HOT); 2037 INTR_UNLOCK(ha); 2038 2039 cmn_err(CE_NOTE, QL_BANG "ql_power(%d): %s is powered OFF\n", 2040 ha->instance, QL_NAME); 2041 2042 rval = DDI_SUCCESS; 2043 break; 2044 } 2045 2046 kmem_free(buf, MAXPATHLEN); 2047 kmem_free(path, MAXPATHLEN); 2048 2049 QL_PRINT_10(CE_CONT, "(%d,%d): done\n", ha->instance, ha->vp_index); 2050 2051 return (rval); 2052 } 2053 2054 /* 2055 * ql_quiesce 2056 * quiesce a device attached to the system. 2057 * 2058 * Input: 2059 * dip = pointer to device information structure. 2060 * 2061 * Returns: 2062 * DDI_SUCCESS 2063 * 2064 * Context: 2065 * Kernel context. 2066 */ 2067 static int 2068 ql_quiesce(dev_info_t *dip) 2069 { 2070 ql_adapter_state_t *ha; 2071 uint32_t timer; 2072 uint32_t stat; 2073 2074 ha = ddi_get_soft_state(ql_state, ddi_get_instance(dip)); 2075 if (ha == NULL) { 2076 /* Oh well.... */ 2077 QL_PRINT_2(CE_CONT, "(%d): no adapter\n", 2078 ddi_get_instance(dip)); 2079 return (DDI_SUCCESS); 2080 } 2081 2082 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance); 2083 2084 if (CFG_IST(ha, CFG_CTRL_242581)) { 2085 WRT32_IO_REG(ha, hccr, HC24_CLR_RISC_INT); 2086 WRT16_IO_REG(ha, mailbox[0], MBC_STOP_FIRMWARE); 2087 WRT32_IO_REG(ha, hccr, HC24_SET_HOST_INT); 2088 for (timer = 0; timer < 30000; timer++) { 2089 stat = RD32_IO_REG(ha, intr_info_lo); 2090 if (stat & BIT_15) { 2091 if ((stat & 0xff) < 0x12) { 2092 WRT32_IO_REG(ha, hccr, 2093 HC24_CLR_RISC_INT); 2094 break; 2095 } 2096 WRT32_IO_REG(ha, hccr, HC24_CLR_RISC_INT); 2097 } 2098 drv_usecwait(100); 2099 } 2100 /* Reset the chip. */ 2101 WRT32_IO_REG(ha, ctrl_status, ISP_RESET | DMA_SHUTDOWN | 2102 MWB_4096_BYTES); 2103 drv_usecwait(100); 2104 2105 } else { 2106 /* Disable ISP interrupts. */ 2107 WRT16_IO_REG(ha, ictrl, 0); 2108 /* Select RISC module registers. */ 2109 WRT16_IO_REG(ha, ctrl_status, 0); 2110 /* Reset ISP semaphore. */ 2111 WRT16_IO_REG(ha, semaphore, 0); 2112 /* Reset RISC module. */ 2113 WRT16_IO_REG(ha, hccr, HC_RESET_RISC); 2114 /* Release RISC module. */ 2115 WRT16_IO_REG(ha, hccr, HC_RELEASE_RISC); 2116 } 2117 2118 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance); 2119 2120 return (DDI_SUCCESS); 2121 } 2122 2123 /* ************************************************************************ */ 2124 /* Fibre Channel Adapter (FCA) Transport Functions. */ 2125 /* ************************************************************************ */ 2126 2127 /* 2128 * ql_bind_port 2129 * Handling port binding. The FC Transport attempts to bind an FCA port 2130 * when it is ready to start transactions on the port. The FC Transport 2131 * will call the fca_bind_port() function specified in the fca_transport 2132 * structure it receives. The FCA must fill in the port_info structure 2133 * passed in the call and also stash the information for future calls. 2134 * 2135 * Input: 2136 * dip = pointer to FCA information structure. 2137 * port_info = pointer to port information structure. 2138 * bind_info = pointer to bind information structure. 2139 * 2140 * Returns: 2141 * NULL = failure 2142 * 2143 * Context: 2144 * Kernel context. 2145 */ 2146 static opaque_t 2147 ql_bind_port(dev_info_t *dip, fc_fca_port_info_t *port_info, 2148 fc_fca_bind_info_t *bind_info) 2149 { 2150 ql_adapter_state_t *ha, *vha; 2151 opaque_t fca_handle = NULL; 2152 port_id_t d_id; 2153 int port_npiv = bind_info->port_npiv; 2154 uchar_t *port_nwwn = bind_info->port_nwwn.raw_wwn; 2155 uchar_t *port_pwwn = bind_info->port_pwwn.raw_wwn; 2156 2157 /* get state info based on the dip */ 2158 ha = ddi_get_soft_state(ql_state, ddi_get_instance(dip)); 2159 if (ha == NULL) { 2160 QL_PRINT_2(CE_CONT, "(%d): no adapter\n", 2161 ddi_get_instance(dip)); 2162 return (NULL); 2163 } 2164 QL_PRINT_10(CE_CONT, "(%d,%d): started\n", ha->instance, ha->vp_index); 2165 2166 /* Verify port number is supported. */ 2167 if (port_npiv != 0) { 2168 if (!(ha->flags & VP_ENABLED)) { 2169 QL_PRINT_2(CE_CONT, "(%d): FC_NPIV_NOT_SUPPORTED\n", 2170 ha->instance); 2171 port_info->pi_error = FC_NPIV_NOT_SUPPORTED; 2172 return (NULL); 2173 } 2174 if (!(ha->flags & POINT_TO_POINT)) { 2175 QL_PRINT_2(CE_CONT, "(%d): FC_NPIV_WRONG_TOPOLOGY\n", 2176 ha->instance); 2177 port_info->pi_error = FC_NPIV_WRONG_TOPOLOGY; 2178 return (NULL); 2179 } 2180 if (!(ha->flags & FDISC_ENABLED)) { 2181 QL_PRINT_2(CE_CONT, "(%d): switch does not support " 2182 "FDISC\n", ha->instance); 2183 port_info->pi_error = FC_NPIV_FDISC_FAILED; 2184 return (NULL); 2185 } 2186 if (bind_info->port_num > (CFG_IST(ha, CFG_CTRL_2422) ? 2187 MAX_24_VIRTUAL_PORTS : MAX_25_VIRTUAL_PORTS)) { 2188 QL_PRINT_2(CE_CONT, "(%d): port number=%d " 2189 "FC_OUTOFBOUNDS\n", ha->instance); 2190 port_info->pi_error = FC_OUTOFBOUNDS; 2191 return (NULL); 2192 } 2193 } else if (bind_info->port_num != 0) { 2194 QL_PRINT_2(CE_CONT, "(%d): failed, port number=%d is not " 2195 "supported\n", ha->instance, bind_info->port_num); 2196 port_info->pi_error = FC_OUTOFBOUNDS; 2197 return (NULL); 2198 } 2199 2200 /* Locate port context. */ 2201 for (vha = ha; vha != NULL; vha = vha->vp_next) { 2202 if (vha->vp_index == bind_info->port_num) { 2203 break; 2204 } 2205 } 2206 2207 /* If virtual port does not exist. */ 2208 if (vha == NULL) { 2209 vha = ql_vport_create(ha, (uint8_t)bind_info->port_num); 2210 } 2211 2212 /* make sure this port isn't already bound */ 2213 if (vha->flags & FCA_BOUND) { 2214 port_info->pi_error = FC_ALREADY; 2215 } else { 2216 if (vha->vp_index != 0) { 2217 bcopy(port_nwwn, 2218 vha->loginparams.node_ww_name.raw_wwn, 8); 2219 bcopy(port_pwwn, 2220 vha->loginparams.nport_ww_name.raw_wwn, 8); 2221 } 2222 if (vha->vp_index != 0 && !(vha->flags & VP_ENABLED)) { 2223 if (ql_vport_enable(vha) != QL_SUCCESS) { 2224 QL_PRINT_2(CE_CONT, "(%d): failed to enable " 2225 "virtual port=%d\n", ha->instance, 2226 vha->vp_index); 2227 port_info->pi_error = FC_NPIV_FDISC_FAILED; 2228 return (NULL); 2229 } 2230 cmn_err(CE_CONT, "!Qlogic %s(%d) NPIV(%d) " 2231 "WWPN=%02x%02x%02x%02x%02x%02x%02x%02x : " 2232 "WWNN=%02x%02x%02x%02x%02x%02x%02x%02x\n", 2233 QL_NAME, ha->instance, vha->vp_index, 2234 port_pwwn[0], port_pwwn[1], port_pwwn[2], 2235 port_pwwn[3], port_pwwn[4], port_pwwn[5], 2236 port_pwwn[6], port_pwwn[7], 2237 port_nwwn[0], port_nwwn[1], port_nwwn[2], 2238 port_nwwn[3], port_nwwn[4], port_nwwn[5], 2239 port_nwwn[6], port_nwwn[7]); 2240 } 2241 2242 /* stash the bind_info supplied by the FC Transport */ 2243 vha->bind_info.port_handle = bind_info->port_handle; 2244 vha->bind_info.port_statec_cb = 2245 bind_info->port_statec_cb; 2246 vha->bind_info.port_unsol_cb = bind_info->port_unsol_cb; 2247 2248 /* Set port's source ID. */ 2249 port_info->pi_s_id.port_id = vha->d_id.b24; 2250 2251 /* copy out the default login parameters */ 2252 bcopy((void *)&vha->loginparams, 2253 (void *)&port_info->pi_login_params, 2254 sizeof (la_els_logi_t)); 2255 2256 /* Set port's hard address if enabled. */ 2257 port_info->pi_hard_addr.hard_addr = 0; 2258 if (bind_info->port_num == 0) { 2259 d_id.b24 = ha->d_id.b24; 2260 if (CFG_IST(ha, CFG_CTRL_242581)) { 2261 if (ha->init_ctrl_blk.cb24. 2262 firmware_options_1[0] & BIT_0) { 2263 d_id.b.al_pa = ql_index_to_alpa[ha-> 2264 init_ctrl_blk.cb24. 2265 hard_address[0]]; 2266 port_info->pi_hard_addr.hard_addr = 2267 d_id.b24; 2268 } 2269 } else if (ha->init_ctrl_blk.cb.firmware_options[0] & 2270 BIT_0) { 2271 d_id.b.al_pa = ql_index_to_alpa[ha-> 2272 init_ctrl_blk.cb.hard_address[0]]; 2273 port_info->pi_hard_addr.hard_addr = d_id.b24; 2274 } 2275 2276 /* Set the node id data */ 2277 if (ql_get_rnid_params(ha, 2278 sizeof (port_info->pi_rnid_params.params), 2279 (caddr_t)&port_info->pi_rnid_params.params) == 2280 QL_SUCCESS) { 2281 port_info->pi_rnid_params.status = FC_SUCCESS; 2282 } else { 2283 port_info->pi_rnid_params.status = FC_FAILURE; 2284 } 2285 2286 /* Populate T11 FC-HBA details */ 2287 ql_populate_hba_fru_details(ha, port_info); 2288 ha->pi_attrs = kmem_zalloc(sizeof (fca_port_attrs_t), 2289 KM_SLEEP); 2290 if (ha->pi_attrs != NULL) { 2291 bcopy(&port_info->pi_attrs, ha->pi_attrs, 2292 sizeof (fca_port_attrs_t)); 2293 } 2294 } else { 2295 port_info->pi_rnid_params.status = FC_FAILURE; 2296 if (ha->pi_attrs != NULL) { 2297 bcopy(ha->pi_attrs, &port_info->pi_attrs, 2298 sizeof (fca_port_attrs_t)); 2299 } 2300 } 2301 2302 /* Generate handle for this FCA. */ 2303 fca_handle = (opaque_t)vha; 2304 2305 ADAPTER_STATE_LOCK(ha); 2306 vha->flags |= FCA_BOUND; 2307 ADAPTER_STATE_UNLOCK(ha); 2308 /* Set port's current state. */ 2309 port_info->pi_port_state = vha->state; 2310 } 2311 2312 QL_PRINT_10(CE_CONT, "(%d,%d): done, pi_port_state=%xh, " 2313 "pi_s_id.port_id=%xh\n", ha->instance, ha->vp_index, 2314 port_info->pi_port_state, port_info->pi_s_id.port_id); 2315 2316 return (fca_handle); 2317 } 2318 2319 /* 2320 * ql_unbind_port 2321 * To unbind a Fibre Channel Adapter from an FC Port driver. 2322 * 2323 * Input: 2324 * fca_handle = handle setup by ql_bind_port(). 2325 * 2326 * Context: 2327 * Kernel context. 2328 */ 2329 static void 2330 ql_unbind_port(opaque_t fca_handle) 2331 { 2332 ql_adapter_state_t *ha; 2333 ql_tgt_t *tq; 2334 uint32_t flgs; 2335 2336 ha = ql_fca_handle_to_state(fca_handle); 2337 if (ha == NULL) { 2338 /*EMPTY*/ 2339 QL_PRINT_2(CE_CONT, "failed, no adapter=%ph\n", 2340 (void *)fca_handle); 2341 } else { 2342 QL_PRINT_10(CE_CONT, "(%d,%d): started\n", ha->instance, 2343 ha->vp_index); 2344 2345 if (!(ha->flags & FCA_BOUND)) { 2346 /*EMPTY*/ 2347 QL_PRINT_2(CE_CONT, "(%d): port=%d already unbound\n", 2348 ha->instance, ha->vp_index); 2349 } else { 2350 if (ha->vp_index != 0 && ha->flags & VP_ENABLED) { 2351 if ((tq = ql_loop_id_to_queue(ha, 2352 FL_PORT_24XX_HDL)) != NULL) { 2353 (void) ql_logout_fabric_port(ha, tq); 2354 } 2355 (void) ql_vport_control(ha, (uint8_t) 2356 (CFG_IST(ha, CFG_CTRL_2425) ? 2357 VPC_DISABLE_INIT : VPC_DISABLE_LOGOUT)); 2358 flgs = FCA_BOUND | VP_ENABLED; 2359 } else { 2360 flgs = FCA_BOUND; 2361 } 2362 ADAPTER_STATE_LOCK(ha); 2363 ha->flags &= ~flgs; 2364 ADAPTER_STATE_UNLOCK(ha); 2365 } 2366 2367 QL_PRINT_10(CE_CONT, "(%d,%d): done\n", ha->instance, 2368 ha->vp_index); 2369 } 2370 } 2371 2372 /* 2373 * ql_init_pkt 2374 * Initialize FCA portion of packet. 2375 * 2376 * Input: 2377 * fca_handle = handle setup by ql_bind_port(). 2378 * pkt = pointer to fc_packet. 2379 * 2380 * Returns: 2381 * FC_SUCCESS - the packet has successfully been initialized. 2382 * FC_UNBOUND - the fca_handle specified is not bound. 2383 * FC_NOMEM - the FCA failed initialization due to an allocation error. 2384 * FC_FAILURE - the FCA failed initialization for undisclosed reasons 2385 * 2386 * Context: 2387 * Kernel context. 2388 */ 2389 /* ARGSUSED */ 2390 static int 2391 ql_init_pkt(opaque_t fca_handle, fc_packet_t *pkt, int sleep) 2392 { 2393 ql_adapter_state_t *ha; 2394 ql_srb_t *sp; 2395 2396 ha = ql_fca_handle_to_state(fca_handle); 2397 if (ha == NULL) { 2398 QL_PRINT_2(CE_CONT, "failed, no adapter=%ph\n", 2399 (void *)fca_handle); 2400 return (FC_UNBOUND); 2401 } 2402 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance); 2403 2404 ASSERT(ha->power_level == PM_LEVEL_D0); 2405 2406 sp = (ql_srb_t *)pkt->pkt_fca_private; 2407 sp->flags = 0; 2408 2409 /* init cmd links */ 2410 sp->cmd.base_address = sp; 2411 sp->cmd.prev = NULL; 2412 sp->cmd.next = NULL; 2413 sp->cmd.head = NULL; 2414 2415 /* init watchdog links */ 2416 sp->wdg.base_address = sp; 2417 sp->wdg.prev = NULL; 2418 sp->wdg.next = NULL; 2419 sp->wdg.head = NULL; 2420 sp->pkt = pkt; 2421 sp->ha = ha; 2422 sp->magic_number = QL_FCA_BRAND; 2423 2424 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance); 2425 2426 return (FC_SUCCESS); 2427 } 2428 2429 /* 2430 * ql_un_init_pkt 2431 * Release all local resources bound to packet. 2432 * 2433 * Input: 2434 * fca_handle = handle setup by ql_bind_port(). 2435 * pkt = pointer to fc_packet. 2436 * 2437 * Returns: 2438 * FC_SUCCESS - the packet has successfully been invalidated. 2439 * FC_UNBOUND - the fca_handle specified is not bound. 2440 * FC_BADPACKET - the packet has not been initialized or has 2441 * already been freed by this FCA. 2442 * 2443 * Context: 2444 * Kernel context. 2445 */ 2446 static int 2447 ql_un_init_pkt(opaque_t fca_handle, fc_packet_t *pkt) 2448 { 2449 ql_adapter_state_t *ha; 2450 int rval; 2451 ql_srb_t *sp; 2452 2453 ha = ql_fca_handle_to_state(fca_handle); 2454 if (ha == NULL) { 2455 QL_PRINT_2(CE_CONT, "failed, no adapter=%ph\n", 2456 (void *)fca_handle); 2457 return (FC_UNBOUND); 2458 } 2459 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance); 2460 2461 sp = (ql_srb_t *)pkt->pkt_fca_private; 2462 ASSERT(sp->magic_number == QL_FCA_BRAND); 2463 2464 if (sp->magic_number != QL_FCA_BRAND) { 2465 EL(ha, "failed, FC_BADPACKET\n"); 2466 rval = FC_BADPACKET; 2467 } else { 2468 sp->magic_number = NULL; 2469 2470 ASSERT((sp->flags & (SRB_IN_DEVICE_QUEUE | 2471 SRB_IN_TOKEN_ARRAY)) == 0); 2472 2473 rval = FC_SUCCESS; 2474 } 2475 2476 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance); 2477 2478 return (rval); 2479 } 2480 2481 /* 2482 * ql_els_send 2483 * Issue a extended link service request. 2484 * 2485 * Input: 2486 * fca_handle = handle setup by ql_bind_port(). 2487 * pkt = pointer to fc_packet. 2488 * 2489 * Returns: 2490 * FC_SUCCESS - the command was successful. 2491 * FC_ELS_FREJECT - the command was rejected by a Fabric. 2492 * FC_ELS_PREJECT - the command was rejected by an N-port. 2493 * FC_TRANSPORT_ERROR - a transport error occurred. 2494 * FC_UNBOUND - the fca_handle specified is not bound. 2495 * FC_ELS_BAD - the FCA can not issue the requested ELS. 2496 * 2497 * Context: 2498 * Kernel context. 2499 */ 2500 static int 2501 ql_els_send(opaque_t fca_handle, fc_packet_t *pkt) 2502 { 2503 ql_adapter_state_t *ha; 2504 int rval; 2505 clock_t timer; 2506 ls_code_t els; 2507 la_els_rjt_t rjt; 2508 ql_srb_t *sp = (ql_srb_t *)pkt->pkt_fca_private; 2509 2510 /* Verify proper command. */ 2511 ha = ql_cmd_setup(fca_handle, pkt, &rval); 2512 if (ha == NULL) { 2513 QL_PRINT_2(CE_CONT, "failed, ql_cmd_setup=%xh, fcah=%ph\n", 2514 rval, fca_handle); 2515 return (FC_INVALID_REQUEST); 2516 } 2517 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance); 2518 2519 ASSERT(ha->power_level == PM_LEVEL_D0); 2520 2521 /* Wait for suspension to end. */ 2522 TASK_DAEMON_LOCK(ha); 2523 while (ha->task_daemon_flags & QL_SUSPENDED) { 2524 ha->task_daemon_flags |= SUSPENDED_WAKEUP_FLG; 2525 2526 /* 30 seconds from now */ 2527 timer = ddi_get_lbolt(); 2528 timer += drv_usectohz(30000000); 2529 2530 if (cv_timedwait(&ha->pha->cv_dr_suspended, 2531 &ha->pha->task_daemon_mutex, timer) == -1) { 2532 /* 2533 * The timeout time 'timer' was 2534 * reached without the condition 2535 * being signaled. 2536 */ 2537 pkt->pkt_state = FC_PKT_TRAN_BSY; 2538 pkt->pkt_reason = FC_REASON_XCHG_BSY; 2539 2540 /* Release task daemon lock. */ 2541 TASK_DAEMON_UNLOCK(ha); 2542 2543 EL(ha, "QL_SUSPENDED failed=%xh\n", 2544 QL_FUNCTION_TIMEOUT); 2545 return (FC_TRAN_BUSY); 2546 } 2547 } 2548 /* Release task daemon lock. */ 2549 TASK_DAEMON_UNLOCK(ha); 2550 2551 /* Setup response header. */ 2552 bcopy((void *)&pkt->pkt_cmd_fhdr, (void *)&pkt->pkt_resp_fhdr, 2553 sizeof (fc_frame_hdr_t)); 2554 2555 if (pkt->pkt_rsplen) { 2556 bzero((void *)pkt->pkt_resp, pkt->pkt_rsplen); 2557 } 2558 2559 pkt->pkt_resp_fhdr.d_id = ha->d_id.b24; 2560 pkt->pkt_resp_fhdr.s_id = pkt->pkt_cmd_fhdr.d_id; 2561 pkt->pkt_resp_fhdr.r_ctl = R_CTL_EXTENDED_SVC | 2562 R_CTL_SOLICITED_CONTROL; 2563 pkt->pkt_resp_fhdr.f_ctl = F_CTL_XCHG_CONTEXT | F_CTL_LAST_SEQ | 2564 F_CTL_END_SEQ; 2565 2566 sp->flags &= ~(SRB_UB_CALLBACK | SRB_UB_RSCN | SRB_UB_FCP | 2567 SRB_FCP_CMD_PKT | SRB_FCP_DATA_PKT | SRB_FCP_RSP_PKT | 2568 SRB_IP_PKT | SRB_COMMAND_TIMEOUT | SRB_UB_ACQUIRED | SRB_MS_PKT); 2569 2570 sp->flags |= SRB_ELS_PKT; 2571 2572 /* map the type of ELS to a function */ 2573 ddi_rep_get8(pkt->pkt_cmd_acc, (uint8_t *)&els, 2574 (uint8_t *)pkt->pkt_cmd, sizeof (els), DDI_DEV_AUTOINCR); 2575 2576 #if 0 2577 QL_PRINT_3(CE_CONT, "(%d): command fhdr:\n", ha->instance); 2578 QL_DUMP_3((uint8_t *)&pkt->pkt_cmd_fhdr, 32, 2579 sizeof (fc_frame_hdr_t) / 4); 2580 QL_PRINT_3(CE_CONT, "(%d): command:\n", ha->instance); 2581 QL_DUMP_3((uint8_t *)&els, 32, sizeof (els) / 4); 2582 #endif 2583 2584 sp->iocb = ha->els_cmd; 2585 sp->req_cnt = 1; 2586 2587 switch (els.ls_code) { 2588 case LA_ELS_RJT: 2589 case LA_ELS_ACC: 2590 EL(ha, "LA_ELS_RJT\n"); 2591 pkt->pkt_state = FC_PKT_SUCCESS; 2592 rval = FC_SUCCESS; 2593 break; 2594 case LA_ELS_PLOGI: 2595 case LA_ELS_PDISC: 2596 rval = ql_els_plogi(ha, pkt); 2597 break; 2598 case LA_ELS_FLOGI: 2599 case LA_ELS_FDISC: 2600 rval = ql_els_flogi(ha, pkt); 2601 break; 2602 case LA_ELS_LOGO: 2603 rval = ql_els_logo(ha, pkt); 2604 break; 2605 case LA_ELS_PRLI: 2606 rval = ql_els_prli(ha, pkt); 2607 break; 2608 case LA_ELS_PRLO: 2609 rval = ql_els_prlo(ha, pkt); 2610 break; 2611 case LA_ELS_ADISC: 2612 rval = ql_els_adisc(ha, pkt); 2613 break; 2614 case LA_ELS_LINIT: 2615 rval = ql_els_linit(ha, pkt); 2616 break; 2617 case LA_ELS_LPC: 2618 rval = ql_els_lpc(ha, pkt); 2619 break; 2620 case LA_ELS_LSTS: 2621 rval = ql_els_lsts(ha, pkt); 2622 break; 2623 case LA_ELS_SCR: 2624 rval = ql_els_scr(ha, pkt); 2625 break; 2626 case LA_ELS_RSCN: 2627 rval = ql_els_rscn(ha, pkt); 2628 break; 2629 case LA_ELS_FARP_REQ: 2630 rval = ql_els_farp_req(ha, pkt); 2631 break; 2632 case LA_ELS_FARP_REPLY: 2633 rval = ql_els_farp_reply(ha, pkt); 2634 break; 2635 case LA_ELS_RLS: 2636 rval = ql_els_rls(ha, pkt); 2637 break; 2638 case LA_ELS_RNID: 2639 rval = ql_els_rnid(ha, pkt); 2640 break; 2641 default: 2642 EL(ha, "LA_ELS_RJT, FC_REASON_CMD_UNSUPPORTED=%xh\n", 2643 els.ls_code); 2644 /* Build RJT. */ 2645 bzero(&rjt, sizeof (rjt)); 2646 rjt.ls_code.ls_code = LA_ELS_RJT; 2647 rjt.reason = FC_REASON_CMD_UNSUPPORTED; 2648 2649 ddi_rep_put8(pkt->pkt_resp_acc, (uint8_t *)&rjt, 2650 (uint8_t *)pkt->pkt_resp, sizeof (rjt), DDI_DEV_AUTOINCR); 2651 2652 pkt->pkt_state = FC_PKT_LOCAL_RJT; 2653 pkt->pkt_reason = FC_REASON_UNSUPPORTED; 2654 rval = FC_SUCCESS; 2655 break; 2656 } 2657 2658 #if 0 2659 QL_PRINT_3(CE_CONT, "(%d): response fhdr:\n", ha->instance); 2660 QL_DUMP_3((uint8_t *)&pkt->pkt_resp_fhdr, 32, 2661 sizeof (fc_frame_hdr_t) / 4); 2662 #endif 2663 /* 2664 * Return success if the srb was consumed by an iocb. The packet 2665 * completion callback will be invoked by the response handler. 2666 */ 2667 if (rval == QL_CONSUMED) { 2668 rval = FC_SUCCESS; 2669 } else if (rval == FC_SUCCESS && 2670 !(pkt->pkt_tran_flags & FC_TRAN_NO_INTR) && pkt->pkt_comp) { 2671 /* Do command callback only if no error */ 2672 ql_awaken_task_daemon(ha, sp, 0, 0); 2673 } 2674 2675 if (rval != FC_SUCCESS) { 2676 EL(ha, "failed, rval = %xh\n", rval); 2677 } else { 2678 /*EMPTY*/ 2679 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance); 2680 } 2681 return (rval); 2682 } 2683 2684 /* 2685 * ql_get_cap 2686 * Export FCA hardware and software capabilities. 2687 * 2688 * Input: 2689 * fca_handle = handle setup by ql_bind_port(). 2690 * cap = pointer to the capabilities string. 2691 * ptr = buffer pointer for return capability. 2692 * 2693 * Returns: 2694 * FC_CAP_ERROR - no such capability 2695 * FC_CAP_FOUND - the capability was returned and cannot be set 2696 * FC_CAP_SETTABLE - the capability was returned and can be set 2697 * FC_UNBOUND - the fca_handle specified is not bound. 2698 * 2699 * Context: 2700 * Kernel context. 2701 */ 2702 static int 2703 ql_get_cap(opaque_t fca_handle, char *cap, void *ptr) 2704 { 2705 ql_adapter_state_t *ha; 2706 int rval; 2707 uint32_t *rptr = (uint32_t *)ptr; 2708 2709 ha = ql_fca_handle_to_state(fca_handle); 2710 if (ha == NULL) { 2711 QL_PRINT_2(CE_CONT, "failed, no adapter=%ph\n", 2712 (void *)fca_handle); 2713 return (FC_UNBOUND); 2714 } 2715 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance); 2716 2717 if (strcmp(cap, FC_NODE_WWN) == 0) { 2718 bcopy((void *)&ha->loginparams.node_ww_name.raw_wwn[0], 2719 ptr, 8); 2720 rval = FC_CAP_FOUND; 2721 } else if (strcmp(cap, FC_LOGIN_PARAMS) == 0) { 2722 bcopy((void *)&ha->loginparams, ptr, 2723 sizeof (la_els_logi_t)); 2724 rval = FC_CAP_FOUND; 2725 } else if (strcmp(cap, FC_CAP_UNSOL_BUF) == 0) { 2726 *rptr = (uint32_t)QL_UB_LIMIT; 2727 rval = FC_CAP_FOUND; 2728 } else if (strcmp(cap, FC_CAP_NOSTREAM_ON_UNALIGN_BUF) == 0) { 2729 2730 dev_info_t *psydip = NULL; 2731 #ifdef __sparc 2732 /* 2733 * Disable streaming for certain 2 chip adapters 2734 * below Psycho to handle Psycho byte hole issue. 2735 */ 2736 if ((CFG_IST(ha, CFG_MULTI_CHIP_ADAPTER)) && 2737 (!CFG_IST(ha, CFG_SBUS_CARD))) { 2738 for (psydip = ddi_get_parent(ha->dip); psydip; 2739 psydip = ddi_get_parent(psydip)) { 2740 if (strcmp(ddi_driver_name(psydip), 2741 "pcipsy") == 0) { 2742 break; 2743 } 2744 } 2745 } 2746 #endif /* __sparc */ 2747 2748 if (psydip) { 2749 *rptr = (uint32_t)FC_NO_STREAMING; 2750 EL(ha, "No Streaming\n"); 2751 } else { 2752 *rptr = (uint32_t)FC_ALLOW_STREAMING; 2753 EL(ha, "Allow Streaming\n"); 2754 } 2755 rval = FC_CAP_FOUND; 2756 } else if (strcmp(cap, FC_CAP_PAYLOAD_SIZE) == 0) { 2757 if (CFG_IST(ha, CFG_CTRL_242581)) { 2758 *rptr = (uint32_t)CHAR_TO_SHORT( 2759 ha->init_ctrl_blk.cb24.max_frame_length[0], 2760 ha->init_ctrl_blk.cb24.max_frame_length[1]); 2761 } else { 2762 *rptr = (uint32_t)CHAR_TO_SHORT( 2763 ha->init_ctrl_blk.cb.max_frame_length[0], 2764 ha->init_ctrl_blk.cb.max_frame_length[1]); 2765 } 2766 rval = FC_CAP_FOUND; 2767 } else if (strcmp(cap, FC_CAP_POST_RESET_BEHAVIOR) == 0) { 2768 *rptr = FC_RESET_RETURN_ALL; 2769 rval = FC_CAP_FOUND; 2770 } else if (strcmp(cap, FC_CAP_FCP_DMA) == 0) { 2771 *rptr = FC_NO_DVMA_SPACE; 2772 rval = FC_CAP_FOUND; 2773 } else { 2774 EL(ha, "unknown=%s, FC_CAP_ERROR\n", cap); 2775 rval = FC_CAP_ERROR; 2776 } 2777 2778 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance); 2779 2780 return (rval); 2781 } 2782 2783 /* 2784 * ql_set_cap 2785 * Allow the FC Transport to set FCA capabilities if possible. 2786 * 2787 * Input: 2788 * fca_handle = handle setup by ql_bind_port(). 2789 * cap = pointer to the capabilities string. 2790 * ptr = buffer pointer for capability. 2791 * 2792 * Returns: 2793 * FC_CAP_ERROR - no such capability 2794 * FC_CAP_FOUND - the capability cannot be set by the FC Transport. 2795 * FC_CAP_SETTABLE - the capability was successfully set. 2796 * FC_UNBOUND - the fca_handle specified is not bound. 2797 * 2798 * Context: 2799 * Kernel context. 2800 */ 2801 /* ARGSUSED */ 2802 static int 2803 ql_set_cap(opaque_t fca_handle, char *cap, void *ptr) 2804 { 2805 ql_adapter_state_t *ha; 2806 int rval; 2807 2808 ha = ql_fca_handle_to_state(fca_handle); 2809 if (ha == NULL) { 2810 QL_PRINT_2(CE_CONT, "failed, no adapter=%ph\n", 2811 (void *)fca_handle); 2812 return (FC_UNBOUND); 2813 } 2814 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance); 2815 2816 if (strcmp(cap, FC_NODE_WWN) == 0) { 2817 rval = FC_CAP_FOUND; 2818 } else if (strcmp(cap, FC_LOGIN_PARAMS) == 0) { 2819 rval = FC_CAP_FOUND; 2820 } else if (strcmp(cap, FC_CAP_UNSOL_BUF) == 0) { 2821 rval = FC_CAP_FOUND; 2822 } else if (strcmp(cap, FC_CAP_PAYLOAD_SIZE) == 0) { 2823 rval = FC_CAP_FOUND; 2824 } else if (strcmp(cap, FC_CAP_POST_RESET_BEHAVIOR) == 0) { 2825 rval = FC_CAP_FOUND; 2826 } else { 2827 EL(ha, "unknown=%s, FC_CAP_ERROR\n", cap); 2828 rval = FC_CAP_ERROR; 2829 } 2830 2831 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance); 2832 2833 return (rval); 2834 } 2835 2836 /* 2837 * ql_getmap 2838 * Request of Arbitrated Loop (AL-PA) map. 2839 * 2840 * Input: 2841 * fca_handle = handle setup by ql_bind_port(). 2842 * mapbuf= buffer pointer for map. 2843 * 2844 * Returns: 2845 * FC_OLDPORT - the specified port is not operating in loop mode. 2846 * FC_OFFLINE - the specified port is not online. 2847 * FC_NOMAP - there is no loop map available for this port. 2848 * FC_UNBOUND - the fca_handle specified is not bound. 2849 * FC_SUCCESS - a valid map has been placed in mapbuf. 2850 * 2851 * Context: 2852 * Kernel context. 2853 */ 2854 static int 2855 ql_getmap(opaque_t fca_handle, fc_lilpmap_t *mapbuf) 2856 { 2857 ql_adapter_state_t *ha; 2858 clock_t timer; 2859 int rval = FC_SUCCESS; 2860 2861 ha = ql_fca_handle_to_state(fca_handle); 2862 if (ha == NULL) { 2863 QL_PRINT_2(CE_CONT, "failed, no adapter=%ph\n", 2864 (void *)fca_handle); 2865 return (FC_UNBOUND); 2866 } 2867 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance); 2868 2869 ASSERT(ha->power_level == PM_LEVEL_D0); 2870 2871 mapbuf->lilp_magic = (uint16_t)MAGIC_LIRP; 2872 mapbuf->lilp_myalpa = ha->d_id.b.al_pa; 2873 2874 /* Wait for suspension to end. */ 2875 TASK_DAEMON_LOCK(ha); 2876 while (ha->task_daemon_flags & QL_SUSPENDED) { 2877 ha->task_daemon_flags |= SUSPENDED_WAKEUP_FLG; 2878 2879 /* 30 seconds from now */ 2880 timer = ddi_get_lbolt(); 2881 timer += drv_usectohz(30000000); 2882 2883 if (cv_timedwait(&ha->pha->cv_dr_suspended, 2884 &ha->pha->task_daemon_mutex, timer) == -1) { 2885 /* 2886 * The timeout time 'timer' was 2887 * reached without the condition 2888 * being signaled. 2889 */ 2890 2891 /* Release task daemon lock. */ 2892 TASK_DAEMON_UNLOCK(ha); 2893 2894 EL(ha, "QL_SUSPENDED failed, FC_TRAN_BUSY\n"); 2895 return (FC_TRAN_BUSY); 2896 } 2897 } 2898 /* Release task daemon lock. */ 2899 TASK_DAEMON_UNLOCK(ha); 2900 2901 if (ql_get_loop_position_map(ha, LOOP_POSITION_MAP_SIZE, 2902 (caddr_t)&mapbuf->lilp_length) != QL_SUCCESS) { 2903 /* 2904 * Now, since transport drivers cosider this as an 2905 * offline condition, let's wait for few seconds 2906 * for any loop transitions before we reset the. 2907 * chip and restart all over again. 2908 */ 2909 ql_delay(ha, 2000000); 2910 EL(ha, "failed, FC_NOMAP\n"); 2911 rval = FC_NOMAP; 2912 } else { 2913 /*EMPTY*/ 2914 QL_PRINT_3(CE_CONT, "(%d): my_alpa %xh len %xh " 2915 "data %xh %xh %xh %xh\n", ha->instance, 2916 mapbuf->lilp_myalpa, mapbuf->lilp_length, 2917 mapbuf->lilp_alpalist[0], mapbuf->lilp_alpalist[1], 2918 mapbuf->lilp_alpalist[2], mapbuf->lilp_alpalist[3]); 2919 } 2920 2921 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance); 2922 #if 0 2923 QL_DUMP_3((uint8_t *)mapbuf, 8, sizeof (fc_lilpmap_t)); 2924 #endif 2925 return (rval); 2926 } 2927 2928 /* 2929 * ql_transport 2930 * Issue an I/O request. Handles all regular requests. 2931 * 2932 * Input: 2933 * fca_handle = handle setup by ql_bind_port(). 2934 * pkt = pointer to fc_packet. 2935 * 2936 * Returns: 2937 * FC_SUCCESS - the packet was accepted for transport. 2938 * FC_TRANSPORT_ERROR - a transport error occurred. 2939 * FC_BADPACKET - the packet to be transported had not been 2940 * initialized by this FCA. 2941 * FC_UNBOUND - the fca_handle specified is not bound. 2942 * 2943 * Context: 2944 * Kernel context. 2945 */ 2946 static int 2947 ql_transport(opaque_t fca_handle, fc_packet_t *pkt) 2948 { 2949 ql_adapter_state_t *ha; 2950 int rval = FC_TRANSPORT_ERROR; 2951 ql_srb_t *sp = (ql_srb_t *)pkt->pkt_fca_private; 2952 2953 /* Verify proper command. */ 2954 ha = ql_cmd_setup(fca_handle, pkt, &rval); 2955 if (ha == NULL) { 2956 QL_PRINT_2(CE_CONT, "failed, ql_cmd_setup=%xh, fcah=%ph\n", 2957 rval, fca_handle); 2958 return (rval); 2959 } 2960 QL_PRINT_3(CE_CONT, "(%d): started command:\n", ha->instance); 2961 #if 0 2962 QL_DUMP_3((uint8_t *)&pkt->pkt_cmd_fhdr, 32, 2963 sizeof (fc_frame_hdr_t) / 4); 2964 QL_PRINT_3(CE_CONT, "(%d): command:\n", ha->instance); 2965 QL_DUMP_3((uint8_t *)pkt->pkt_cmd, 8, pkt->pkt_cmdlen); 2966 #endif 2967 if (ha->flags & ADAPTER_SUSPENDED) { 2968 ASSERT(pkt->pkt_tran_flags & FC_TRAN_DUMPING); 2969 } 2970 2971 ASSERT(ha->power_level == PM_LEVEL_D0); 2972 2973 /* Reset SRB flags. */ 2974 sp->flags &= ~(SRB_ISP_STARTED | SRB_ISP_COMPLETED | SRB_RETRY | 2975 SRB_POLL | SRB_WATCHDOG_ENABLED | SRB_ABORT | SRB_UB_CALLBACK | 2976 SRB_UB_RSCN | SRB_UB_FCP | SRB_FCP_CMD_PKT | SRB_FCP_DATA_PKT | 2977 SRB_FCP_RSP_PKT | SRB_IP_PKT | SRB_GENERIC_SERVICES_PKT | 2978 SRB_COMMAND_TIMEOUT | SRB_ABORTING | SRB_IN_DEVICE_QUEUE | 2979 SRB_IN_TOKEN_ARRAY | SRB_UB_FREE_REQUESTED | SRB_UB_ACQUIRED | 2980 SRB_MS_PKT | SRB_ELS_PKT); 2981 2982 pkt->pkt_resp_fhdr.d_id = ha->d_id.b24; 2983 pkt->pkt_resp_fhdr.r_ctl = R_CTL_STATUS; 2984 pkt->pkt_resp_fhdr.s_id = pkt->pkt_cmd_fhdr.d_id; 2985 pkt->pkt_resp_fhdr.f_ctl = pkt->pkt_cmd_fhdr.f_ctl; 2986 pkt->pkt_resp_fhdr.type = pkt->pkt_cmd_fhdr.type; 2987 2988 switch (pkt->pkt_cmd_fhdr.r_ctl) { 2989 case R_CTL_COMMAND: 2990 if (pkt->pkt_cmd_fhdr.type == FC_TYPE_SCSI_FCP) { 2991 sp->flags |= SRB_FCP_CMD_PKT; 2992 rval = ql_fcp_scsi_cmd(ha, pkt, sp); 2993 } 2994 break; 2995 2996 default: 2997 /* Setup response header and buffer. */ 2998 if (pkt->pkt_rsplen) { 2999 bzero((void *)pkt->pkt_resp, pkt->pkt_rsplen); 3000 } 3001 3002 switch (pkt->pkt_cmd_fhdr.r_ctl) { 3003 case R_CTL_UNSOL_DATA: 3004 if (pkt->pkt_cmd_fhdr.type == FC_TYPE_IS8802_SNAP) { 3005 sp->flags |= SRB_IP_PKT; 3006 rval = ql_fcp_ip_cmd(ha, pkt, sp); 3007 } 3008 break; 3009 3010 case R_CTL_UNSOL_CONTROL: 3011 if (pkt->pkt_cmd_fhdr.type == FC_TYPE_FC_SERVICES) { 3012 sp->flags |= SRB_GENERIC_SERVICES_PKT; 3013 rval = ql_fc_services(ha, pkt); 3014 } 3015 break; 3016 3017 case R_CTL_SOLICITED_DATA: 3018 case R_CTL_STATUS: 3019 default: 3020 pkt->pkt_state = FC_PKT_LOCAL_RJT; 3021 pkt->pkt_reason = FC_REASON_UNSUPPORTED; 3022 rval = FC_TRANSPORT_ERROR; 3023 EL(ha, "unknown, r_ctl=%xh\n", 3024 pkt->pkt_cmd_fhdr.r_ctl); 3025 break; 3026 } 3027 } 3028 3029 if (rval != FC_SUCCESS) { 3030 EL(ha, "failed, rval = %xh\n", rval); 3031 } else { 3032 /*EMPTY*/ 3033 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance); 3034 } 3035 3036 return (rval); 3037 } 3038 3039 /* 3040 * ql_ub_alloc 3041 * Allocate buffers for unsolicited exchanges. 3042 * 3043 * Input: 3044 * fca_handle = handle setup by ql_bind_port(). 3045 * tokens = token array for each buffer. 3046 * size = size of each buffer. 3047 * count = pointer to number of buffers. 3048 * type = the FC-4 type the buffers are reserved for. 3049 * 1 = Extended Link Services, 5 = LLC/SNAP 3050 * 3051 * Returns: 3052 * FC_FAILURE - buffers could not be allocated. 3053 * FC_TOOMANY - the FCA could not allocate the requested 3054 * number of buffers. 3055 * FC_SUCCESS - unsolicited buffers were allocated. 3056 * FC_UNBOUND - the fca_handle specified is not bound. 3057 * 3058 * Context: 3059 * Kernel context. 3060 */ 3061 static int 3062 ql_ub_alloc(opaque_t fca_handle, uint64_t tokens[], uint32_t size, 3063 uint32_t *count, uint32_t type) 3064 { 3065 ql_adapter_state_t *ha; 3066 caddr_t bufp = NULL; 3067 fc_unsol_buf_t *ubp; 3068 ql_srb_t *sp; 3069 uint32_t index; 3070 uint32_t cnt; 3071 uint32_t ub_array_index = 0; 3072 int rval = FC_SUCCESS; 3073 int ub_updated = FALSE; 3074 3075 /* Check handle. */ 3076 ha = ql_fca_handle_to_state(fca_handle); 3077 if (ha == NULL) { 3078 QL_PRINT_2(CE_CONT, "failed, no adapter=%ph\n", 3079 (void *)fca_handle); 3080 return (FC_UNBOUND); 3081 } 3082 QL_PRINT_3(CE_CONT, "(%d,%d): started, count = %xh\n", 3083 ha->instance, ha->vp_index, *count); 3084 3085 QL_PM_LOCK(ha); 3086 if (ha->power_level != PM_LEVEL_D0) { 3087 QL_PM_UNLOCK(ha); 3088 QL_PRINT_3(CE_CONT, "(%d,%d): down done\n", ha->instance, 3089 ha->vp_index); 3090 return (FC_FAILURE); 3091 } 3092 QL_PM_UNLOCK(ha); 3093 3094 /* Acquire adapter state lock. */ 3095 ADAPTER_STATE_LOCK(ha); 3096 3097 /* Check the count. */ 3098 if ((*count + ha->ub_allocated) > QL_UB_LIMIT) { 3099 *count = 0; 3100 EL(ha, "failed, FC_TOOMANY\n"); 3101 rval = FC_TOOMANY; 3102 } 3103 3104 /* 3105 * reset ub_array_index 3106 */ 3107 ub_array_index = 0; 3108 3109 /* 3110 * Now proceed to allocate any buffers required 3111 */ 3112 for (index = 0; index < *count && rval == FC_SUCCESS; index++) { 3113 /* Allocate all memory needed. */ 3114 ubp = (fc_unsol_buf_t *)kmem_zalloc(sizeof (fc_unsol_buf_t), 3115 KM_SLEEP); 3116 if (ubp == NULL) { 3117 EL(ha, "failed, FC_FAILURE\n"); 3118 rval = FC_FAILURE; 3119 } else { 3120 sp = kmem_zalloc(sizeof (ql_srb_t), KM_SLEEP); 3121 if (sp == NULL) { 3122 kmem_free(ubp, sizeof (fc_unsol_buf_t)); 3123 rval = FC_FAILURE; 3124 } else { 3125 if (type == FC_TYPE_IS8802_SNAP) { 3126 #ifdef __sparc 3127 if (ql_get_dma_mem(ha, 3128 &sp->ub_buffer, size, 3129 BIG_ENDIAN_DMA, 3130 QL_DMA_DATA_ALIGN) != QL_SUCCESS) { 3131 rval = FC_FAILURE; 3132 kmem_free(ubp, 3133 sizeof (fc_unsol_buf_t)); 3134 kmem_free(sp, 3135 sizeof (ql_srb_t)); 3136 } else { 3137 bufp = sp->ub_buffer.bp; 3138 sp->ub_size = size; 3139 } 3140 #else 3141 if (ql_get_dma_mem(ha, 3142 &sp->ub_buffer, size, 3143 LITTLE_ENDIAN_DMA, 3144 QL_DMA_DATA_ALIGN) != QL_SUCCESS) { 3145 rval = FC_FAILURE; 3146 kmem_free(ubp, 3147 sizeof (fc_unsol_buf_t)); 3148 kmem_free(sp, 3149 sizeof (ql_srb_t)); 3150 } else { 3151 bufp = sp->ub_buffer.bp; 3152 sp->ub_size = size; 3153 } 3154 #endif 3155 } else { 3156 bufp = kmem_zalloc(size, KM_SLEEP); 3157 if (bufp == NULL) { 3158 rval = FC_FAILURE; 3159 kmem_free(ubp, 3160 sizeof (fc_unsol_buf_t)); 3161 kmem_free(sp, 3162 sizeof (ql_srb_t)); 3163 } else { 3164 sp->ub_size = size; 3165 } 3166 } 3167 } 3168 } 3169 3170 if (rval == FC_SUCCESS) { 3171 /* Find next available slot. */ 3172 QL_UB_LOCK(ha); 3173 while (ha->ub_array[ub_array_index] != NULL) { 3174 ub_array_index++; 3175 } 3176 3177 ubp->ub_fca_private = (void *)sp; 3178 3179 /* init cmd links */ 3180 sp->cmd.base_address = sp; 3181 sp->cmd.prev = NULL; 3182 sp->cmd.next = NULL; 3183 sp->cmd.head = NULL; 3184 3185 /* init wdg links */ 3186 sp->wdg.base_address = sp; 3187 sp->wdg.prev = NULL; 3188 sp->wdg.next = NULL; 3189 sp->wdg.head = NULL; 3190 sp->ha = ha; 3191 3192 ubp->ub_buffer = bufp; 3193 ubp->ub_bufsize = size; 3194 ubp->ub_port_handle = fca_handle; 3195 ubp->ub_token = ub_array_index; 3196 3197 /* Save the token. */ 3198 tokens[index] = ub_array_index; 3199 3200 /* Setup FCA private information. */ 3201 sp->ub_type = type; 3202 sp->handle = ub_array_index; 3203 sp->flags |= SRB_UB_IN_FCA; 3204 3205 ha->ub_array[ub_array_index] = ubp; 3206 ha->ub_allocated++; 3207 ub_updated = TRUE; 3208 QL_UB_UNLOCK(ha); 3209 } 3210 } 3211 3212 /* Release adapter state lock. */ 3213 ADAPTER_STATE_UNLOCK(ha); 3214 3215 /* IP buffer. */ 3216 if (ub_updated) { 3217 if ((type == FC_TYPE_IS8802_SNAP) && 3218 (!(CFG_IST(ha, (CFG_CTRL_6322 | CFG_CTRL_2581))))) { 3219 3220 ADAPTER_STATE_LOCK(ha); 3221 ha->flags |= IP_ENABLED; 3222 ADAPTER_STATE_UNLOCK(ha); 3223 3224 if (!(ha->flags & IP_INITIALIZED)) { 3225 if (CFG_IST(ha, CFG_CTRL_2422)) { 3226 ha->ip_init_ctrl_blk.cb24.mtu_size[0] = 3227 LSB(ql_ip_mtu); 3228 ha->ip_init_ctrl_blk.cb24.mtu_size[1] = 3229 MSB(ql_ip_mtu); 3230 ha->ip_init_ctrl_blk.cb24.buf_size[0] = 3231 LSB(size); 3232 ha->ip_init_ctrl_blk.cb24.buf_size[1] = 3233 MSB(size); 3234 3235 cnt = CHAR_TO_SHORT( 3236 ha->ip_init_ctrl_blk.cb24.cc[0], 3237 ha->ip_init_ctrl_blk.cb24.cc[1]); 3238 3239 if (cnt < *count) { 3240 ha->ip_init_ctrl_blk.cb24.cc[0] 3241 = LSB(*count); 3242 ha->ip_init_ctrl_blk.cb24.cc[1] 3243 = MSB(*count); 3244 } 3245 } else { 3246 ha->ip_init_ctrl_blk.cb.mtu_size[0] = 3247 LSB(ql_ip_mtu); 3248 ha->ip_init_ctrl_blk.cb.mtu_size[1] = 3249 MSB(ql_ip_mtu); 3250 ha->ip_init_ctrl_blk.cb.buf_size[0] = 3251 LSB(size); 3252 ha->ip_init_ctrl_blk.cb.buf_size[1] = 3253 MSB(size); 3254 3255 cnt = CHAR_TO_SHORT( 3256 ha->ip_init_ctrl_blk.cb.cc[0], 3257 ha->ip_init_ctrl_blk.cb.cc[1]); 3258 3259 if (cnt < *count) { 3260 ha->ip_init_ctrl_blk.cb.cc[0] = 3261 LSB(*count); 3262 ha->ip_init_ctrl_blk.cb.cc[1] = 3263 MSB(*count); 3264 } 3265 } 3266 3267 (void) ql_initialize_ip(ha); 3268 } 3269 ql_isp_rcvbuf(ha); 3270 } 3271 } 3272 3273 if (rval != FC_SUCCESS) { 3274 EL(ha, "failed=%xh\n", rval); 3275 } else { 3276 /*EMPTY*/ 3277 QL_PRINT_3(CE_CONT, "(%d,%d): done\n", ha->instance, 3278 ha->vp_index); 3279 } 3280 return (rval); 3281 } 3282 3283 /* 3284 * ql_ub_free 3285 * Free unsolicited buffers. 3286 * 3287 * Input: 3288 * fca_handle = handle setup by ql_bind_port(). 3289 * count = number of buffers. 3290 * tokens = token array for each buffer. 3291 * 3292 * Returns: 3293 * FC_SUCCESS - the requested buffers have been freed. 3294 * FC_UNBOUND - the fca_handle specified is not bound. 3295 * FC_UB_BADTOKEN - an invalid token was encountered. 3296 * No buffers have been released. 3297 * 3298 * Context: 3299 * Kernel context. 3300 */ 3301 static int 3302 ql_ub_free(opaque_t fca_handle, uint32_t count, uint64_t tokens[]) 3303 { 3304 ql_adapter_state_t *ha; 3305 ql_srb_t *sp; 3306 uint32_t index; 3307 uint64_t ub_array_index; 3308 int rval = FC_SUCCESS; 3309 3310 /* Check handle. */ 3311 ha = ql_fca_handle_to_state(fca_handle); 3312 if (ha == NULL) { 3313 QL_PRINT_2(CE_CONT, "failed, no adapter=%ph\n", 3314 (void *)fca_handle); 3315 return (FC_UNBOUND); 3316 } 3317 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance); 3318 3319 /* Acquire adapter state lock. */ 3320 ADAPTER_STATE_LOCK(ha); 3321 3322 /* Check all returned tokens. */ 3323 for (index = 0; index < count; index++) { 3324 fc_unsol_buf_t *ubp; 3325 3326 /* Check the token range. */ 3327 if ((ub_array_index = tokens[index]) >= QL_UB_LIMIT) { 3328 EL(ha, "failed, FC_UB_BADTOKEN\n"); 3329 rval = FC_UB_BADTOKEN; 3330 break; 3331 } 3332 3333 /* Check the unsolicited buffer array. */ 3334 QL_UB_LOCK(ha); 3335 ubp = ha->ub_array[ub_array_index]; 3336 3337 if (ubp == NULL) { 3338 EL(ha, "failed, FC_UB_BADTOKEN-2\n"); 3339 rval = FC_UB_BADTOKEN; 3340 QL_UB_UNLOCK(ha); 3341 break; 3342 } 3343 3344 /* Check the state of the unsolicited buffer. */ 3345 sp = ha->ub_array[ub_array_index]->ub_fca_private; 3346 sp->flags |= SRB_UB_FREE_REQUESTED; 3347 3348 while (!(sp->flags & SRB_UB_IN_FCA) || 3349 (sp->flags & (SRB_UB_CALLBACK | SRB_UB_ACQUIRED))) { 3350 QL_UB_UNLOCK(ha); 3351 ADAPTER_STATE_UNLOCK(ha); 3352 delay(drv_usectohz(100000)); 3353 ADAPTER_STATE_LOCK(ha); 3354 QL_UB_LOCK(ha); 3355 } 3356 ha->ub_array[ub_array_index] = NULL; 3357 QL_UB_UNLOCK(ha); 3358 ql_free_unsolicited_buffer(ha, ubp); 3359 } 3360 3361 if (rval == FC_SUCCESS) { 3362 /* 3363 * Signal any pending hardware reset when there are 3364 * no more unsolicited buffers in use. 3365 */ 3366 if (ha->ub_allocated == 0) { 3367 cv_broadcast(&ha->pha->cv_ub); 3368 } 3369 } 3370 3371 /* Release adapter state lock. */ 3372 ADAPTER_STATE_UNLOCK(ha); 3373 3374 if (rval !=