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