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