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