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