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