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