ql_api.c revision 10736:d831c82c5d2c
1/* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 22/* Copyright 2009 QLogic Corporation */ 23 24/* 25 * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 26 * Use is subject to license terms. 27 */ 28 29#pragma ident "Copyright 2009 QLogic Corporation; ql_api.c" 30 31/* 32 * ISP2xxx Solaris Fibre Channel Adapter (FCA) driver source file. 33 * 34 * *********************************************************************** 35 * * ** 36 * * NOTICE ** 37 * * COPYRIGHT (C) 1996-2009 QLOGIC CORPORATION ** 38 * * ALL RIGHTS RESERVED ** 39 * * ** 40 * *********************************************************************** 41 * 42 */ 43 44#include <ql_apps.h> 45#include <ql_api.h> 46#include <ql_debug.h> 47#include <ql_init.h> 48#include <ql_iocb.h> 49#include <ql_ioctl.h> 50#include <ql_isr.h> 51#include <ql_mbx.h> 52#include <ql_xioctl.h> 53 54/* 55 * Solaris external defines. 56 */ 57extern pri_t minclsyspri; 58extern pri_t maxclsyspri; 59 60/* 61 * dev_ops functions prototypes 62 */ 63static int ql_getinfo(dev_info_t *, ddi_info_cmd_t, void *, void **); 64static int ql_attach(dev_info_t *, ddi_attach_cmd_t); 65static int ql_detach(dev_info_t *, ddi_detach_cmd_t); 66static int ql_power(dev_info_t *, int, int); 67static int ql_quiesce(dev_info_t *); 68 69/* 70 * FCA functions prototypes exported by means of the transport table 71 */ 72static opaque_t ql_bind_port(dev_info_t *, fc_fca_port_info_t *, 73 fc_fca_bind_info_t *); 74static void ql_unbind_port(opaque_t); 75static int ql_init_pkt(opaque_t, fc_packet_t *, int); 76static int ql_un_init_pkt(opaque_t, fc_packet_t *); 77static int ql_els_send(opaque_t, fc_packet_t *); 78static int ql_get_cap(opaque_t, char *, void *); 79static int ql_set_cap(opaque_t, char *, void *); 80static int ql_getmap(opaque_t, fc_lilpmap_t *); 81static int ql_transport(opaque_t, fc_packet_t *); 82static int ql_ub_alloc(opaque_t, uint64_t *, uint32_t, uint32_t *, uint32_t); 83static int ql_ub_free(opaque_t, uint32_t, uint64_t *); 84static int ql_ub_release(opaque_t, uint32_t, uint64_t *); 85static int ql_abort(opaque_t, fc_packet_t *, int); 86static int ql_reset(opaque_t, uint32_t); 87static int ql_port_manage(opaque_t, fc_fca_pm_t *); 88static opaque_t ql_get_device(opaque_t, fc_portid_t); 89 90/* 91 * FCA Driver Support Function Prototypes. 92 */ 93static uint16_t ql_wait_outstanding(ql_adapter_state_t *); 94static void ql_task_mgmt(ql_adapter_state_t *, ql_tgt_t *, fc_packet_t *, 95 ql_srb_t *); 96static void ql_task_daemon(void *); 97static void ql_task_thread(ql_adapter_state_t *); 98static void ql_unsol_callback(ql_srb_t *); 99static void ql_free_unsolicited_buffer(ql_adapter_state_t *, 100 fc_unsol_buf_t *); 101static void ql_timer(void *); 102static void ql_watchdog(ql_adapter_state_t *, uint32_t *, uint32_t *); 103static void ql_cmd_timeout(ql_adapter_state_t *, ql_tgt_t *q, ql_srb_t *, 104 uint32_t *, uint32_t *); 105static void ql_halt(ql_adapter_state_t *, int); 106static int ql_els_plogi(ql_adapter_state_t *, fc_packet_t *); 107static int ql_els_flogi(ql_adapter_state_t *, fc_packet_t *); 108static int ql_els_logo(ql_adapter_state_t *, fc_packet_t *); 109static int ql_els_prli(ql_adapter_state_t *, fc_packet_t *); 110static int ql_els_prlo(ql_adapter_state_t *, fc_packet_t *); 111static int ql_els_adisc(ql_adapter_state_t *, fc_packet_t *); 112static int ql_els_linit(ql_adapter_state_t *, fc_packet_t *); 113static int ql_els_lpc(ql_adapter_state_t *, fc_packet_t *); 114static int ql_els_lsts(ql_adapter_state_t *, fc_packet_t *); 115static int ql_els_scr(ql_adapter_state_t *, fc_packet_t *); 116static int ql_els_rscn(ql_adapter_state_t *, fc_packet_t *); 117static int ql_els_farp_req(ql_adapter_state_t *, fc_packet_t *); 118static int ql_els_farp_reply(ql_adapter_state_t *, fc_packet_t *); 119static int ql_els_rls(ql_adapter_state_t *, fc_packet_t *); 120static int ql_els_rnid(ql_adapter_state_t *, fc_packet_t *); 121static int ql_login_port(ql_adapter_state_t *, port_id_t); 122static int ql_login_fabric_port(ql_adapter_state_t *, ql_tgt_t *, uint16_t); 123static int ql_logout_port(ql_adapter_state_t *, port_id_t); 124static ql_lun_t *ql_lun_queue(ql_adapter_state_t *, ql_tgt_t *, uint16_t); 125static int ql_fcp_scsi_cmd(ql_adapter_state_t *, fc_packet_t *, ql_srb_t *); 126static int ql_fcp_ip_cmd(ql_adapter_state_t *, fc_packet_t *, ql_srb_t *); 127static int ql_fc_services(ql_adapter_state_t *, fc_packet_t *); 128static int ql_poll_cmd(ql_adapter_state_t *, ql_srb_t *, time_t); 129static int ql_start_cmd(ql_adapter_state_t *, ql_tgt_t *, fc_packet_t *, 130 ql_srb_t *); 131static int ql_kstat_update(kstat_t *, int); 132static ql_adapter_state_t *ql_fca_handle_to_state(opaque_t); 133static ql_adapter_state_t *ql_cmd_setup(opaque_t, fc_packet_t *, int *); 134static int ql_program_flash_address(ql_adapter_state_t *, uint32_t, uint8_t); 135static void ql_rst_aen(ql_adapter_state_t *); 136static void ql_restart_queues(ql_adapter_state_t *); 137static void ql_abort_queues(ql_adapter_state_t *); 138static void ql_abort_device_queues(ql_adapter_state_t *ha, ql_tgt_t *tq); 139static void ql_idle_check(ql_adapter_state_t *); 140static int ql_loop_resync(ql_adapter_state_t *); 141static size_t ql_24xx_ascii_fw_dump(ql_adapter_state_t *, caddr_t); 142static size_t ql_2581_ascii_fw_dump(ql_adapter_state_t *, caddr_t); 143static int ql_save_config_regs(dev_info_t *); 144static int ql_restore_config_regs(dev_info_t *); 145static int ql_process_rscn(ql_adapter_state_t *, fc_affected_id_t *); 146static int ql_handle_rscn_update(ql_adapter_state_t *); 147static int ql_send_plogi(ql_adapter_state_t *, ql_tgt_t *, ql_head_t *); 148static int ql_process_rscn_for_device(ql_adapter_state_t *, ql_tgt_t *); 149static int ql_dump_firmware(ql_adapter_state_t *); 150static int ql_process_logo_for_device(ql_adapter_state_t *, ql_tgt_t *); 151static int ql_2200_binary_fw_dump(ql_adapter_state_t *, ql_fw_dump_t *); 152static int ql_2300_binary_fw_dump(ql_adapter_state_t *, ql_fw_dump_t *); 153static int ql_24xx_binary_fw_dump(ql_adapter_state_t *, ql_24xx_fw_dump_t *); 154static int ql_25xx_binary_fw_dump(ql_adapter_state_t *, ql_25xx_fw_dump_t *); 155static int ql_81xx_binary_fw_dump(ql_adapter_state_t *, ql_81xx_fw_dump_t *); 156static int ql_read_risc_ram(ql_adapter_state_t *, uint32_t, uint32_t, 157 void *); 158static void *ql_read_regs(ql_adapter_state_t *, void *, void *, uint32_t, 159 uint8_t); 160static int ql_busy_plogi(ql_adapter_state_t *, fc_packet_t *, ql_tgt_t *); 161static int ql_suspend_adapter(ql_adapter_state_t *); 162static int ql_bstr_to_dec(char *, uint32_t *, uint32_t); 163static void ql_update_rscn(ql_adapter_state_t *, fc_affected_id_t *); 164int ql_alloc_dma_resouce(ql_adapter_state_t *, dma_mem_t *, int); 165static int ql_bind_dma_buffer(ql_adapter_state_t *, dma_mem_t *, int); 166static void ql_unbind_dma_buffer(ql_adapter_state_t *, dma_mem_t *); 167static void ql_timeout_insert(ql_adapter_state_t *, ql_tgt_t *, ql_srb_t *); 168static int ql_setup_interrupts(ql_adapter_state_t *); 169static int ql_setup_msi(ql_adapter_state_t *); 170static int ql_setup_msix(ql_adapter_state_t *); 171static int ql_setup_fixed(ql_adapter_state_t *); 172static void ql_release_intr(ql_adapter_state_t *); 173static void ql_disable_intr(ql_adapter_state_t *); 174static int ql_legacy_intr(ql_adapter_state_t *); 175static int ql_init_mutex(ql_adapter_state_t *); 176static void ql_destroy_mutex(ql_adapter_state_t *); 177static void ql_iidma(ql_adapter_state_t *); 178 179static int ql_n_port_plogi(ql_adapter_state_t *); 180static void ql_fca_isp_els_request(ql_adapter_state_t *, fc_packet_t *, 181 els_descriptor_t *); 182static void ql_isp_els_request_ctor(els_descriptor_t *, 183 els_passthru_entry_t *); 184static int ql_p2p_plogi(ql_adapter_state_t *, fc_packet_t *); 185static int ql_wait_for_td_stop(ql_adapter_state_t *ha); 186 187/* 188 * Global data 189 */ 190static uint8_t ql_enable_pm = 1; 191static int ql_flash_sbus_fpga = 0; 192uint32_t ql_os_release_level; 193uint32_t ql_disable_aif = 0; 194uint32_t ql_disable_msi = 0; 195uint32_t ql_disable_msix = 0; 196 197/* Timer routine variables. */ 198static timeout_id_t ql_timer_timeout_id = NULL; 199static clock_t ql_timer_ticks; 200 201/* Soft state head pointer. */ 202void *ql_state = NULL; 203 204/* Head adapter link. */ 205ql_head_t ql_hba = { 206 NULL, 207 NULL 208}; 209 210/* Global hba index */ 211uint32_t ql_gfru_hba_index = 1; 212 213/* 214 * Some IP defines and globals 215 */ 216uint32_t ql_ip_buffer_count = 128; 217uint32_t ql_ip_low_water = 10; 218uint8_t ql_ip_fast_post_count = 5; 219static int ql_ip_mtu = 65280; /* equivalent to FCIPMTU */ 220 221/* Device AL_PA to Device Head Queue index array. */ 222uint8_t ql_alpa_to_index[] = { 223 0x7e, 0x7d, 0x7c, 0x00, 0x7b, 0x01, 0x02, 0x03, 0x7a, 0x04, 224 0x05, 0x06, 0x07, 0x08, 0x09, 0x79, 0x78, 0x0a, 0x0b, 0x0c, 225 0x0d, 0x0e, 0x0f, 0x77, 0x76, 0x10, 0x11, 0x75, 0x12, 0x74, 226 0x73, 0x72, 0x13, 0x14, 0x15, 0x71, 0x16, 0x70, 0x6f, 0x6e, 227 0x17, 0x6d, 0x6c, 0x6b, 0x6a, 0x69, 0x68, 0x18, 0x19, 0x67, 228 0x66, 0x65, 0x64, 0x63, 0x62, 0x20, 0x21, 0x61, 0x60, 0x23, 229 0x5f, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x5e, 0x2a, 0x5d, 230 0x5c, 0x5b, 0x2b, 0x5a, 0x59, 0x58, 0x57, 0x56, 0x55, 0x2c, 231 0x2d, 0x54, 0x53, 0x52, 0x51, 0x50, 0x4f, 0x2e, 0x2f, 0x4e, 232 0x4d, 0x30, 0x4c, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x4b, 233 0x37, 0x4a, 0x49, 0x48, 0x38, 0x47, 0x46, 0x45, 0x44, 0x43, 234 0x42, 0x39, 0x3a, 0x41, 0x40, 0x3f, 0x3e, 0x3d, 0x3c, 0x3b, 235 0x3c, 0x3b, 0x3a, 0x3d, 0x39, 0x3e, 0x3f, 0x40, 0x38, 0x37, 236 0x36, 0x41, 0x35, 0x42, 0x43, 0x44, 0x34, 0x45, 0x46, 0x47, 237 0x48, 0x49, 0x4a, 0x33, 0x32, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, 238 0x50, 0x31, 0x30, 0x51, 0x52, 0x2f, 0x53, 0x2e, 0x2d, 0x2c, 239 0x54, 0x55, 0x56, 0x2b, 0x57, 0x2a, 0x29, 0x28, 0x58, 0x27, 240 0x26, 0x25, 0x24, 0x23, 0x22, 0x59, 0x5a, 0x21, 0x20, 0x1f, 241 0x1e, 0x1d, 0x1c, 0x5b, 0x5c, 0x1b, 0x1a, 0x5d, 0x19, 0x5e, 242 0x5f, 0x60, 0x61, 0x62, 0x63, 0x18, 0x64, 0x17, 0x16, 0x15, 243 0x65, 0x14, 0x13, 0x12, 0x11, 0x10, 0x0f, 0x66, 0x67, 0x0e, 244 0x0d, 0x0c, 0x0b, 0x0a, 0x09, 0x68, 0x69, 0x08, 0x07, 0x6a, 245 0x06, 0x6b, 0x6c, 0x6d, 0x05, 0x04, 0x03, 0x6e, 0x02, 0x6f, 246 0x70, 0x71, 0x01, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x00, 247 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7f, 0x80, 0x00, 0x01, 248 0x02, 0x03, 0x80, 0x7f, 0x7e, 0x04 249}; 250 251/* Device loop_id to ALPA array. */ 252static uint8_t ql_index_to_alpa[] = { 253 0xef, 0xe8, 0xe4, 0xe2, 0xe1, 0xe0, 0xdc, 0xda, 0xd9, 0xd6, 254 0xd5, 0xd4, 0xd3, 0xd2, 0xd1, 0xce, 0xcd, 0xcc, 0xcb, 0xca, 255 0xc9, 0xc7, 0xc6, 0xc5, 0xc3, 0xbc, 0xba, 0xb9, 0xb6, 0xb5, 256 0xb4, 0xb3, 0xb2, 0xb1, 0xae, 0xad, 0xac, 0xab, 0xaa, 0xa9, 257 0xa7, 0xa6, 0xa5, 0xa3, 0x9f, 0x9e, 0x9d, 0x9b, 0x98, 0x97, 258 0x90, 0x8f, 0x88, 0x84, 0x82, 0x81, 0x80, 0x7c, 0x7a, 0x79, 259 0x76, 0x75, 0x74, 0x73, 0x72, 0x71, 0x6e, 0x6d, 0x6c, 0x6b, 260 0x6a, 0x69, 0x67, 0x66, 0x65, 0x63, 0x5c, 0x5a, 0x59, 0x56, 261 0x55, 0x54, 0x53, 0x52, 0x51, 0x4e, 0x4d, 0x4c, 0x4b, 0x4a, 262 0x49, 0x47, 0x46, 0x45, 0x43, 0x3c, 0x3a, 0x39, 0x36, 0x35, 263 0x34, 0x33, 0x32, 0x31, 0x2e, 0x2d, 0x2c, 0x2b, 0x2a, 0x29, 264 0x27, 0x26, 0x25, 0x23, 0x1f, 0x1e, 0x1d, 0x1b, 0x18, 0x17, 265 0x10, 0x0f, 0x08, 0x04, 0x02, 0x01 266}; 267 268/* 2200 register offsets */ 269static reg_off_t reg_off_2200 = { 270 0x00, 0x02, 0x06, 0x08, 0x0a, 0x0c, 0x0e, 271 0x18, 0x18, 0x1A, 0x1A, /* req in, out, resp in, out */ 272 0x00, 0x00, /* intr info lo, hi */ 273 24, /* Number of mailboxes */ 274 /* Mailbox register offsets */ 275 0x10, 0x12, 0x14, 0x16, 0x18, 0x1a, 0x1c, 0x1e, 276 0xe0, 0xe2, 0xe4, 0xe6, 0xe8, 0xea, 0xec, 0xee, 277 0xf0, 0xf2, 0xf4, 0xf6, 0xf8, 0xfa, 0xfc, 0xfe, 278 /* 2200 does not have mailbox 24-31 */ 279 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 280 0x96, 0xa4, 0xb0, 0xb8, 0xc0, 0xcc, 0xce, 281 /* host to host sema */ 282 0x00, 283 /* 2200 does not have pri_req_in, pri_req_out, */ 284 /* atio_req_in, atio_req_out, io_base_addr */ 285 0xff, 0xff, 0xff, 0xff, 0xff 286}; 287 288/* 2300 register offsets */ 289static reg_off_t reg_off_2300 = { 290 0x00, 0x02, 0x06, 0x08, 0x0a, 0x0c, 0x0e, 291 0x10, 0x12, 0x14, 0x16, /* req in, out, resp in, out */ 292 0x18, 0x1A, /* intr info lo, hi */ 293 32, /* Number of mailboxes */ 294 /* Mailbox register offsets */ 295 0x40, 0x42, 0x44, 0x46, 0x48, 0x4a, 0x4c, 0x4e, 296 0x50, 0x52, 0x54, 0x56, 0x58, 0x5a, 0x5c, 0x5e, 297 0x60, 0x62, 0x64, 0x66, 0x68, 0x6a, 0x6c, 0x6e, 298 0x70, 0x72, 0x74, 0x76, 0x78, 0x7a, 0x7c, 0x7e, 299 0x96, 0xa4, 0xb0, 0x80, 0xc0, 0xcc, 0xce, 300 /* host to host sema */ 301 0x1c, 302 /* 2300 does not have pri_req_in, pri_req_out, */ 303 /* atio_req_in, atio_req_out, io_base_addr */ 304 0xff, 0xff, 0xff, 0xff, 0xff 305}; 306 307/* 2400/2500 register offsets */ 308reg_off_t reg_off_2400_2500 = { 309 0x00, 0x04, /* flash_address, flash_data */ 310 0x08, 0x0c, 0x10, /* ctrl_status, ictrl, istatus */ 311 /* 2400 does not have semaphore, nvram */ 312 0x14, 0x18, 313 0x1c, 0x20, 0x24, 0x28, /* req_in, req_out, resp_in, resp_out */ 314 0x44, 0x46, /* intr info lo, hi */ 315 32, /* Number of mailboxes */ 316 /* Mailbox register offsets */ 317 0x80, 0x82, 0x84, 0x86, 0x88, 0x8a, 0x8c, 0x8e, 318 0x90, 0x92, 0x94, 0x96, 0x98, 0x9a, 0x9c, 0x9e, 319 0xa0, 0xa2, 0xa4, 0xa6, 0xa8, 0xaa, 0xac, 0xae, 320 0xb0, 0xb2, 0xb4, 0xb6, 0xb8, 0xba, 0xbc, 0xbe, 321 /* 2400 does not have fpm_diag_config, pcr, mctr, fb_cmd */ 322 0xff, 0xff, 0xff, 0xff, 323 0x48, 0x4c, 0x50, /* hccr, gpiod, gpioe */ 324 0xff, /* host to host sema */ 325 0x2c, 0x30, /* pri_req_in, pri_req_out */ 326 0x3c, 0x40, /* atio_req_in, atio_req_out */ 327 0x54 /* io_base_addr */ 328}; 329 330/* mutex for protecting variables shared by all instances of the driver */ 331kmutex_t ql_global_mutex; 332kmutex_t ql_global_hw_mutex; 333kmutex_t ql_global_el_mutex; 334 335/* DMA access attribute structure. */ 336static ddi_device_acc_attr_t ql_dev_acc_attr = { 337 DDI_DEVICE_ATTR_V0, 338 DDI_STRUCTURE_LE_ACC, 339 DDI_STRICTORDER_ACC 340}; 341 342/* I/O DMA attributes structures. */ 343static ddi_dma_attr_t ql_64bit_io_dma_attr = { 344 DMA_ATTR_V0, /* dma_attr_version */ 345 QL_DMA_LOW_ADDRESS, /* low DMA address range */ 346 QL_DMA_HIGH_64BIT_ADDRESS, /* high DMA address range */ 347 QL_DMA_XFER_COUNTER, /* DMA counter register */ 348 QL_DMA_ADDRESS_ALIGNMENT, /* DMA address alignment */ 349 QL_DMA_BURSTSIZES, /* DMA burstsizes */ 350 QL_DMA_MIN_XFER_SIZE, /* min effective DMA size */ 351 QL_DMA_MAX_XFER_SIZE, /* max DMA xfer size */ 352 QL_DMA_SEGMENT_BOUNDARY, /* segment boundary */ 353 QL_DMA_SG_LIST_LENGTH, /* s/g list length */ 354 QL_DMA_GRANULARITY, /* granularity of device */ 355 QL_DMA_XFER_FLAGS /* DMA transfer flags */ 356}; 357 358static ddi_dma_attr_t ql_32bit_io_dma_attr = { 359 DMA_ATTR_V0, /* dma_attr_version */ 360 QL_DMA_LOW_ADDRESS, /* low DMA address range */ 361 QL_DMA_HIGH_32BIT_ADDRESS, /* high DMA address range */ 362 QL_DMA_XFER_COUNTER, /* DMA counter register */ 363 QL_DMA_ADDRESS_ALIGNMENT, /* DMA address alignment */ 364 QL_DMA_BURSTSIZES, /* DMA burstsizes */ 365 QL_DMA_MIN_XFER_SIZE, /* min effective DMA size */ 366 QL_DMA_MAX_XFER_SIZE, /* max DMA xfer size */ 367 QL_DMA_SEGMENT_BOUNDARY, /* segment boundary */ 368 QL_DMA_SG_LIST_LENGTH, /* s/g list length */ 369 QL_DMA_GRANULARITY, /* granularity of device */ 370 QL_DMA_XFER_FLAGS /* DMA transfer flags */ 371}; 372 373/* Load the default dma attributes */ 374static ddi_dma_attr_t ql_32fcsm_cmd_dma_attr; 375static ddi_dma_attr_t ql_64fcsm_cmd_dma_attr; 376static ddi_dma_attr_t ql_32fcsm_rsp_dma_attr; 377static ddi_dma_attr_t ql_64fcsm_rsp_dma_attr; 378static ddi_dma_attr_t ql_32fcip_cmd_dma_attr; 379static ddi_dma_attr_t ql_64fcip_cmd_dma_attr; 380static ddi_dma_attr_t ql_32fcip_rsp_dma_attr; 381static ddi_dma_attr_t ql_64fcip_rsp_dma_attr; 382static ddi_dma_attr_t ql_32fcp_cmd_dma_attr; 383static ddi_dma_attr_t ql_64fcp_cmd_dma_attr; 384static ddi_dma_attr_t ql_32fcp_rsp_dma_attr; 385static ddi_dma_attr_t ql_64fcp_rsp_dma_attr; 386static ddi_dma_attr_t ql_32fcp_data_dma_attr; 387static ddi_dma_attr_t ql_64fcp_data_dma_attr; 388 389/* Static declarations of cb_ops entry point functions... */ 390static struct cb_ops ql_cb_ops = { 391 ql_open, /* b/c open */ 392 ql_close, /* b/c close */ 393 nodev, /* b strategy */ 394 nodev, /* b print */ 395 nodev, /* b dump */ 396 nodev, /* c read */ 397 nodev, /* c write */ 398 ql_ioctl, /* c ioctl */ 399 nodev, /* c devmap */ 400 nodev, /* c mmap */ 401 nodev, /* c segmap */ 402 nochpoll, /* c poll */ 403 nodev, /* cb_prop_op */ 404 NULL, /* streamtab */ 405 D_MP | D_NEW | D_HOTPLUG, /* Driver compatibility flag */ 406 CB_REV, /* cb_ops revision */ 407 nodev, /* c aread */ 408 nodev /* c awrite */ 409}; 410 411/* Static declarations of dev_ops entry point functions... */ 412static struct dev_ops ql_devops = { 413 DEVO_REV, /* devo_rev */ 414 0, /* refcnt */ 415 ql_getinfo, /* getinfo */ 416 nulldev, /* identify */ 417 nulldev, /* probe */ 418 ql_attach, /* attach */ 419 ql_detach, /* detach */ 420 nodev, /* reset */ 421 &ql_cb_ops, /* char/block ops */ 422 NULL, /* bus operations */ 423 ql_power, /* power management */ 424 ql_quiesce /* quiesce device */ 425}; 426 427/* ELS command code to text converter */ 428cmd_table_t els_cmd_tbl[] = ELS_CMD_TABLE(); 429/* Mailbox command code to text converter */ 430cmd_table_t mbox_cmd_tbl[] = MBOX_CMD_TABLE(); 431 432char qlc_driver_version[] = QL_VERSION; 433 434/* 435 * Loadable Driver Interface Structures. 436 * Declare and initialize the module configuration section... 437 */ 438static struct modldrv modldrv = { 439 &mod_driverops, /* type of module: driver */ 440 "SunFC Qlogic FCA v" QL_VERSION, /* name of module */ 441 &ql_devops /* driver dev_ops */ 442}; 443 444static struct modlinkage modlinkage = { 445 MODREV_1, 446 &modldrv, 447 NULL 448}; 449 450/* ************************************************************************ */ 451/* Loadable Module Routines. */ 452/* ************************************************************************ */ 453 454/* 455 * _init 456 * Initializes a loadable module. It is called before any other 457 * routine in a loadable module. 458 * 459 * Returns: 460 * 0 = success 461 * 462 * Context: 463 * Kernel context. 464 */ 465int 466_init(void) 467{ 468 uint16_t w16; 469 int rval = 0; 470 471 /* Get OS major release level. */ 472 for (w16 = 0; w16 < sizeof (utsname.release); w16++) { 473 if (utsname.release[w16] == '.') { 474 w16++; 475 break; 476 } 477 } 478 if (w16 < sizeof (utsname.release)) { 479 (void) ql_bstr_to_dec(&utsname.release[w16], 480 &ql_os_release_level, 0); 481 } else { 482 ql_os_release_level = 0; 483 } 484 if (ql_os_release_level < 6) { 485 cmn_err(CE_WARN, "%s Unsupported OS release level = %d", 486 QL_NAME, ql_os_release_level); 487 rval = EINVAL; 488 } 489 if (ql_os_release_level == 6) { 490 ql_32bit_io_dma_attr.dma_attr_count_max = 0x00ffffff; 491 ql_64bit_io_dma_attr.dma_attr_count_max = 0x00ffffff; 492 } 493 494 if (rval == 0) { 495 rval = ddi_soft_state_init(&ql_state, 496 sizeof (ql_adapter_state_t), 0); 497 } 498 if (rval == 0) { 499 /* allow the FC Transport to tweak the dev_ops */ 500 fc_fca_init(&ql_devops); 501 502 mutex_init(&ql_global_mutex, NULL, MUTEX_DRIVER, NULL); 503 mutex_init(&ql_global_hw_mutex, NULL, MUTEX_DRIVER, NULL); 504 mutex_init(&ql_global_el_mutex, NULL, MUTEX_DRIVER, NULL); 505 rval = mod_install(&modlinkage); 506 if (rval != 0) { 507 mutex_destroy(&ql_global_hw_mutex); 508 mutex_destroy(&ql_global_mutex); 509 mutex_destroy(&ql_global_el_mutex); 510 ddi_soft_state_fini(&ql_state); 511 } else { 512 /*EMPTY*/ 513 ql_32fcsm_cmd_dma_attr = ql_32bit_io_dma_attr; 514 ql_64fcsm_cmd_dma_attr = ql_64bit_io_dma_attr; 515 ql_32fcsm_rsp_dma_attr = ql_32bit_io_dma_attr; 516 ql_64fcsm_rsp_dma_attr = ql_64bit_io_dma_attr; 517 ql_32fcip_cmd_dma_attr = ql_32bit_io_dma_attr; 518 ql_64fcip_cmd_dma_attr = ql_64bit_io_dma_attr; 519 ql_32fcip_rsp_dma_attr = ql_32bit_io_dma_attr; 520 ql_64fcip_rsp_dma_attr = ql_64bit_io_dma_attr; 521 ql_32fcp_cmd_dma_attr = ql_32bit_io_dma_attr; 522 ql_64fcp_cmd_dma_attr = ql_64bit_io_dma_attr; 523 ql_32fcp_rsp_dma_attr = ql_32bit_io_dma_attr; 524 ql_64fcp_rsp_dma_attr = ql_64bit_io_dma_attr; 525 ql_32fcp_data_dma_attr = ql_32bit_io_dma_attr; 526 ql_64fcp_data_dma_attr = ql_64bit_io_dma_attr; 527 ql_32fcsm_cmd_dma_attr.dma_attr_sgllen = 528 ql_64fcsm_cmd_dma_attr.dma_attr_sgllen = 529 QL_FCSM_CMD_SGLLEN; 530 ql_32fcsm_rsp_dma_attr.dma_attr_sgllen = 531 ql_64fcsm_rsp_dma_attr.dma_attr_sgllen = 532 QL_FCSM_RSP_SGLLEN; 533 ql_32fcip_cmd_dma_attr.dma_attr_sgllen = 534 ql_64fcip_cmd_dma_attr.dma_attr_sgllen = 535 QL_FCIP_CMD_SGLLEN; 536 ql_32fcip_rsp_dma_attr.dma_attr_sgllen = 537 ql_64fcip_rsp_dma_attr.dma_attr_sgllen = 538 QL_FCIP_RSP_SGLLEN; 539 ql_32fcp_cmd_dma_attr.dma_attr_sgllen = 540 ql_64fcp_cmd_dma_attr.dma_attr_sgllen = 541 QL_FCP_CMD_SGLLEN; 542 ql_32fcp_rsp_dma_attr.dma_attr_sgllen = 543 ql_64fcp_rsp_dma_attr.dma_attr_sgllen = 544 QL_FCP_RSP_SGLLEN; 545 } 546 } 547 548 if (rval != 0) { 549 cmn_err(CE_CONT, "?Unable to install/attach driver '%s'", 550 QL_NAME); 551 } 552 553 return (rval); 554} 555 556/* 557 * _fini 558 * Prepares a module for unloading. It is called when the system 559 * wants to unload a module. If the module determines that it can 560 * be unloaded, then _fini() returns the value returned by 561 * mod_remove(). Upon successful return from _fini() no other 562 * routine in the module will be called before _init() is called. 563 * 564 * Returns: 565 * 0 = success 566 * 567 * Context: 568 * Kernel context. 569 */ 570int 571_fini(void) 572{ 573 int rval; 574 575 rval = mod_remove(&modlinkage); 576 if (rval == 0) { 577 mutex_destroy(&ql_global_hw_mutex); 578 mutex_destroy(&ql_global_mutex); 579 mutex_destroy(&ql_global_el_mutex); 580 ddi_soft_state_fini(&ql_state); 581 } 582 583 return (rval); 584} 585 586/* 587 * _info 588 * Returns information about loadable module. 589 * 590 * Input: 591 * modinfo = pointer to module information structure. 592 * 593 * Returns: 594 * Value returned by mod_info(). 595 * 596 * Context: 597 * Kernel context. 598 */ 599int 600_info(struct modinfo *modinfop) 601{ 602 return (mod_info(&modlinkage, modinfop)); 603} 604 605/* ************************************************************************ */ 606/* dev_ops functions */ 607/* ************************************************************************ */ 608 609/* 610 * ql_getinfo 611 * Returns the pointer associated with arg when cmd is 612 * set to DDI_INFO_DEVT2DEVINFO, or it should return the 613 * instance number associated with arg when cmd is set 614 * to DDI_INFO_DEV2INSTANCE. 615 * 616 * Input: 617 * dip = Do not use. 618 * cmd = command argument. 619 * arg = command specific argument. 620 * resultp = pointer to where request information is stored. 621 * 622 * Returns: 623 * DDI_SUCCESS or DDI_FAILURE. 624 * 625 * Context: 626 * Kernel context. 627 */ 628/* ARGSUSED */ 629static int 630ql_getinfo(dev_info_t *dip, ddi_info_cmd_t cmd, void *arg, void **resultp) 631{ 632 ql_adapter_state_t *ha; 633 int minor; 634 int rval = DDI_FAILURE; 635 636 minor = (int)(getminor((dev_t)arg)); 637 ha = ddi_get_soft_state(ql_state, minor); 638 if (ha == NULL) { 639 QL_PRINT_2(CE_CONT, "failed, unknown minor=%d\n", 640 getminor((dev_t)arg)); 641 *resultp = NULL; 642 return (rval); 643 } 644 645 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance); 646 647 switch (cmd) { 648 case DDI_INFO_DEVT2DEVINFO: 649 *resultp = ha->dip; 650 rval = DDI_SUCCESS; 651 break; 652 case DDI_INFO_DEVT2INSTANCE: 653 *resultp = (void *)(uintptr_t)(ha->instance); 654 rval = DDI_SUCCESS; 655 break; 656 default: 657 EL(ha, "failed, unsupported cmd=%d\n", cmd); 658 rval = DDI_FAILURE; 659 break; 660 } 661 662 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance); 663 664 return (rval); 665} 666 667/* 668 * ql_attach 669 * Configure and attach an instance of the driver 670 * for a port. 671 * 672 * Input: 673 * dip = pointer to device information structure. 674 * cmd = attach type. 675 * 676 * Returns: 677 * DDI_SUCCESS or DDI_FAILURE. 678 * 679 * Context: 680 * Kernel context. 681 */ 682static int 683ql_attach(dev_info_t *dip, ddi_attach_cmd_t cmd) 684{ 685 uint32_t size; 686 int rval; 687 int instance; 688 uint_t progress = 0; 689 char *buf; 690 ushort_t caps_ptr, cap; 691 fc_fca_tran_t *tran; 692 ql_adapter_state_t *ha = NULL; 693 694 static char *pmcomps[] = { 695 NULL, 696 PM_LEVEL_D3_STR, /* Device OFF */ 697 PM_LEVEL_D0_STR, /* Device ON */ 698 }; 699 700 QL_PRINT_3(CE_CONT, "(%d): started, cmd=%xh\n", 701 ddi_get_instance(dip), cmd); 702 703 buf = (char *)(kmem_zalloc(MAXPATHLEN, KM_SLEEP)); 704 705 switch (cmd) { 706 case DDI_ATTACH: 707 /* first get the instance */ 708 instance = ddi_get_instance(dip); 709 710 cmn_err(CE_CONT, "!Qlogic %s(%d) FCA Driver v%s\n", 711 QL_NAME, instance, QL_VERSION); 712 713 /* Correct OS version? */ 714 if (ql_os_release_level != 11) { 715 cmn_err(CE_WARN, "%s(%d): This driver is for Solaris " 716 "11", QL_NAME, instance); 717 goto attach_failed; 718 } 719 720 /* Hardware is installed in a DMA-capable slot? */ 721 if (ddi_slaveonly(dip) == DDI_SUCCESS) { 722 cmn_err(CE_WARN, "%s(%d): slave only", QL_NAME, 723 instance); 724 goto attach_failed; 725 } 726 727 /* No support for high-level interrupts */ 728 if (ddi_intr_hilevel(dip, 0) != 0) { 729 cmn_err(CE_WARN, "%s(%d): High level interrupt" 730 " not supported", QL_NAME, instance); 731 goto attach_failed; 732 } 733 734 /* Allocate our per-device-instance structure */ 735 if (ddi_soft_state_zalloc(ql_state, 736 instance) != DDI_SUCCESS) { 737 cmn_err(CE_WARN, "%s(%d): soft state alloc failed", 738 QL_NAME, instance); 739 goto attach_failed; 740 } 741 progress |= QL_SOFT_STATE_ALLOCED; 742 743 ha = ddi_get_soft_state(ql_state, instance); 744 if (ha == NULL) { 745 cmn_err(CE_WARN, "%s(%d): can't get soft state", 746 QL_NAME, instance); 747 goto attach_failed; 748 } 749 ha->dip = dip; 750 ha->instance = instance; 751 ha->hba.base_address = ha; 752 ha->pha = ha; 753 754 if (ql_el_trace_desc_ctor(ha) != DDI_SUCCESS) { 755 cmn_err(CE_WARN, "%s(%d): can't setup el tracing", 756 QL_NAME, instance); 757 goto attach_failed; 758 } 759 760 /* Get extended logging and dump flags. */ 761 ql_common_properties(ha); 762 763 if (strcmp(ddi_driver_name(ddi_get_parent(dip)), 764 "sbus") == 0) { 765 EL(ha, "%s SBUS card detected", QL_NAME); 766 ha->cfg_flags |= CFG_SBUS_CARD; 767 } 768 769 ha->dev = kmem_zalloc(sizeof (*ha->dev) * 770 DEVICE_HEAD_LIST_SIZE, KM_SLEEP); 771 772 ha->outstanding_cmds = kmem_zalloc( 773 sizeof (*ha->outstanding_cmds) * MAX_OUTSTANDING_COMMANDS, 774 KM_SLEEP); 775 776 ha->ub_array = kmem_zalloc(sizeof (*ha->ub_array) * 777 QL_UB_LIMIT, KM_SLEEP); 778 779 ha->adapter_stats = kmem_zalloc(sizeof (*ha->adapter_stats), 780 KM_SLEEP); 781 782 (void) ddi_pathname(dip, buf); 783 ha->devpath = kmem_zalloc(strlen(buf)+1, KM_SLEEP); 784 if (ha->devpath == NULL) { 785 EL(ha, "devpath mem alloc failed\n"); 786 } else { 787 (void) strcpy(ha->devpath, buf); 788 EL(ha, "devpath is: %s\n", ha->devpath); 789 } 790 791 if (CFG_IST(ha, CFG_SBUS_CARD)) { 792 /* 793 * For cards where PCI is mapped to sbus e.g. Ivory. 794 * 795 * 0x00 : 0x000 - 0x0FF PCI Config Space for 2200 796 * : 0x100 - 0x3FF PCI IO space for 2200 797 * 0x01 : 0x000 - 0x0FF PCI Config Space for fpga 798 * : 0x100 - 0x3FF PCI IO Space for fpga 799 */ 800 if (ddi_regs_map_setup(dip, 0, (caddr_t *)&ha->iobase, 801 0x100, 0x300, &ql_dev_acc_attr, &ha->dev_handle) 802 != DDI_SUCCESS) { 803 cmn_err(CE_WARN, "%s(%d): Unable to map device" 804 " registers", QL_NAME, instance); 805 goto attach_failed; 806 } 807 if (ddi_regs_map_setup(dip, 1, 808 (caddr_t *)&ha->sbus_fpga_iobase, 0, 0x400, 809 &ql_dev_acc_attr, &ha->sbus_fpga_dev_handle) 810 != DDI_SUCCESS) { 811 /* We should not fail attach here */ 812 cmn_err(CE_WARN, "%s(%d): Unable to map FPGA", 813 QL_NAME, instance); 814 ha->sbus_fpga_iobase = NULL; 815 } 816 progress |= QL_REGS_MAPPED; 817 } else { 818 /* 819 * Setup the ISP2200 registers address mapping to be 820 * accessed by this particular driver. 821 * 0x0 Configuration Space 822 * 0x1 I/O Space 823 * 0x2 32-bit Memory Space address 824 * 0x3 64-bit Memory Space address 825 */ 826 if (ddi_regs_map_setup(dip, 2, (caddr_t *)&ha->iobase, 827 0, 0x100, &ql_dev_acc_attr, 828 &ha->dev_handle) != DDI_SUCCESS) { 829 cmn_err(CE_WARN, "%s(%d): regs_map_setup " 830 "failed", QL_NAME, instance); 831 goto attach_failed; 832 } 833 progress |= QL_REGS_MAPPED; 834 835 /* 836 * We need I/O space mappings for 23xx HBAs for 837 * loading flash (FCode). The chip has a bug due to 838 * which loading flash fails through mem space 839 * mappings in PCI-X mode. 840 */ 841 if (ddi_regs_map_setup(dip, 1, 842 (caddr_t *)&ha->iomap_iobase, 0, 0x100, 843 &ql_dev_acc_attr, 844 &ha->iomap_dev_handle) != DDI_SUCCESS) { 845 cmn_err(CE_WARN, "%s(%d): regs_map_setup(I/O)" 846 " failed", QL_NAME, instance); 847 goto attach_failed; 848 } 849 progress |= QL_IOMAP_IOBASE_MAPPED; 850 } 851 852 /* 853 * We should map config space before adding interrupt 854 * So that the chip type (2200 or 2300) can be determined 855 * before the interrupt routine gets a chance to execute. 856 */ 857 if (CFG_IST(ha, CFG_SBUS_CARD)) { 858 if (ddi_regs_map_setup(dip, 0, 859 (caddr_t *)&ha->sbus_config_base, 0, 0x100, 860 &ql_dev_acc_attr, &ha->sbus_config_handle) != 861 DDI_SUCCESS) { 862 cmn_err(CE_WARN, "%s(%d): Unable to map sbus " 863 "config registers", QL_NAME, instance); 864 goto attach_failed; 865 } 866 } else { 867 if (pci_config_setup(ha->dip, &ha->pci_handle) != 868 DDI_SUCCESS) { 869 cmn_err(CE_WARN, "%s(%d): can't setup PCI " 870 "config space", QL_NAME, instance); 871 goto attach_failed; 872 } 873 } 874 progress |= QL_CONFIG_SPACE_SETUP; 875 876 ha->subsys_id = (uint16_t)ql_pci_config_get16(ha, 877 PCI_CONF_SUBSYSID); 878 ha->subven_id = (uint16_t)ql_pci_config_get16(ha, 879 PCI_CONF_SUBVENID); 880 ha->ven_id = (uint16_t)ql_pci_config_get16(ha, 881 PCI_CONF_VENID); 882 ha->device_id = (uint16_t)ql_pci_config_get16(ha, 883 PCI_CONF_DEVID); 884 ha->rev_id = (uint8_t)ql_pci_config_get8(ha, 885 PCI_CONF_REVID); 886 887 EL(ha, "ISP%x chip detected (RevID=%x, VenID=%x, SVenID=%x, " 888 "SSysID=%x)\n", ha->device_id, ha->rev_id, ha->ven_id, 889 ha->subven_id, ha->subsys_id); 890 891 switch (ha->device_id) { 892 case 0x2300: 893 case 0x2312: 894#if !defined(__sparc) || defined(QL_DEBUG_ROUTINES) 895 /* 896 * per marketing, fibre-lite HBA's are not supported 897 * on sparc platforms 898 */ 899 case 0x6312: 900 case 0x6322: 901#endif /* !defined(__sparc) || defined(QL_DEBUG_ROUTINES) */ 902 if (ql_pci_config_get8(ha, PCI_CONF_IPIN) == 2) { 903 ha->flags |= FUNCTION_1; 904 } 905 if (ha->device_id == 0x6322) { 906 ha->cfg_flags |= CFG_CTRL_6322; 907 ha->fw_class = 0x6322; 908 ha->risc_dump_size = QL_6322_FW_DUMP_SIZE; 909 } else { 910 ha->cfg_flags |= CFG_CTRL_2300; 911 ha->fw_class = 0x2300; 912 ha->risc_dump_size = QL_2300_FW_DUMP_SIZE; 913 } 914 ha->reg_off = ®_off_2300; 915 if (ql_fwmodule_resolve(ha) != QL_SUCCESS) { 916 goto attach_failed; 917 } 918 ha->fcp_cmd = ql_command_iocb; 919 ha->ip_cmd = ql_ip_iocb; 920 ha->ms_cmd = ql_ms_iocb; 921 if (CFG_IST(ha, CFG_SBUS_CARD)) { 922 ha->cmd_segs = CMD_TYPE_2_DATA_SEGMENTS; 923 ha->cmd_cont_segs = CONT_TYPE_0_DATA_SEGMENTS; 924 } else { 925 ha->cmd_segs = CMD_TYPE_3_DATA_SEGMENTS; 926 ha->cmd_cont_segs = CONT_TYPE_1_DATA_SEGMENTS; 927 } 928 break; 929 930 case 0x2200: 931 ha->cfg_flags |= CFG_CTRL_2200; 932 ha->reg_off = ®_off_2200; 933 ha->fw_class = 0x2200; 934 if (ql_fwmodule_resolve(ha) != QL_SUCCESS) { 935 goto attach_failed; 936 } 937 ha->risc_dump_size = QL_2200_FW_DUMP_SIZE; 938 ha->fcp_cmd = ql_command_iocb; 939 ha->ip_cmd = ql_ip_iocb; 940 ha->ms_cmd = ql_ms_iocb; 941 if (CFG_IST(ha, CFG_SBUS_CARD)) { 942 ha->cmd_segs = CMD_TYPE_2_DATA_SEGMENTS; 943 ha->cmd_cont_segs = CONT_TYPE_0_DATA_SEGMENTS; 944 } else { 945 ha->cmd_segs = CMD_TYPE_3_DATA_SEGMENTS; 946 ha->cmd_cont_segs = CONT_TYPE_1_DATA_SEGMENTS; 947 } 948 break; 949 950 case 0x2422: 951 case 0x2432: 952 case 0x5422: 953 case 0x5432: 954 case 0x8432: 955#ifdef __sparc 956 /* 957 * Per marketing, the QLA/QLE-2440's (which 958 * also use the 2422 & 2432) are only for the 959 * x86 platform (SMB market). 960 */ 961 if (ha->subsys_id == 0x145 || ha->subsys_id == 0x147 || 962 ha->subsys_id == 0x13e) { 963 cmn_err(CE_WARN, 964 "%s(%d): Unsupported HBA ssid: %x", 965 QL_NAME, instance, ha->subsys_id); 966 goto attach_failed; 967 } 968#endif /* __sparc */ 969 if (ql_pci_config_get8(ha, PCI_CONF_IPIN) == 2) { 970 ha->flags |= FUNCTION_1; 971 } 972 ha->cfg_flags |= CFG_CTRL_2422; 973 if (ha->device_id == 0x8432) { 974 ha->cfg_flags |= CFG_CTRL_MENLO; 975 } else { 976 ha->flags |= VP_ENABLED; 977 } 978 979 ha->reg_off = ®_off_2400_2500; 980 ha->fw_class = 0x2400; 981 if (ql_fwmodule_resolve(ha) != QL_SUCCESS) { 982 goto attach_failed; 983 } 984 ha->risc_dump_size = QL_24XX_FW_DUMP_SIZE; 985 ha->fcp_cmd = ql_command_24xx_iocb; 986 ha->ip_cmd = ql_ip_24xx_iocb; 987 ha->ms_cmd = ql_ms_24xx_iocb; 988 ha->els_cmd = ql_els_24xx_iocb; 989 ha->cmd_segs = CMD_TYPE_7_DATA_SEGMENTS; 990 ha->cmd_cont_segs = CONT_TYPE_1_DATA_SEGMENTS; 991 break; 992 993 case 0x2522: 994 case 0x2532: 995 if (ql_pci_config_get8(ha, PCI_CONF_IPIN) == 2) { 996 ha->flags |= FUNCTION_1; 997 } 998 ha->cfg_flags |= CFG_CTRL_25XX; 999 ha->flags |= VP_ENABLED; 1000 ha->fw_class = 0x2500; 1001 ha->reg_off = ®_off_2400_2500; 1002 if (ql_fwmodule_resolve(ha) != QL_SUCCESS) { 1003 goto attach_failed; 1004 } 1005 ha->risc_dump_size = QL_25XX_FW_DUMP_SIZE; 1006 ha->fcp_cmd = ql_command_24xx_iocb; 1007 ha->ip_cmd = ql_ip_24xx_iocb; 1008 ha->ms_cmd = ql_ms_24xx_iocb; 1009 ha->els_cmd = ql_els_24xx_iocb; 1010 ha->cmd_segs = CMD_TYPE_7_DATA_SEGMENTS; 1011 ha->cmd_cont_segs = CONT_TYPE_1_DATA_SEGMENTS; 1012 break; 1013 1014 case 0x8001: 1015 if (ql_pci_config_get8(ha, PCI_CONF_IPIN) == 4) { 1016 ha->flags |= FUNCTION_1; 1017 } 1018 ha->cfg_flags |= CFG_CTRL_81XX; 1019 ha->flags |= VP_ENABLED; 1020 ha->fw_class = 0x8100; 1021 ha->reg_off = ®_off_2400_2500; 1022 if (ql_fwmodule_resolve(ha) != QL_SUCCESS) { 1023 goto attach_failed; 1024 } 1025 ha->risc_dump_size = QL_25XX_FW_DUMP_SIZE; 1026 ha->fcp_cmd = ql_command_24xx_iocb; 1027 ha->ip_cmd = ql_ip_24xx_iocb; 1028 ha->ms_cmd = ql_ms_24xx_iocb; 1029 ha->cmd_segs = CMD_TYPE_7_DATA_SEGMENTS; 1030 ha->cmd_cont_segs = CONT_TYPE_1_DATA_SEGMENTS; 1031 break; 1032 1033 default: 1034 cmn_err(CE_WARN, "%s(%d): Unsupported device id: %x", 1035 QL_NAME, instance, ha->device_id); 1036 goto attach_failed; 1037 } 1038 1039 /* Setup hba buffer. */ 1040 1041 size = CFG_IST(ha, CFG_CTRL_242581) ? 1042 (REQUEST_QUEUE_SIZE + RESPONSE_QUEUE_SIZE) : 1043 (REQUEST_QUEUE_SIZE + RESPONSE_QUEUE_SIZE + 1044 RCVBUF_QUEUE_SIZE); 1045 1046 if (ql_get_dma_mem(ha, &ha->hba_buf, size, LITTLE_ENDIAN_DMA, 1047 QL_DMA_RING_ALIGN) != QL_SUCCESS) { 1048 cmn_err(CE_WARN, "%s(%d): request queue DMA memory " 1049 "alloc failed", QL_NAME, instance); 1050 goto attach_failed; 1051 } 1052 progress |= QL_HBA_BUFFER_SETUP; 1053 1054 /* Setup buffer pointers. */ 1055 ha->request_dvma = ha->hba_buf.cookie.dmac_laddress + 1056 REQUEST_Q_BUFFER_OFFSET; 1057 ha->request_ring_bp = (struct cmd_entry *) 1058 ((caddr_t)ha->hba_buf.bp + REQUEST_Q_BUFFER_OFFSET); 1059 1060 ha->response_dvma = ha->hba_buf.cookie.dmac_laddress + 1061 RESPONSE_Q_BUFFER_OFFSET; 1062 ha->response_ring_bp = (struct sts_entry *) 1063 ((caddr_t)ha->hba_buf.bp + RESPONSE_Q_BUFFER_OFFSET); 1064 1065 ha->rcvbuf_dvma = ha->hba_buf.cookie.dmac_laddress + 1066 RCVBUF_Q_BUFFER_OFFSET; 1067 ha->rcvbuf_ring_bp = (struct rcvbuf *) 1068 ((caddr_t)ha->hba_buf.bp + RCVBUF_Q_BUFFER_OFFSET); 1069 1070 /* Allocate resource for QLogic IOCTL */ 1071 (void) ql_alloc_xioctl_resource(ha); 1072 1073 /* Setup interrupts */ 1074 if ((rval = ql_setup_interrupts(ha)) != DDI_SUCCESS) { 1075 cmn_err(CE_WARN, "%s(%d): Failed to add interrupt, " 1076 "rval=%xh", QL_NAME, instance, rval); 1077 goto attach_failed; 1078 } 1079 1080 progress |= (QL_INTR_ADDED | QL_MUTEX_CV_INITED); 1081 1082 /* 1083 * Allocate an N Port information structure 1084 * for use when in P2P topology. 1085 */ 1086 ha->n_port = (ql_n_port_info_t *) 1087 kmem_zalloc(sizeof (ql_n_port_info_t), KM_SLEEP); 1088 if (ha->n_port == NULL) { 1089 cmn_err(CE_WARN, "%s(%d): Failed to create N Port info", 1090 QL_NAME, instance); 1091 goto attach_failed; 1092 } 1093 1094 progress |= QL_N_PORT_INFO_CREATED; 1095 1096 /* 1097 * Determine support for Power Management 1098 */ 1099 caps_ptr = (uint8_t)ql_pci_config_get8(ha, PCI_CONF_CAP_PTR); 1100 1101 while (caps_ptr != PCI_CAP_NEXT_PTR_NULL) { 1102 cap = (uint8_t)ql_pci_config_get8(ha, caps_ptr); 1103 if (cap == PCI_CAP_ID_PM) { 1104 ha->pm_capable = 1; 1105 break; 1106 } 1107 caps_ptr = (uint8_t)ql_pci_config_get8(ha, caps_ptr + 1108 PCI_CAP_NEXT_PTR); 1109 } 1110 1111 if (ha->pm_capable) { 1112 /* 1113 * Enable PM for 2200 based HBAs only. 1114 */ 1115 if (ha->device_id != 0x2200) { 1116 ha->pm_capable = 0; 1117 } 1118 } 1119 1120 if (ha->pm_capable) { 1121 ha->pm_capable = ql_enable_pm; 1122 } 1123 1124 if (ha->pm_capable) { 1125 /* 1126 * Initialize power management bookkeeping; 1127 * components are created idle. 1128 */ 1129 (void) sprintf(buf, "NAME=%s(%d)", QL_NAME, instance); 1130 pmcomps[0] = buf; 1131 1132 /*LINTED [Solaris DDI_DEV_T_NONE Lint warning]*/ 1133 if (ddi_prop_update_string_array(DDI_DEV_T_NONE, 1134 dip, "pm-components", pmcomps, 1135 sizeof (pmcomps) / sizeof (pmcomps[0])) != 1136 DDI_PROP_SUCCESS) { 1137 cmn_err(CE_WARN, "%s(%d): failed to create" 1138 " pm-components property", QL_NAME, 1139 instance); 1140 1141 /* Initialize adapter. */ 1142 ha->power_level = PM_LEVEL_D0; 1143 if (ql_initialize_adapter(ha) != QL_SUCCESS) { 1144 cmn_err(CE_WARN, "%s(%d): failed to" 1145 " initialize adapter", QL_NAME, 1146 instance); 1147 goto attach_failed; 1148 } 1149 } else { 1150 ha->power_level = PM_LEVEL_D3; 1151 if (pm_raise_power(dip, QL_POWER_COMPONENT, 1152 PM_LEVEL_D0) != DDI_SUCCESS) { 1153 cmn_err(CE_WARN, "%s(%d): failed to" 1154 " raise power or initialize" 1155 " adapter", QL_NAME, instance); 1156 } 1157 } 1158 } else { 1159 /* Initialize adapter. */ 1160 ha->power_level = PM_LEVEL_D0; 1161 if (ql_initialize_adapter(ha) != QL_SUCCESS) { 1162 cmn_err(CE_WARN, "%s(%d): failed to initialize" 1163 " adapter", QL_NAME, instance); 1164 } 1165 } 1166 1167 if (ha->fw_major_version == 0 && ha->fw_minor_version == 0 && 1168 ha->fw_subminor_version == 0) { 1169 cmn_err(CE_NOTE, "!%s(%d): Firmware not loaded", 1170 QL_NAME, ha->instance); 1171 } else { 1172 int rval; 1173 char ver_fmt[256]; 1174 1175 rval = (int)snprintf(ver_fmt, (size_t)sizeof (ver_fmt), 1176 "Firmware version %d.%d.%d", ha->fw_major_version, 1177 ha->fw_minor_version, ha->fw_subminor_version); 1178 1179 if (CFG_IST(ha, CFG_CTRL_81XX)) { 1180 rval = (int)snprintf(ver_fmt + rval, 1181 (size_t)sizeof (ver_fmt), 1182 ", MPI fw version %d.%d.%d", 1183 ha->mpi_fw_major_version, 1184 ha->mpi_fw_minor_version, 1185 ha->mpi_fw_subminor_version); 1186 1187 if (ha->subsys_id == 0x17B || 1188 ha->subsys_id == 0x17D) { 1189 (void) snprintf(ver_fmt + rval, 1190 (size_t)sizeof (ver_fmt), 1191 ", PHY fw version %d.%d.%d", 1192 ha->phy_fw_major_version, 1193 ha->phy_fw_minor_version, 1194 ha->phy_fw_subminor_version); 1195 } 1196 } 1197 cmn_err(CE_NOTE, "!%s(%d): %s", 1198 QL_NAME, ha->instance, ver_fmt); 1199 } 1200 1201 ha->k_stats = kstat_create(QL_NAME, instance, "statistics", 1202 "controller", KSTAT_TYPE_RAW, 1203 (uint32_t)sizeof (ql_adapter_stat_t), KSTAT_FLAG_VIRTUAL); 1204 if (ha->k_stats == NULL) { 1205 cmn_err(CE_WARN, "%s(%d): Failed to create kstat", 1206 QL_NAME, instance); 1207 goto attach_failed; 1208 } 1209 progress |= QL_KSTAT_CREATED; 1210 1211 ha->adapter_stats->version = 1; 1212 ha->k_stats->ks_data = (void *)ha->adapter_stats; 1213 ha->k_stats->ks_private = ha; 1214 ha->k_stats->ks_update = ql_kstat_update; 1215 ha->k_stats->ks_ndata = 1; 1216 ha->k_stats->ks_data_size = sizeof (ql_adapter_stat_t); 1217 kstat_install(ha->k_stats); 1218 1219 if (ddi_create_minor_node(dip, "devctl", S_IFCHR, 1220 instance, DDI_NT_NEXUS, 0) != DDI_SUCCESS) { 1221 cmn_err(CE_WARN, "%s(%d): failed to create minor node", 1222 QL_NAME, instance); 1223 goto attach_failed; 1224 } 1225 progress |= QL_MINOR_NODE_CREATED; 1226 1227 /* Allocate a transport structure for this instance */ 1228 tran = kmem_zalloc(sizeof (fc_fca_tran_t), KM_SLEEP); 1229 if (tran == NULL) { 1230 cmn_err(CE_WARN, "%s(%d): failed to allocate transport", 1231 QL_NAME, instance); 1232 goto attach_failed; 1233 } 1234 1235 progress |= QL_FCA_TRAN_ALLOCED; 1236 1237 /* fill in the structure */ 1238 tran->fca_numports = 1; 1239 tran->fca_version = FCTL_FCA_MODREV_5; 1240 if (CFG_IST(ha, CFG_CTRL_2422)) { 1241 tran->fca_num_npivports = MAX_24_VIRTUAL_PORTS; 1242 } else if (CFG_IST(ha, CFG_CTRL_2581)) { 1243 tran->fca_num_npivports = MAX_25_VIRTUAL_PORTS; 1244 } 1245 bcopy(ha->loginparams.node_ww_name.raw_wwn, 1246 tran->fca_perm_pwwn.raw_wwn, 8); 1247 1248 EL(ha, "FCA version %d\n", tran->fca_version); 1249 1250 /* Specify the amount of space needed in each packet */ 1251 tran->fca_pkt_size = sizeof (ql_srb_t); 1252 1253 /* command limits are usually dictated by hardware */ 1254 tran->fca_cmd_max = MAX_OUTSTANDING_COMMANDS; 1255 1256 /* dmaattr are static, set elsewhere. */ 1257 if (CFG_IST(ha, CFG_ENABLE_64BIT_ADDRESSING)) { 1258 tran->fca_dma_attr = &ql_64bit_io_dma_attr; 1259 tran->fca_dma_fcp_cmd_attr = &ql_64fcp_cmd_dma_attr; 1260 tran->fca_dma_fcp_rsp_attr = &ql_64fcp_rsp_dma_attr; 1261 tran->fca_dma_fcp_data_attr = &ql_64fcp_data_dma_attr; 1262 tran->fca_dma_fcsm_cmd_attr = &ql_64fcsm_cmd_dma_attr; 1263 tran->fca_dma_fcsm_rsp_attr = &ql_64fcsm_rsp_dma_attr; 1264 tran->fca_dma_fcip_cmd_attr = &ql_64fcip_cmd_dma_attr; 1265 tran->fca_dma_fcip_rsp_attr = &ql_64fcip_rsp_dma_attr; 1266 } else { 1267 tran->fca_dma_attr = &ql_32bit_io_dma_attr; 1268 tran->fca_dma_fcp_cmd_attr = &ql_32fcp_cmd_dma_attr; 1269 tran->fca_dma_fcp_rsp_attr = &ql_32fcp_rsp_dma_attr; 1270 tran->fca_dma_fcp_data_attr = &ql_32fcp_data_dma_attr; 1271 tran->fca_dma_fcsm_cmd_attr = &ql_32fcsm_cmd_dma_attr; 1272 tran->fca_dma_fcsm_rsp_attr = &ql_32fcsm_rsp_dma_attr; 1273 tran->fca_dma_fcip_cmd_attr = &ql_32fcip_cmd_dma_attr; 1274 tran->fca_dma_fcip_rsp_attr = &ql_32fcip_rsp_dma_attr; 1275 } 1276 1277 tran->fca_acc_attr = &ql_dev_acc_attr; 1278 tran->fca_iblock = &(ha->iblock_cookie); 1279 1280 /* the remaining values are simply function vectors */ 1281 tran->fca_bind_port = ql_bind_port; 1282 tran->fca_unbind_port = ql_unbind_port; 1283 tran->fca_init_pkt = ql_init_pkt; 1284 tran->fca_un_init_pkt = ql_un_init_pkt; 1285 tran->fca_els_send = ql_els_send; 1286 tran->fca_get_cap = ql_get_cap; 1287 tran->fca_set_cap = ql_set_cap; 1288 tran->fca_getmap = ql_getmap; 1289 tran->fca_transport = ql_transport; 1290 tran->fca_ub_alloc = ql_ub_alloc; 1291 tran->fca_ub_free = ql_ub_free; 1292 tran->fca_ub_release = ql_ub_release; 1293 tran->fca_abort = ql_abort; 1294 tran->fca_reset = ql_reset; 1295 tran->fca_port_manage = ql_port_manage; 1296 tran->fca_get_device = ql_get_device; 1297 1298 /* give it to the FC transport */ 1299 if (fc_fca_attach(dip, tran) != DDI_SUCCESS) { 1300 cmn_err(CE_WARN, "%s(%d): FCA attach failed", QL_NAME, 1301 instance); 1302 goto attach_failed; 1303 } 1304 progress |= QL_FCA_ATTACH_DONE; 1305 1306 /* Stash the structure so it can be freed at detach */ 1307 ha->tran = tran; 1308 1309 /* Acquire global state lock. */ 1310 GLOBAL_STATE_LOCK(); 1311 1312 /* Add adapter structure to link list. */ 1313 ql_add_link_b(&ql_hba, &ha->hba); 1314 1315 /* Start one second driver timer. */ 1316 if (ql_timer_timeout_id == NULL) { 1317 ql_timer_ticks = drv_usectohz(1000000); 1318 ql_timer_timeout_id = timeout(ql_timer, (void *)0, 1319 ql_timer_ticks); 1320 } 1321 1322 /* Release global state lock. */ 1323 GLOBAL_STATE_UNLOCK(); 1324 1325 /* Determine and populate HBA fru info */ 1326 ql_setup_fruinfo(ha); 1327 1328 /* Setup task_daemon thread. */ 1329 (void) thread_create(NULL, 0, (void (*)())ql_task_daemon, ha, 1330 0, &p0, TS_RUN, minclsyspri); 1331 1332 progress |= QL_TASK_DAEMON_STARTED; 1333 1334 ddi_report_dev(dip); 1335 1336 /* Disable link reset in panic path */ 1337 ha->lip_on_panic = 1; 1338 1339 rval = DDI_SUCCESS; 1340 break; 1341 1342attach_failed: 1343 if (progress & QL_FCA_ATTACH_DONE) { 1344 (void) fc_fca_detach(dip); 1345 progress &= ~QL_FCA_ATTACH_DONE; 1346 } 1347 1348 if (progress & QL_FCA_TRAN_ALLOCED) { 1349 kmem_free(tran, sizeof (fc_fca_tran_t)); 1350 progress &= ~QL_FCA_TRAN_ALLOCED; 1351 } 1352 1353 if (progress & QL_MINOR_NODE_CREATED) { 1354 ddi_remove_minor_node(dip, "devctl"); 1355 progress &= ~QL_MINOR_NODE_CREATED; 1356 } 1357 1358 if (progress & QL_KSTAT_CREATED) { 1359 kstat_delete(ha->k_stats); 1360 progress &= ~QL_KSTAT_CREATED; 1361 } 1362 1363 if (progress & QL_N_PORT_INFO_CREATED) { 1364 kmem_free(ha->n_port, sizeof (ql_n_port_info_t)); 1365 progress &= ~QL_N_PORT_INFO_CREATED; 1366 } 1367 1368 if (progress & QL_TASK_DAEMON_STARTED) { 1369 TASK_DAEMON_LOCK(ha); 1370 1371 ha->task_daemon_flags |= TASK_DAEMON_STOP_FLG; 1372 1373 cv_signal(&ha->cv_task_daemon); 1374 1375 /* Release task daemon lock. */ 1376 TASK_DAEMON_UNLOCK(ha); 1377 1378 /* Wait for for task daemon to stop running. */ 1379 while (ha->task_daemon_flags & TASK_DAEMON_STOP_FLG) { 1380 ql_delay(ha, 10000); 1381 } 1382 progress &= ~QL_TASK_DAEMON_STARTED; 1383 } 1384 1385 if (progress & QL_IOMAP_IOBASE_MAPPED) { 1386 ddi_regs_map_free(&ha->iomap_dev_handle); 1387 progress &= ~QL_IOMAP_IOBASE_MAPPED; 1388 } 1389 1390 if (progress & QL_CONFIG_SPACE_SETUP) { 1391 if (CFG_IST(ha, CFG_SBUS_CARD)) { 1392 ddi_regs_map_free(&ha->sbus_config_handle); 1393 } else { 1394 pci_config_teardown(&ha->pci_handle); 1395 } 1396 progress &= ~QL_CONFIG_SPACE_SETUP; 1397 } 1398 1399 if (progress & QL_INTR_ADDED) { 1400 ql_disable_intr(ha); 1401 ql_release_intr(ha); 1402 progress &= ~QL_INTR_ADDED; 1403 } 1404 1405 if (progress & QL_MUTEX_CV_INITED) { 1406 ql_destroy_mutex(ha); 1407 progress &= ~QL_MUTEX_CV_INITED; 1408 } 1409 1410 if (progress & QL_HBA_BUFFER_SETUP) { 1411 ql_free_phys(ha, &ha->hba_buf); 1412 progress &= ~QL_HBA_BUFFER_SETUP; 1413 } 1414 1415 if (progress & QL_REGS_MAPPED) { 1416 ddi_regs_map_free(&ha->dev_handle); 1417 if (ha->sbus_fpga_iobase != NULL) { 1418 ddi_regs_map_free(&ha->sbus_fpga_dev_handle); 1419 } 1420 progress &= ~QL_REGS_MAPPED; 1421 } 1422 1423 if (progress & QL_SOFT_STATE_ALLOCED) { 1424 1425 ql_fcache_rel(ha->fcache); 1426 1427 kmem_free(ha->adapter_stats, 1428 sizeof (*ha->adapter_stats)); 1429 1430 kmem_free(ha->ub_array, sizeof (*ha->ub_array) * 1431 QL_UB_LIMIT); 1432 1433 kmem_free(ha->outstanding_cmds, 1434 sizeof (*ha->outstanding_cmds) * 1435 MAX_OUTSTANDING_COMMANDS); 1436 1437 if (ha->devpath != NULL) { 1438 kmem_free(ha->devpath, 1439 strlen(ha->devpath) + 1); 1440 } 1441 1442 kmem_free(ha->dev, sizeof (*ha->dev) * 1443 DEVICE_HEAD_LIST_SIZE); 1444 1445 if (ha->xioctl != NULL) { 1446 ql_free_xioctl_resource(ha); 1447 } 1448 1449 if (ha->fw_module != NULL) { 1450 (void) ddi_modclose(ha->fw_module); 1451 } 1452 1453 ddi_soft_state_free(ql_state, instance); 1454 progress &= ~QL_SOFT_STATE_ALLOCED; 1455 } 1456 1457 ddi_prop_remove_all(dip); 1458 rval = DDI_FAILURE; 1459 break; 1460 1461 case DDI_RESUME: 1462 rval = DDI_FAILURE; 1463 1464 ha = ddi_get_soft_state(ql_state, ddi_get_instance(dip)); 1465 if (ha == NULL) { 1466 cmn_err(CE_WARN, "%s(%d): can't get soft state", 1467 QL_NAME, instance); 1468 break; 1469 } 1470 1471 ha->power_level = PM_LEVEL_D3; 1472 if (ha->pm_capable) { 1473 /* 1474 * Get ql_power to do power on initialization 1475 */ 1476 if (pm_raise_power(dip, QL_POWER_COMPONENT, 1477 PM_LEVEL_D0) != DDI_SUCCESS) { 1478 cmn_err(CE_WARN, "%s(%d): can't raise adapter" 1479 " power", QL_NAME, instance); 1480 } 1481 } 1482 1483 /* 1484 * There is a bug in DR that prevents PM framework 1485 * from calling ql_power. 1486 */ 1487 if (ha->power_level == PM_LEVEL_D3) { 1488 ha->power_level = PM_LEVEL_D0; 1489 1490 if (ql_initialize_adapter(ha) != QL_SUCCESS) { 1491 cmn_err(CE_WARN, "%s(%d): can't initialize the" 1492 " adapter", QL_NAME, instance); 1493 } 1494 1495 /* Wake up task_daemon. */ 1496 ql_awaken_task_daemon(ha, NULL, TASK_DAEMON_ALIVE_FLG, 1497 0); 1498 } 1499 1500 /* Acquire global state lock. */ 1501 GLOBAL_STATE_LOCK(); 1502 1503 /* Restart driver timer. */ 1504 if (ql_timer_timeout_id == NULL) { 1505 ql_timer_timeout_id = timeout(ql_timer, (void *)0, 1506 ql_timer_ticks); 1507 } 1508 1509 /* Release global state lock. */ 1510 GLOBAL_STATE_UNLOCK(); 1511 1512 /* Wake up command start routine. */ 1513 ADAPTER_STATE_LOCK(ha); 1514 ha->flags &= ~ADAPTER_SUSPENDED; 1515 ADAPTER_STATE_UNLOCK(ha); 1516 1517 /* 1518 * Transport doesn't make FC discovery in polled 1519 * mode; So we need the daemon thread's services 1520 * right here. 1521 */ 1522 (void) callb_generic_cpr(&ha->cprinfo, CB_CODE_CPR_RESUME); 1523 1524 rval = DDI_SUCCESS; 1525 1526 /* Restart IP if it was running. */ 1527 if (ha->flags & IP_ENABLED && !(ha->flags & IP_INITIALIZED)) { 1528 (void) ql_initialize_ip(ha); 1529 ql_isp_rcvbuf(ha); 1530 } 1531 break; 1532 1533 default: 1534 cmn_err(CE_WARN, "%s(%d): attach, unknown code:" 1535 " %x", QL_NAME, ddi_get_instance(dip), cmd); 1536 rval = DDI_FAILURE; 1537 break; 1538 } 1539 1540 kmem_free(buf, MAXPATHLEN); 1541 1542 if (rval != DDI_SUCCESS) { 1543 /*EMPTY*/ 1544 QL_PRINT_2(CE_CONT, "(%d): failed, rval = %xh\n", 1545 ddi_get_instance(dip), rval); 1546 } else { 1547 /*EMPTY*/ 1548 QL_PRINT_3(CE_CONT, "(%d): done\n", ddi_get_instance(dip)); 1549 } 1550 1551 return (rval); 1552} 1553 1554/* 1555 * ql_detach 1556 * Used to remove all the states associated with a given 1557 * instances of a device node prior to the removal of that 1558 * instance from the system. 1559 * 1560 * Input: 1561 * dip = pointer to device information structure. 1562 * cmd = type of detach. 1563 * 1564 * Returns: 1565 * DDI_SUCCESS or DDI_FAILURE. 1566 * 1567 * Context: 1568 * Kernel context. 1569 */ 1570static int 1571ql_detach(dev_info_t *dip, ddi_detach_cmd_t cmd) 1572{ 1573 ql_adapter_state_t *ha, *vha; 1574 ql_tgt_t *tq; 1575 int delay_cnt; 1576 uint16_t index; 1577 ql_link_t *link; 1578 char *buf; 1579 timeout_id_t timer_id = NULL; 1580 int suspend, rval = DDI_SUCCESS; 1581 1582 ha = ddi_get_soft_state(ql_state, ddi_get_instance(dip)); 1583 if (ha == NULL) { 1584 QL_PRINT_2(CE_CONT, "(%d): no adapter\n", 1585 ddi_get_instance(dip)); 1586 return (DDI_FAILURE); 1587 } 1588 1589 QL_PRINT_3(CE_CONT, "(%d): started, cmd=%xh\n", ha->instance, cmd); 1590 1591 buf = (char *)(kmem_zalloc(MAXPATHLEN, KM_SLEEP)); 1592 1593 switch (cmd) { 1594 case DDI_DETACH: 1595 ADAPTER_STATE_LOCK(ha); 1596 ha->flags |= (ADAPTER_SUSPENDED | ABORT_CMDS_LOOP_DOWN_TMO); 1597 ADAPTER_STATE_UNLOCK(ha); 1598 1599 TASK_DAEMON_LOCK(ha); 1600 1601 if (ha->task_daemon_flags & TASK_DAEMON_ALIVE_FLG) { 1602 ha->task_daemon_flags |= TASK_DAEMON_STOP_FLG; 1603 cv_signal(&ha->cv_task_daemon); 1604 1605 TASK_DAEMON_UNLOCK(ha); 1606 1607 (void) ql_wait_for_td_stop(ha); 1608 1609 TASK_DAEMON_LOCK(ha); 1610 if (ha->task_daemon_flags & TASK_DAEMON_STOP_FLG) { 1611 ha->task_daemon_flags &= ~TASK_DAEMON_STOP_FLG; 1612 EL(ha, "failed, could not stop task daemon\n"); 1613 } 1614 } 1615 TASK_DAEMON_UNLOCK(ha); 1616 1617 GLOBAL_STATE_LOCK(); 1618 1619 /* Disable driver timer if no adapters. */ 1620 if (ql_timer_timeout_id && ql_hba.first == &ha->hba && 1621 ql_hba.last == &ha->hba) { 1622 timer_id = ql_timer_timeout_id; 1623 ql_timer_timeout_id = NULL; 1624 } 1625 ql_remove_link(&ql_hba, &ha->hba); 1626 1627 GLOBAL_STATE_UNLOCK(); 1628 1629 if (timer_id) { 1630 (void) untimeout(timer_id); 1631 } 1632 1633 if (ha->pm_capable) { 1634 if (pm_lower_power(dip, QL_POWER_COMPONENT, 1635 PM_LEVEL_D3) != DDI_SUCCESS) { 1636 cmn_err(CE_WARN, "%s(%d): failed to lower the" 1637 " power", QL_NAME, ha->instance); 1638 } 1639 } 1640 1641 /* 1642 * If pm_lower_power shutdown the adapter, there 1643 * isn't much else to do 1644 */ 1645 if (ha->power_level != PM_LEVEL_D3) { 1646 ql_halt(ha, PM_LEVEL_D3); 1647 } 1648 1649 /* Remove virtual ports. */ 1650 while ((vha = ha->vp_next) != NULL) { 1651 ql_vport_destroy(vha); 1652 } 1653 1654 /* Free target queues. */ 1655 for (index = 0; index < DEVICE_HEAD_LIST_SIZE; index++) { 1656 link = ha->dev[index].first; 1657 while (link != NULL) { 1658 tq = link->base_address; 1659 link = link->next; 1660 ql_dev_free(ha, tq); 1661 } 1662 } 1663 1664 /* 1665 * Free unsolicited buffers. 1666 * If we are here then there are no ULPs still 1667 * alive that wish to talk to ql so free up 1668 * any SRB_IP_UB_UNUSED buffers that are 1669 * lingering around 1670 */ 1671 QL_UB_LOCK(ha); 1672 for (index = 0; index < QL_UB_LIMIT; index++) { 1673 fc_unsol_buf_t *ubp = ha->ub_array[index]; 1674 1675 if (ubp != NULL) { 1676 ql_srb_t *sp = ubp->ub_fca_private; 1677 1678 sp->flags |= SRB_UB_FREE_REQUESTED; 1679 1680 while (!(sp->flags & SRB_UB_IN_FCA) || 1681 (sp->flags & (SRB_UB_CALLBACK | 1682 SRB_UB_ACQUIRED))) { 1683 QL_UB_UNLOCK(ha); 1684 delay(drv_usectohz(100000)); 1685 QL_UB_LOCK(ha); 1686 } 1687 ha->ub_array[index] = NULL; 1688 1689 QL_UB_UNLOCK(ha); 1690 ql_free_unsolicited_buffer(ha, ubp); 1691 QL_UB_LOCK(ha); 1692 } 1693 } 1694 QL_UB_UNLOCK(ha); 1695 1696 /* Free any saved RISC code. */ 1697 if (ha->risc_code != NULL) { 1698 kmem_free(ha->risc_code, ha->risc_code_size); 1699 ha->risc_code = NULL; 1700 ha->risc_code_size = 0; 1701 } 1702 1703 if (ha->fw_module != NULL) { 1704 (void) ddi_modclose(ha->fw_module); 1705 ha->fw_module = NULL; 1706 } 1707 1708 /* Free resources. */ 1709 ddi_prop_remove_all(dip); 1710 (void) fc_fca_detach(dip); 1711 kmem_free(ha->tran, sizeof (fc_fca_tran_t)); 1712 ddi_remove_minor_node(dip, "devctl"); 1713 if (ha->k_stats != NULL) { 1714 kstat_delete(ha->k_stats); 1715 } 1716 1717 if (CFG_IST(ha, CFG_SBUS_CARD)) { 1718 ddi_regs_map_free(&ha->sbus_config_handle); 1719 } else { 1720 ddi_regs_map_free(&ha->iomap_dev_handle); 1721 pci_config_teardown(&ha->pci_handle); 1722 } 1723 1724 ql_disable_intr(ha); 1725 ql_release_intr(ha); 1726 1727 ql_free_xioctl_resource(ha); 1728 1729 ql_destroy_mutex(ha); 1730 1731 ql_free_phys(ha, &ha->hba_buf); 1732 ql_free_phys(ha, &ha->fwexttracebuf); 1733 ql_free_phys(ha, &ha->fwfcetracebuf); 1734 1735 ddi_regs_map_free(&ha->dev_handle); 1736 if (ha->sbus_fpga_iobase != NULL) { 1737 ddi_regs_map_free(&ha->sbus_fpga_dev_handle); 1738 } 1739 1740 ql_fcache_rel(ha->fcache); 1741 if (ha->vcache != NULL) { 1742 kmem_free(ha->vcache, QL_24XX_VPD_SIZE); 1743 } 1744 1745 if (ha->pi_attrs != NULL) { 1746 kmem_free(ha->pi_attrs, sizeof (fca_port_attrs_t)); 1747 } 1748 1749 kmem_free(ha->adapter_stats, sizeof (*ha->adapter_stats)); 1750 1751 kmem_free(ha->ub_array, sizeof (*ha->ub_array) * QL_UB_LIMIT); 1752 1753 kmem_free(ha->outstanding_cmds, 1754 sizeof (*ha->outstanding_cmds) * MAX_OUTSTANDING_COMMANDS); 1755 1756 if (ha->n_port != NULL) { 1757 kmem_free(ha->n_port, sizeof (ql_n_port_info_t)); 1758 } 1759 1760 if (ha->devpath != NULL) { 1761 kmem_free(ha->devpath, strlen(ha->devpath) + 1); 1762 } 1763 1764 kmem_free(ha->dev, sizeof (*ha->dev) * DEVICE_HEAD_LIST_SIZE); 1765 1766 EL(ha, "detached\n"); 1767 1768 ddi_soft_state_free(ql_state, (int)ha->instance); 1769 1770 break; 1771 1772 case DDI_SUSPEND: 1773 ADAPTER_STATE_LOCK(ha); 1774 1775 delay_cnt = 0; 1776 ha->flags |= ADAPTER_SUSPENDED; 1777 while (ha->flags & ADAPTER_TIMER_BUSY && delay_cnt++ < 10) { 1778 ADAPTER_STATE_UNLOCK(ha); 1779 delay(drv_usectohz(1000000)); 1780 ADAPTER_STATE_LOCK(ha); 1781 } 1782 if (ha->busy || ha->flags & ADAPTER_TIMER_BUSY) { 1783 ha->flags &= ~ADAPTER_SUSPENDED; 1784 ADAPTER_STATE_UNLOCK(ha); 1785 rval = DDI_FAILURE; 1786 cmn_err(CE_WARN, "!%s(%d): Fail suspend" 1787 " busy %xh flags %xh", QL_NAME, ha->instance, 1788 ha->busy, ha->flags); 1789 break; 1790 } 1791 1792 ADAPTER_STATE_UNLOCK(ha); 1793 1794 if (ha->flags & IP_INITIALIZED) { 1795 (void) ql_shutdown_ip(ha); 1796 } 1797 1798 if ((suspend = ql_suspend_adapter(ha)) != QL_SUCCESS) { 1799 ADAPTER_STATE_LOCK(ha); 1800 ha->flags &= ~ADAPTER_SUSPENDED; 1801 ADAPTER_STATE_UNLOCK(ha); 1802 cmn_err(CE_WARN, "%s(%d): Fail suspend rval %xh", 1803 QL_NAME, ha->instance, suspend); 1804 1805 /* Restart IP if it was running. */ 1806 if (ha->flags & IP_ENABLED && 1807 !(ha->flags & IP_INITIALIZED)) { 1808 (void) ql_initialize_ip(ha); 1809 ql_isp_rcvbuf(ha); 1810 } 1811 rval = DDI_FAILURE; 1812 break; 1813 } 1814 1815 /* Acquire global state lock. */ 1816 GLOBAL_STATE_LOCK(); 1817 1818 /* Disable driver timer if last adapter. */ 1819 if (ql_timer_timeout_id && ql_hba.first == &ha->hba && 1820 ql_hba.last == &ha->hba) { 1821 timer_id = ql_timer_timeout_id; 1822 ql_timer_timeout_id = NULL; 1823 } 1824 GLOBAL_STATE_UNLOCK(); 1825 1826 if (timer_id) { 1827 (void) untimeout(timer_id); 1828 } 1829 1830 EL(ha, "suspended\n"); 1831 1832 break; 1833 1834 default: 1835 rval = DDI_FAILURE; 1836 break; 1837 } 1838 1839 kmem_free(buf, MAXPATHLEN); 1840 1841 if (rval != DDI_SUCCESS) { 1842 if (ha != NULL) { 1843 EL(ha, "failed, rval = %xh\n", rval); 1844 } else { 1845 /*EMPTY*/ 1846 QL_PRINT_2(CE_CONT, "(%d): failed, rval = %xh\n", 1847 ddi_get_instance(dip), rval); 1848 } 1849 } else { 1850 /*EMPTY*/ 1851 QL_PRINT_3(CE_CONT, "(%d): done\n", ddi_get_instance(dip)); 1852 } 1853 1854 return (rval); 1855} 1856 1857 1858/* 1859 * ql_power 1860 * Power a device attached to the system. 1861 * 1862 * Input: 1863 * dip = pointer to device information structure. 1864 * component = device. 1865 * level = power level. 1866 * 1867 * Returns: 1868 * DDI_SUCCESS or DDI_FAILURE. 1869 * 1870 * Context: 1871 * Kernel context. 1872 */ 1873/* ARGSUSED */ 1874static int 1875ql_power(dev_info_t *dip, int component, int level) 1876{ 1877 int rval = DDI_FAILURE; 1878 off_t csr; 1879 uint8_t saved_pm_val; 1880 ql_adapter_state_t *ha; 1881 char *buf; 1882 char *path; 1883 1884 ha = ddi_get_soft_state(ql_state, ddi_get_instance(dip)); 1885 if (ha == NULL || ha->pm_capable == 0) { 1886 QL_PRINT_2(CE_CONT, "(%d): no hba or PM not supported\n", 1887 ddi_get_instance(dip)); 1888 return (rval); 1889 } 1890 1891 QL_PRINT_10(CE_CONT, "(%d,%d): started\n", ha->instance, ha->vp_index); 1892 1893 buf = (char *)(kmem_zalloc(MAXPATHLEN, KM_SLEEP)); 1894 path = (char *)(kmem_zalloc(MAXPATHLEN, KM_SLEEP)); 1895 1896 if (component != QL_POWER_COMPONENT || (level != PM_LEVEL_D0 && 1897 level != PM_LEVEL_D3)) { 1898 EL(ha, "invalid, component=%xh or level=%xh\n", 1899 component, level); 1900 return (rval); 1901 } 1902 1903 GLOBAL_HW_LOCK(); 1904 csr = (uint8_t)ql_pci_config_get8(ha, PCI_CONF_CAP_PTR) + PCI_PMCSR; 1905 GLOBAL_HW_UNLOCK(); 1906 1907 (void) snprintf(buf, sizeof (buf), 1908 "Qlogic %s(%d): %s\n\t", QL_NAME, ddi_get_instance(dip), 1909 ddi_pathname(dip, path)); 1910 1911 switch (level) { 1912 case PM_LEVEL_D0: /* power up to D0 state - fully on */ 1913 1914 QL_PM_LOCK(ha); 1915 if (ha->power_level == PM_LEVEL_D0) { 1916 QL_PM_UNLOCK(ha); 1917 rval = DDI_SUCCESS; 1918 break; 1919 } 1920 1921 /* 1922 * Enable interrupts now 1923 */ 1924 saved_pm_val = ha->power_level; 1925 ha->power_level = PM_LEVEL_D0; 1926 QL_PM_UNLOCK(ha); 1927 1928 GLOBAL_HW_LOCK(); 1929 1930 ql_pci_config_put16(ha, csr, PCI_PMCSR_D0); 1931 1932 /* 1933 * Delay after reset, for chip to recover. 1934 * Otherwise causes system PANIC 1935 */ 1936 drv_usecwait(200000); 1937 1938 GLOBAL_HW_UNLOCK(); 1939 1940 if (ha->config_saved) { 1941 ha->config_saved = 0; 1942 if (QL_RESTORE_CONFIG_REGS(dip) != DDI_SUCCESS) { 1943 QL_PM_LOCK(ha); 1944 ha->power_level = saved_pm_val; 1945 QL_PM_UNLOCK(ha); 1946 cmn_err(CE_WARN, "%s failed to restore " 1947 "config regs", buf); 1948 break; 1949 } 1950 } 1951 1952 if (ql_initialize_adapter(ha) != QL_SUCCESS) { 1953 cmn_err(CE_WARN, "%s adapter initialization failed", 1954 buf); 1955 } 1956 1957 /* Wake up task_daemon. */ 1958 ql_awaken_task_daemon(ha, NULL, TASK_DAEMON_ALIVE_FLG | 1959 TASK_DAEMON_SLEEPING_FLG, 0); 1960 1961 /* Restart IP if it was running. */ 1962 if (ha->flags & IP_ENABLED && !(ha->flags & IP_INITIALIZED)) { 1963 (void) ql_initialize_ip(ha); 1964 ql_isp_rcvbuf(ha); 1965 } 1966 1967 cmn_err(CE_NOTE, QL_BANG "ql_power(%d): %s is powered ON\n", 1968 ha->instance, QL_NAME); 1969 1970 rval = DDI_SUCCESS; 1971 break; 1972 1973 case PM_LEVEL_D3: /* power down to D3 state - off */ 1974 1975 QL_PM_LOCK(ha); 1976 1977 if (ha->busy || ((ha->task_daemon_flags & 1978 TASK_DAEMON_SLEEPING_FLG) == 0)) { 1979 QL_PM_UNLOCK(ha); 1980 break; 1981 } 1982 1983 if (ha->power_level == PM_LEVEL_D3) { 1984 rval = DDI_SUCCESS; 1985 QL_PM_UNLOCK(ha); 1986 break; 1987 } 1988 QL_PM_UNLOCK(ha); 1989 1990 if (QL_SAVE_CONFIG_REGS(dip) != DDI_SUCCESS) { 1991 cmn_err(CE_WARN, "!Qlogic %s(%d): %s failed to save" 1992 " config regs", QL_NAME, ha->instance, buf); 1993 break; 1994 } 1995 ha->config_saved = 1; 1996 1997 /* 1998 * Don't enable interrupts. Running mailbox commands with 1999 * interrupts enabled could cause hangs since pm_run_scan() 2000 * runs out of a callout thread and on single cpu systems 2001 * cv_timedwait(), called from ql_mailbox_command(), would 2002 * not get to run. 2003 */ 2004 TASK_DAEMON_LOCK(ha); 2005 ha->task_daemon_flags |= TASK_DAEMON_POWERING_DOWN; 2006 TASK_DAEMON_UNLOCK(ha); 2007 2008 ql_halt(ha, PM_LEVEL_D3); 2009 2010 /* 2011 * Setup ql_intr to ignore interrupts from here on. 2012 */ 2013 QL_PM_LOCK(ha); 2014 ha->power_level = PM_LEVEL_D3; 2015 QL_PM_UNLOCK(ha); 2016 2017 /* 2018 * Wait for ISR to complete. 2019 */ 2020 INTR_LOCK(ha); 2021 ql_pci_config_put16(ha, csr, PCI_PMCSR_D3HOT); 2022 INTR_UNLOCK(ha); 2023 2024 cmn_err(CE_NOTE, QL_BANG "ql_power(%d): %s is powered OFF\n", 2025 ha->instance, QL_NAME); 2026 2027 rval = DDI_SUCCESS; 2028 break; 2029 } 2030 2031 kmem_free(buf, MAXPATHLEN); 2032 kmem_free(path, MAXPATHLEN); 2033 2034 QL_PRINT_10(CE_CONT, "(%d,%d): done\n", ha->instance, ha->vp_index); 2035 2036 return (rval); 2037} 2038 2039/* 2040 * ql_quiesce 2041 * quiesce a device attached to the system. 2042 * 2043 * Input: 2044 * dip = pointer to device information structure. 2045 * 2046 * Returns: 2047 * DDI_SUCCESS 2048 * 2049 * Context: 2050 * Kernel context. 2051 */ 2052static int 2053ql_quiesce(dev_info_t *dip) 2054{ 2055 ql_adapter_state_t *ha; 2056 uint32_t timer; 2057 uint32_t stat; 2058 2059 ha = ddi_get_soft_state(ql_state, ddi_get_instance(dip)); 2060 if (ha == NULL) { 2061 /* Oh well.... */ 2062 QL_PRINT_2(CE_CONT, "(%d): no adapter\n", 2063 ddi_get_instance(dip)); 2064 return (DDI_SUCCESS); 2065 } 2066 2067 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance); 2068 2069 if (CFG_IST(ha, CFG_CTRL_242581)) { 2070 WRT32_IO_REG(ha, hccr, HC24_CLR_RISC_INT); 2071 WRT16_IO_REG(ha, mailbox[0], MBC_STOP_FIRMWARE); 2072 WRT32_IO_REG(ha, hccr, HC24_SET_HOST_INT); 2073 for (timer = 0; timer < 30000; timer++) { 2074 stat = RD32_IO_REG(ha, intr_info_lo); 2075 if (stat & BIT_15) { 2076 if ((stat & 0xff) < 0x12) { 2077 WRT32_IO_REG(ha, hccr, 2078 HC24_CLR_RISC_INT); 2079 break; 2080 } 2081 WRT32_IO_REG(ha, hccr, HC24_CLR_RISC_INT); 2082 } 2083 drv_usecwait(100); 2084 } 2085 /* Reset the chip. */ 2086 WRT32_IO_REG(ha, ctrl_status, ISP_RESET | DMA_SHUTDOWN | 2087 MWB_4096_BYTES); 2088 drv_usecwait(100); 2089 2090 } else { 2091 /* Disable ISP interrupts. */ 2092 WRT16_IO_REG(ha, ictrl, 0); 2093 /* Select RISC module registers. */ 2094 WRT16_IO_REG(ha, ctrl_status, 0); 2095 /* Reset ISP semaphore. */ 2096 WRT16_IO_REG(ha, semaphore, 0); 2097 /* Reset RISC module. */ 2098 WRT16_IO_REG(ha, hccr, HC_RESET_RISC); 2099 /* Release RISC module. */ 2100 WRT16_IO_REG(ha, hccr, HC_RELEASE_RISC); 2101 } 2102 2103 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance); 2104 2105 return (DDI_SUCCESS); 2106} 2107 2108/* ************************************************************************ */ 2109/* Fibre Channel Adapter (FCA) Transport Functions. */ 2110/* ************************************************************************ */ 2111 2112/* 2113 * ql_bind_port 2114 * Handling port binding. The FC Transport attempts to bind an FCA port 2115 * when it is ready to start transactions on the port. The FC Transport 2116 * will call the fca_bind_port() function specified in the fca_transport 2117 * structure it receives. The FCA must fill in the port_info structure 2118 * passed in the call and also stash the information for future calls. 2119 * 2120 * Input: 2121 * dip = pointer to FCA information structure. 2122 * port_info = pointer to port information structure. 2123 * bind_info = pointer to bind information structure. 2124 * 2125 * Returns: 2126 * NULL = failure 2127 * 2128 * Context: 2129 * Kernel context. 2130 */ 2131static opaque_t 2132ql_bind_port(dev_info_t *dip, fc_fca_port_info_t *port_info, 2133 fc_fca_bind_info_t *bind_info) 2134{ 2135 ql_adapter_state_t *ha, *vha; 2136 opaque_t fca_handle = NULL; 2137 port_id_t d_id; 2138 int port_npiv = bind_info->port_npiv; 2139 uchar_t *port_nwwn = bind_info->port_nwwn.raw_wwn; 2140 uchar_t *port_pwwn = bind_info->port_pwwn.raw_wwn; 2141 2142 /* get state info based on the dip */ 2143 ha = ddi_get_soft_state(ql_state, ddi_get_instance(dip)); 2144 if (ha == NULL) { 2145 QL_PRINT_2(CE_CONT, "(%d): no adapter\n", 2146 ddi_get_instance(dip)); 2147 return (NULL); 2148 } 2149 QL_PRINT_10(CE_CONT, "(%d,%d): started\n", ha->instance, ha->vp_index); 2150 2151 /* Verify port number is supported. */ 2152 if (port_npiv != 0) { 2153 if (!(ha->flags & VP_ENABLED)) { 2154 QL_PRINT_2(CE_CONT, "(%d): FC_NPIV_NOT_SUPPORTED\n", 2155 ha->instance); 2156 port_info->pi_error = FC_NPIV_NOT_SUPPORTED; 2157 return (NULL); 2158 } 2159 if (!(ha->flags & POINT_TO_POINT)) { 2160 QL_PRINT_2(CE_CONT, "(%d): FC_NPIV_WRONG_TOPOLOGY\n", 2161 ha->instance); 2162 port_info->pi_error = FC_NPIV_WRONG_TOPOLOGY; 2163 return (NULL); 2164 } 2165 if (!(ha->flags & FDISC_ENABLED)) { 2166 QL_PRINT_2(CE_CONT, "(%d): switch does not support " 2167 "FDISC\n", ha->instance); 2168 port_info->pi_error = FC_NPIV_FDISC_FAILED; 2169 return (NULL); 2170 } 2171 if (bind_info->port_num > (CFG_IST(ha, CFG_CTRL_2422) ? 2172 MAX_24_VIRTUAL_PORTS : MAX_25_VIRTUAL_PORTS)) { 2173 QL_PRINT_2(CE_CONT, "(%d): port number=%d " 2174 "FC_OUTOFBOUNDS\n", ha->instance); 2175 port_info->pi_error = FC_OUTOFBOUNDS; 2176 return (NULL); 2177 } 2178 } else if (bind_info->port_num != 0) { 2179 QL_PRINT_2(CE_CONT, "(%d): failed, port number=%d is not " 2180 "supported\n", ha->instance, bind_info->port_num); 2181 port_info->pi_error = FC_OUTOFBOUNDS; 2182 return (NULL); 2183 } 2184 2185 /* Locate port context. */ 2186 for (vha = ha; vha != NULL; vha = vha->vp_next) { 2187 if (vha->vp_index == bind_info->port_num) { 2188 break; 2189 } 2190 } 2191 2192 /* If virtual port does not exist. */ 2193 if (vha == NULL) { 2194 vha = ql_vport_create(ha, (uint8_t)bind_info->port_num); 2195 } 2196 2197 /* make sure this port isn't already bound */ 2198 if (vha->flags & FCA_BOUND) { 2199 port_info->pi_error = FC_ALREADY; 2200 } else { 2201 if (vha->vp_index != 0) { 2202 bcopy(port_nwwn, 2203 vha->loginparams.node_ww_name.raw_wwn, 8); 2204 bcopy(port_pwwn, 2205 vha->loginparams.nport_ww_name.raw_wwn, 8); 2206 } 2207 if (vha->vp_index != 0 && !(vha->flags & VP_ENABLED)) { 2208 if (ql_vport_enable(vha) != QL_SUCCESS) { 2209 QL_PRINT_2(CE_CONT, "(%d): failed to enable " 2210 "virtual port=%d\n", ha->instance, 2211 vha->vp_index); 2212 port_info->pi_error = FC_NPIV_FDISC_FAILED; 2213 return (NULL); 2214 } 2215 cmn_err(CE_CONT, "!Qlogic %s(%d) NPIV(%d) " 2216 "WWPN=%02x%02x%02x%02x%02x%02x%02x%02x : " 2217 "WWNN=%02x%02x%02x%02x%02x%02x%02x%02x\n", 2218 QL_NAME, ha->instance, vha->vp_index, 2219 port_pwwn[0], port_pwwn[1], port_pwwn[2], 2220 port_pwwn[3], port_pwwn[4], port_pwwn[5], 2221 port_pwwn[6], port_pwwn[7], 2222 port_nwwn[0], port_nwwn[1], port_nwwn[2], 2223 port_nwwn[3], port_nwwn[4], port_nwwn[5], 2224 port_nwwn[6], port_nwwn[7]); 2225 } 2226 2227 /* stash the bind_info supplied by the FC Transport */ 2228 vha->bind_info.port_handle = bind_info->port_handle; 2229 vha->bind_info.port_statec_cb = 2230 bind_info->port_statec_cb; 2231 vha->bind_info.port_unsol_cb = bind_info->port_unsol_cb; 2232 2233 /* Set port's source ID. */ 2234 port_info->pi_s_id.port_id = vha->d_id.b24; 2235 2236 /* copy out the default login parameters */ 2237 bcopy((void *)&vha->loginparams, 2238 (void *)&port_info->pi_login_params, 2239 sizeof (la_els_logi_t)); 2240 2241 /* Set port's hard address if enabled. */ 2242 port_info->pi_hard_addr.hard_addr = 0; 2243 if (bind_info->port_num == 0) { 2244 d_id.b24 = ha->d_id.b24; 2245 if (CFG_IST(ha, CFG_CTRL_242581)) { 2246 if (ha->init_ctrl_blk.cb24. 2247 firmware_options_1[0] & BIT_0) { 2248 d_id.b.al_pa = ql_index_to_alpa[ha-> 2249 init_ctrl_blk.cb24. 2250 hard_address[0]]; 2251 port_info->pi_hard_addr.hard_addr = 2252 d_id.b24; 2253 } 2254 } else if (ha->init_ctrl_blk.cb.firmware_options[0] & 2255 BIT_0) { 2256 d_id.b.al_pa = ql_index_to_alpa[ha-> 2257 init_ctrl_blk.cb.hard_address[0]]; 2258 port_info->pi_hard_addr.hard_addr = d_id.b24; 2259 } 2260 2261 /* Set the node id data */ 2262 if (ql_get_rnid_params(ha, 2263 sizeof (port_info->pi_rnid_params.params), 2264 (caddr_t)&port_info->pi_rnid_params.params) == 2265 QL_SUCCESS) { 2266 port_info->pi_rnid_params.status = FC_SUCCESS; 2267 } else { 2268 port_info->pi_rnid_params.status = FC_FAILURE; 2269 } 2270 2271 /* Populate T11 FC-HBA details */ 2272 ql_populate_hba_fru_details(ha, port_info); 2273 ha->pi_attrs = kmem_zalloc(sizeof (fca_port_attrs_t), 2274 KM_SLEEP); 2275 if (ha->pi_attrs != NULL) { 2276 bcopy(&port_info->pi_attrs, ha->pi_attrs, 2277 sizeof (fca_port_attrs_t)); 2278 } 2279 } else { 2280 port_info->pi_rnid_params.status = FC_FAILURE; 2281 if (ha->pi_attrs != NULL) { 2282 bcopy(ha->pi_attrs, &port_info->pi_attrs, 2283 sizeof (fca_port_attrs_t)); 2284 } 2285 } 2286 2287 /* Generate handle for this FCA. */ 2288 fca_handle = (opaque_t)vha; 2289 2290 ADAPTER_STATE_LOCK(ha); 2291 vha->flags |= FCA_BOUND; 2292 ADAPTER_STATE_UNLOCK(ha); 2293 /* Set port's current state. */ 2294 port_info->pi_port_state = vha->state; 2295 } 2296 2297 QL_PRINT_10(CE_CONT, "(%d,%d): done, pi_port_state=%xh, " 2298 "pi_s_id.port_id=%xh\n", ha->instance, ha->vp_index, 2299 port_info->pi_port_state, port_info->pi_s_id.port_id); 2300 2301 return (fca_handle); 2302} 2303 2304/* 2305 * ql_unbind_port 2306 * To unbind a Fibre Channel Adapter from an FC Port driver. 2307 * 2308 * Input: 2309 * fca_handle = handle setup by ql_bind_port(). 2310 * 2311 * Context: 2312 * Kernel context. 2313 */ 2314static void 2315ql_unbind_port(opaque_t fca_handle) 2316{ 2317 ql_adapter_state_t *ha; 2318 ql_tgt_t *tq; 2319 uint32_t flgs; 2320 2321 ha = ql_fca_handle_to_state(fca_handle); 2322 if (ha == NULL) { 2323 /*EMPTY*/ 2324 QL_PRINT_2(CE_CONT, "failed, no adapter=%ph\n", 2325 (void *)fca_handle); 2326 } else { 2327 QL_PRINT_10(CE_CONT, "(%d,%d): started\n", ha->instance, 2328 ha->vp_index); 2329 2330 if (!(ha->flags & FCA_BOUND)) { 2331 /*EMPTY*/ 2332 QL_PRINT_2(CE_CONT, "(%d): port=%d already unbound\n", 2333 ha->instance, ha->vp_index); 2334 } else { 2335 if (ha->vp_index != 0 && ha->flags & VP_ENABLED) { 2336 if ((tq = ql_loop_id_to_queue(ha, 2337 FL_PORT_24XX_HDL)) != NULL) { 2338 (void) ql_logout_fabric_port(ha, tq); 2339 } 2340 (void) ql_vport_control(ha, (uint8_t) 2341 (CFG_IST(ha, CFG_CTRL_2425) ? 2342 VPC_DISABLE_INIT : VPC_DISABLE_LOGOUT)); 2343 flgs = FCA_BOUND | VP_ENABLED; 2344 } else { 2345 flgs = FCA_BOUND; 2346 } 2347 ADAPTER_STATE_LOCK(ha); 2348 ha->flags &= ~flgs; 2349 ADAPTER_STATE_UNLOCK(ha); 2350 } 2351 2352 QL_PRINT_10(CE_CONT, "(%d,%d): done\n", ha->instance, 2353 ha->vp_index); 2354 } 2355} 2356 2357/* 2358 * ql_init_pkt 2359 * Initialize FCA portion of packet. 2360 * 2361 * Input: 2362 * fca_handle = handle setup by ql_bind_port(). 2363 * pkt = pointer to fc_packet. 2364 * 2365 * Returns: 2366 * FC_SUCCESS - the packet has successfully been initialized. 2367 * FC_UNBOUND - the fca_handle specified is not bound. 2368 * FC_NOMEM - the FCA failed initialization due to an allocation error. 2369 * FC_FAILURE - the FCA failed initialization for undisclosed reasons 2370 * 2371 * Context: 2372 * Kernel context. 2373 */ 2374/* ARGSUSED */ 2375static int 2376ql_init_pkt(opaque_t fca_handle, fc_packet_t *pkt, int sleep) 2377{ 2378 ql_adapter_state_t *ha; 2379 ql_srb_t *sp; 2380 2381 ha = ql_fca_handle_to_state(fca_handle); 2382 if (ha == NULL) { 2383 QL_PRINT_2(CE_CONT, "failed, no adapter=%ph\n", 2384 (void *)fca_handle); 2385 return (FC_UNBOUND); 2386 } 2387 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance); 2388 2389 sp = (ql_srb_t *)pkt->pkt_fca_private; 2390 sp->flags = 0; 2391 2392 /* init cmd links */ 2393 sp->cmd.base_address = sp; 2394 sp->cmd.prev = NULL; 2395 sp->cmd.next = NULL; 2396 sp->cmd.head = NULL; 2397 2398 /* init watchdog links */ 2399 sp->wdg.base_address = sp; 2400 sp->wdg.prev = NULL; 2401 sp->wdg.next = NULL; 2402 sp->wdg.head = NULL; 2403 sp->pkt = pkt; 2404 sp->ha = ha; 2405 sp->magic_number = QL_FCA_BRAND; 2406 2407 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance); 2408 2409 return (FC_SUCCESS); 2410} 2411 2412/* 2413 * ql_un_init_pkt 2414 * Release all local resources bound to packet. 2415 * 2416 * Input: 2417 * fca_handle = handle setup by ql_bind_port(). 2418 * pkt = pointer to fc_packet. 2419 * 2420 * Returns: 2421 * FC_SUCCESS - the packet has successfully been invalidated. 2422 * FC_UNBOUND - the fca_handle specified is not bound. 2423 * FC_BADPACKET - the packet has not been initialized or has 2424 * already been freed by this FCA. 2425 * 2426 * Context: 2427 * Kernel context. 2428 */ 2429static int 2430ql_un_init_pkt(opaque_t fca_handle, fc_packet_t *pkt) 2431{ 2432 ql_adapter_state_t *ha; 2433 int rval; 2434 ql_srb_t *sp; 2435 2436 ha = ql_fca_handle_to_state(fca_handle); 2437 if (ha == NULL) { 2438 QL_PRINT_2(CE_CONT, "failed, no adapter=%ph\n", 2439 (void *)fca_handle); 2440 return (FC_UNBOUND); 2441 } 2442 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance); 2443 2444 sp = (ql_srb_t *)pkt->pkt_fca_private; 2445 2446 if (sp->magic_number != QL_FCA_BRAND) { 2447 EL(ha, "failed, FC_BADPACKET\n"); 2448 rval = FC_BADPACKET; 2449 } else { 2450 sp->magic_number = NULL; 2451 2452 rval = FC_SUCCESS; 2453 } 2454 2455 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance); 2456 2457 return (rval); 2458} 2459 2460/* 2461 * ql_els_send 2462 * Issue a extended link service request. 2463 * 2464 * Input: 2465 * fca_handle = handle setup by ql_bind_port(). 2466 * pkt = pointer to fc_packet. 2467 * 2468 * Returns: 2469 * FC_SUCCESS - the command was successful. 2470 * FC_ELS_FREJECT - the command was rejected by a Fabric. 2471 * FC_ELS_PREJECT - the command was rejected by an N-port. 2472 * FC_TRANSPORT_ERROR - a transport error occurred. 2473 * FC_UNBOUND - the fca_handle specified is not bound. 2474 * FC_ELS_BAD - the FCA can not issue the requested ELS. 2475 * 2476 * Context: 2477 * Kernel context. 2478 */ 2479static int 2480ql_els_send(opaque_t fca_handle, fc_packet_t *pkt) 2481{ 2482 ql_adapter_state_t *ha; 2483 int rval; 2484 clock_t timer; 2485 ls_code_t els; 2486 la_els_rjt_t rjt; 2487 ql_srb_t *sp = (ql_srb_t *)pkt->pkt_fca_private; 2488 2489 /* Verify proper command. */ 2490 ha = ql_cmd_setup(fca_handle, pkt, &rval); 2491 if (ha == NULL) { 2492 QL_PRINT_2(CE_CONT, "failed, ql_cmd_setup=%xh, fcah=%ph\n", 2493 rval, fca_handle); 2494 return (FC_INVALID_REQUEST); 2495 } 2496 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance); 2497 2498 /* Wait for suspension to end. */ 2499 TASK_DAEMON_LOCK(ha); 2500 while (ha->task_daemon_flags & QL_SUSPENDED) { 2501 ha->task_daemon_flags |= SUSPENDED_WAKEUP_FLG; 2502 2503 /* 30 seconds from now */ 2504 timer = ddi_get_lbolt(); 2505 timer += drv_usectohz(30000000); 2506 2507 if (cv_timedwait(&ha->pha->cv_dr_suspended, 2508 &ha->pha->task_daemon_mutex, timer) == -1) { 2509 /* 2510 * The timeout time 'timer' was 2511 * reached without the condition 2512 * being signaled. 2513 */ 2514 pkt->pkt_state = FC_PKT_TRAN_BSY; 2515 pkt->pkt_reason = FC_REASON_XCHG_BSY; 2516 2517 /* Release task daemon lock. */ 2518 TASK_DAEMON_UNLOCK(ha); 2519 2520 EL(ha, "QL_SUSPENDED failed=%xh\n", 2521 QL_FUNCTION_TIMEOUT); 2522 return (FC_TRAN_BUSY); 2523 } 2524 } 2525 /* Release task daemon lock. */ 2526 TASK_DAEMON_UNLOCK(ha); 2527 2528 /* Setup response header. */ 2529 bcopy((void *)&pkt->pkt_cmd_fhdr, (void *)&pkt->pkt_resp_fhdr, 2530 sizeof (fc_frame_hdr_t)); 2531 2532 if (pkt->pkt_rsplen) { 2533 bzero((void *)pkt->pkt_resp, pkt->pkt_rsplen); 2534 } 2535 2536 pkt->pkt_resp_fhdr.d_id = ha->d_id.b24; 2537 pkt->pkt_resp_fhdr.s_id = pkt->pkt_cmd_fhdr.d_id; 2538 pkt->pkt_resp_fhdr.r_ctl = R_CTL_EXTENDED_SVC | 2539 R_CTL_SOLICITED_CONTROL; 2540 pkt->pkt_resp_fhdr.f_ctl = F_CTL_XCHG_CONTEXT | F_CTL_LAST_SEQ | 2541 F_CTL_END_SEQ; 2542 2543 sp->flags &= ~(SRB_UB_CALLBACK | SRB_UB_RSCN | SRB_UB_FCP | 2544 SRB_FCP_CMD_PKT | SRB_FCP_DATA_PKT | SRB_FCP_RSP_PKT | 2545 SRB_IP_PKT | SRB_COMMAND_TIMEOUT | SRB_UB_ACQUIRED | SRB_MS_PKT); 2546 2547 sp->flags |= SRB_ELS_PKT; 2548 2549 /* map the type of ELS to a function */ 2550 ddi_rep_get8(pkt->pkt_cmd_acc, (uint8_t *)&els, 2551 (uint8_t *)pkt->pkt_cmd, sizeof (els), DDI_DEV_AUTOINCR); 2552 2553#if 0 2554 QL_PRINT_3(CE_CONT, "(%d): command fhdr:\n", ha->instance); 2555 QL_DUMP_3((uint8_t *)&pkt->pkt_cmd_fhdr, 32, 2556 sizeof (fc_frame_hdr_t) / 4); 2557 QL_PRINT_3(CE_CONT, "(%d): command:\n", ha->instance); 2558 QL_DUMP_3((uint8_t *)&els, 32, sizeof (els) / 4); 2559#endif 2560 2561 sp->iocb = ha->els_cmd; 2562 sp->req_cnt = 1; 2563 2564 switch (els.ls_code) { 2565 case LA_ELS_RJT: 2566 case LA_ELS_ACC: 2567 EL(ha, "LA_ELS_RJT\n"); 2568 pkt->pkt_state = FC_PKT_SUCCESS; 2569 rval = FC_SUCCESS; 2570 break; 2571 case LA_ELS_PLOGI: 2572 case LA_ELS_PDISC: 2573 rval = ql_els_plogi(ha, pkt); 2574 break; 2575 case LA_ELS_FLOGI: 2576 case LA_ELS_FDISC: 2577 rval = ql_els_flogi(ha, pkt); 2578 break; 2579 case LA_ELS_LOGO: 2580 rval = ql_els_logo(ha, pkt); 2581 break; 2582 case LA_ELS_PRLI: 2583 rval = ql_els_prli(ha, pkt); 2584 break; 2585 case LA_ELS_PRLO: 2586 rval = ql_els_prlo(ha, pkt); 2587 break; 2588 case LA_ELS_ADISC: 2589 rval = ql_els_adisc(ha, pkt); 2590 break; 2591 case LA_ELS_LINIT: 2592 rval = ql_els_linit(ha, pkt); 2593 break; 2594 case LA_ELS_LPC: 2595 rval = ql_els_lpc(ha, pkt); 2596 break; 2597 case LA_ELS_LSTS: 2598 rval = ql_els_lsts(ha, pkt); 2599 break; 2600 case LA_ELS_SCR: 2601 rval = ql_els_scr(ha, pkt); 2602 break; 2603 case LA_ELS_RSCN: 2604 rval = ql_els_rscn(ha, pkt); 2605 break; 2606 case LA_ELS_FARP_REQ: 2607 rval = ql_els_farp_req(ha, pkt); 2608 break; 2609 case LA_ELS_FARP_REPLY: 2610 rval = ql_els_farp_reply(ha, pkt); 2611 break; 2612 case LA_ELS_RLS: 2613 rval = ql_els_rls(ha, pkt); 2614 break; 2615 case LA_ELS_RNID: 2616 rval = ql_els_rnid(ha, pkt); 2617 break; 2618 default: 2619 EL(ha, "LA_ELS_RJT, FC_REASON_CMD_UNSUPPORTED=%xh\n", 2620 els.ls_code); 2621 /* Build RJT. */ 2622 bzero(&rjt, sizeof (rjt)); 2623 rjt.ls_code.ls_code = LA_ELS_RJT; 2624 rjt.reason = FC_REASON_CMD_UNSUPPORTED; 2625 2626 ddi_rep_put8(pkt->pkt_resp_acc, (uint8_t *)&rjt, 2627 (uint8_t *)pkt->pkt_resp, sizeof (rjt), DDI_DEV_AUTOINCR); 2628 2629 pkt->pkt_state = FC_PKT_LOCAL_RJT; 2630 pkt->pkt_reason = FC_REASON_UNSUPPORTED; 2631 rval = FC_SUCCESS; 2632 break; 2633 } 2634 2635#if 0 2636 QL_PRINT_3(CE_CONT, "(%d): response fhdr:\n", ha->instance); 2637 QL_DUMP_3((uint8_t *)&pkt->pkt_resp_fhdr, 32, 2638 sizeof (fc_frame_hdr_t) / 4); 2639#endif 2640 /* 2641 * Return success if the srb was consumed by an iocb. The packet 2642 * completion callback will be invoked by the response handler. 2643 */ 2644 if (rval == QL_CONSUMED) { 2645 rval = FC_SUCCESS; 2646 } else if (rval == FC_SUCCESS && 2647 !(pkt->pkt_tran_flags & FC_TRAN_NO_INTR) && pkt->pkt_comp) { 2648 /* Do command callback only if no error */ 2649 ql_awaken_task_daemon(ha, sp, 0, 0); 2650 } 2651 2652 if (rval != FC_SUCCESS) { 2653 EL(ha, "failed, rval = %xh\n", rval); 2654 } else { 2655 /*EMPTY*/ 2656 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance); 2657 } 2658 return (rval); 2659} 2660 2661/* 2662 * ql_get_cap 2663 * Export FCA hardware and software capabilities. 2664 * 2665 * Input: 2666 * fca_handle = handle setup by ql_bind_port(). 2667 * cap = pointer to the capabilities string. 2668 * ptr = buffer pointer for return capability. 2669 * 2670 * Returns: 2671 * FC_CAP_ERROR - no such capability 2672 * FC_CAP_FOUND - the capability was returned and cannot be set 2673 * FC_CAP_SETTABLE - the capability was returned and can be set 2674 * FC_UNBOUND - the fca_handle specified is not bound. 2675 * 2676 * Context: 2677 * Kernel context. 2678 */ 2679static int 2680ql_get_cap(opaque_t fca_handle, char *cap, void *ptr) 2681{ 2682 ql_adapter_state_t *ha; 2683 int rval; 2684 uint32_t *rptr = (uint32_t *)ptr; 2685 2686 ha = ql_fca_handle_to_state(fca_handle); 2687 if (ha == NULL) { 2688 QL_PRINT_2(CE_CONT, "failed, no adapter=%ph\n", 2689 (void *)fca_handle); 2690 return (FC_UNBOUND); 2691 } 2692 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance); 2693 2694 if (strcmp(cap, FC_NODE_WWN) == 0) { 2695 bcopy((void *)&ha->loginparams.node_ww_name.raw_wwn[0], 2696 ptr, 8); 2697 rval = FC_CAP_FOUND; 2698 } else if (strcmp(cap, FC_LOGIN_PARAMS) == 0) { 2699 bcopy((void *)&ha->loginparams, ptr, 2700 sizeof (la_els_logi_t)); 2701 rval = FC_CAP_FOUND; 2702 } else if (strcmp(cap, FC_CAP_UNSOL_BUF) == 0) { 2703 *rptr = (uint32_t)QL_UB_LIMIT; 2704 rval = FC_CAP_FOUND; 2705 } else if (strcmp(cap, FC_CAP_NOSTREAM_ON_UNALIGN_BUF) == 0) { 2706 2707 dev_info_t *psydip = NULL; 2708#ifdef __sparc 2709 /* 2710 * Disable streaming for certain 2 chip adapters 2711 * below Psycho to handle Psycho byte hole issue. 2712 */ 2713 if ((CFG_IST(ha, CFG_MULTI_CHIP_ADAPTER)) && 2714 (!CFG_IST(ha, CFG_SBUS_CARD))) { 2715 for (psydip = ddi_get_parent(ha->dip); psydip; 2716 psydip = ddi_get_parent(psydip)) { 2717 if (strcmp(ddi_driver_name(psydip), 2718 "pcipsy") == 0) { 2719 break; 2720 } 2721 } 2722 } 2723#endif /* __sparc */ 2724 2725 if (psydip) { 2726 *rptr = (uint32_t)FC_NO_STREAMING; 2727 EL(ha, "No Streaming\n"); 2728 } else { 2729 *rptr = (uint32_t)FC_ALLOW_STREAMING; 2730 EL(ha, "Allow Streaming\n"); 2731 } 2732 rval = FC_CAP_FOUND; 2733 } else if (strcmp(cap, FC_CAP_PAYLOAD_SIZE) == 0) { 2734 if (CFG_IST(ha, CFG_CTRL_242581)) { 2735 *rptr = (uint32_t)CHAR_TO_SHORT( 2736 ha->init_ctrl_blk.cb24.max_frame_length[0], 2737 ha->init_ctrl_blk.cb24.max_frame_length[1]); 2738 } else { 2739 *rptr = (uint32_t)CHAR_TO_SHORT( 2740 ha->init_ctrl_blk.cb.max_frame_length[0], 2741 ha->init_ctrl_blk.cb.max_frame_length[1]); 2742 } 2743 rval = FC_CAP_FOUND; 2744 } else if (strcmp(cap, FC_CAP_POST_RESET_BEHAVIOR) == 0) { 2745 *rptr = FC_RESET_RETURN_ALL; 2746 rval = FC_CAP_FOUND; 2747 } else if (strcmp(cap, FC_CAP_FCP_DMA) == 0) { 2748 *rptr = FC_NO_DVMA_SPACE; 2749 rval = FC_CAP_FOUND; 2750 } else { 2751 EL(ha, "unknown=%s, FC_CAP_ERROR\n", cap); 2752 rval = FC_CAP_ERROR; 2753 } 2754 2755 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance); 2756 2757 return (rval); 2758} 2759 2760/* 2761 * ql_set_cap 2762 * Allow the FC Transport to set FCA capabilities if possible. 2763 * 2764 * Input: 2765 * fca_handle = handle setup by ql_bind_port(). 2766 * cap = pointer to the capabilities string. 2767 * ptr = buffer pointer for capability. 2768 * 2769 * Returns: 2770 * FC_CAP_ERROR - no such capability 2771 * FC_CAP_FOUND - the capability cannot be set by the FC Transport. 2772 * FC_CAP_SETTABLE - the capability was successfully set. 2773 * FC_UNBOUND - the fca_handle specified is not bound. 2774 * 2775 * Context: 2776 * Kernel context. 2777 */ 2778/* ARGSUSED */ 2779static int 2780ql_set_cap(opaque_t fca_handle, char *cap, void *ptr) 2781{ 2782 ql_adapter_state_t *ha; 2783 int rval; 2784 2785 ha = ql_fca_handle_to_state(fca_handle); 2786 if (ha == NULL) { 2787 QL_PRINT_2(CE_CONT, "failed, no adapter=%ph\n", 2788 (void *)fca_handle); 2789 return (FC_UNBOUND); 2790 } 2791 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance); 2792 2793 if (strcmp(cap, FC_NODE_WWN) == 0) { 2794 rval = FC_CAP_FOUND; 2795 } else if (strcmp(cap, FC_LOGIN_PARAMS) == 0) { 2796 rval = FC_CAP_FOUND; 2797 } else if (strcmp(cap, FC_CAP_UNSOL_BUF) == 0) { 2798 rval = FC_CAP_FOUND; 2799 } else if (strcmp(cap, FC_CAP_PAYLOAD_SIZE) == 0) { 2800 rval = FC_CAP_FOUND; 2801 } else if (strcmp(cap, FC_CAP_POST_RESET_BEHAVIOR) == 0) { 2802 rval = FC_CAP_FOUND; 2803 } else { 2804 EL(ha, "unknown=%s, FC_CAP_ERROR\n", cap); 2805 rval = FC_CAP_ERROR; 2806 } 2807 2808 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance); 2809 2810 return (rval); 2811} 2812 2813/* 2814 * ql_getmap 2815 * Request of Arbitrated Loop (AL-PA) map. 2816 * 2817 * Input: 2818 * fca_handle = handle setup by ql_bind_port(). 2819 * mapbuf= buffer pointer for map. 2820 * 2821 * Returns: 2822 * FC_OLDPORT - the specified port is not operating in loop mode. 2823 * FC_OFFLINE - the specified port is not online. 2824 * FC_NOMAP - there is no loop map available for this port. 2825 * FC_UNBOUND - the fca_handle specified is not bound. 2826 * FC_SUCCESS - a valid map has been placed in mapbuf. 2827 * 2828 * Context: 2829 * Kernel context. 2830 */ 2831static int 2832ql_getmap(opaque_t fca_handle, fc_lilpmap_t *mapbuf) 2833{ 2834 ql_adapter_state_t *ha; 2835 clock_t timer; 2836 int rval = FC_SUCCESS; 2837 2838 ha = ql_fca_handle_to_state(fca_handle); 2839 if (ha == NULL) { 2840 QL_PRINT_2(CE_CONT, "failed, no adapter=%ph\n", 2841 (void *)fca_handle); 2842 return (FC_UNBOUND); 2843 } 2844 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance); 2845 2846 mapbuf->lilp_magic = (uint16_t)MAGIC_LIRP; 2847 mapbuf->lilp_myalpa = ha->d_id.b.al_pa; 2848 2849 /* Wait for suspension to end. */ 2850 TASK_DAEMON_LOCK(ha); 2851 while (ha->task_daemon_flags & QL_SUSPENDED) { 2852 ha->task_daemon_flags |= SUSPENDED_WAKEUP_FLG; 2853 2854 /* 30 seconds from now */ 2855 timer = ddi_get_lbolt(); 2856 timer += drv_usectohz(30000000); 2857 2858 if (cv_timedwait(&ha->pha->cv_dr_suspended, 2859 &ha->pha->task_daemon_mutex, timer) == -1) { 2860 /* 2861 * The timeout time 'timer' was 2862 * reached without the condition 2863 * being signaled. 2864 */ 2865 2866 /* Release task daemon lock. */ 2867 TASK_DAEMON_UNLOCK(ha); 2868 2869 EL(ha, "QL_SUSPENDED failed, FC_TRAN_BUSY\n"); 2870 return (FC_TRAN_BUSY); 2871 } 2872 } 2873 /* Release task daemon lock. */ 2874 TASK_DAEMON_UNLOCK(ha); 2875 2876 if (ql_get_loop_position_map(ha, LOOP_POSITION_MAP_SIZE, 2877 (caddr_t)&mapbuf->lilp_length) != QL_SUCCESS) { 2878 /* 2879 * Now, since transport drivers cosider this as an 2880 * offline condition, let's wait for few seconds 2881 * for any loop transitions before we reset the. 2882 * chip and restart all over again. 2883 */ 2884 ql_delay(ha, 2000000); 2885 EL(ha, "failed, FC_NOMAP\n"); 2886 rval = FC_NOMAP; 2887 } else { 2888 /*EMPTY*/ 2889 QL_PRINT_3(CE_CONT, "(%d): my_alpa %xh len %xh " 2890 "data %xh %xh %xh %xh\n", ha->instance, 2891 mapbuf->lilp_myalpa, mapbuf->lilp_length, 2892 mapbuf->lilp_alpalist[0], mapbuf->lilp_alpalist[1], 2893 mapbuf->lilp_alpalist[2], mapbuf->lilp_alpalist[3]); 2894 } 2895 2896 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance); 2897#if 0 2898 QL_DUMP_3((uint8_t *)mapbuf, 8, sizeof (fc_lilpmap_t)); 2899#endif 2900 return (rval); 2901} 2902 2903/* 2904 * ql_transport 2905 * Issue an I/O request. Handles all regular requests. 2906 * 2907 * Input: 2908 * fca_handle = handle setup by ql_bind_port(). 2909 * pkt = pointer to fc_packet. 2910 * 2911 * Returns: 2912 * FC_SUCCESS - the packet was accepted for transport. 2913 * FC_TRANSPORT_ERROR - a transport error occurred. 2914 * FC_BADPACKET - the packet to be transported had not been 2915 * initialized by this FCA. 2916 * FC_UNBOUND - the fca_handle specified is not bound. 2917 * 2918 * Context: 2919 * Kernel context. 2920 */ 2921static int 2922ql_transport(opaque_t fca_handle, fc_packet_t *pkt) 2923{ 2924 ql_adapter_state_t *ha; 2925 int rval = FC_TRANSPORT_ERROR; 2926 ql_srb_t *sp = (ql_srb_t *)pkt->pkt_fca_private; 2927 2928 /* Verify proper command. */ 2929 ha = ql_cmd_setup(fca_handle, pkt, &rval); 2930 if (ha == NULL) { 2931 QL_PRINT_2(CE_CONT, "failed, ql_cmd_setup=%xh, fcah=%ph\n", 2932 rval, fca_handle); 2933 return (rval); 2934 } 2935 QL_PRINT_3(CE_CONT, "(%d): started command:\n", ha->instance); 2936#if 0 2937 QL_DUMP_3((uint8_t *)&pkt->pkt_cmd_fhdr, 32, 2938 sizeof (fc_frame_hdr_t) / 4); 2939 QL_PRINT_3(CE_CONT, "(%d): command:\n", ha->instance); 2940 QL_DUMP_3((uint8_t *)pkt->pkt_cmd, 8, pkt->pkt_cmdlen); 2941#endif 2942 2943 /* Reset SRB flags. */ 2944 sp->flags &= ~(SRB_ISP_STARTED | SRB_ISP_COMPLETED | SRB_RETRY | 2945 SRB_POLL | SRB_WATCHDOG_ENABLED | SRB_ABORT | SRB_UB_CALLBACK | 2946 SRB_UB_RSCN | SRB_UB_FCP | SRB_FCP_CMD_PKT | SRB_FCP_DATA_PKT | 2947 SRB_FCP_RSP_PKT | SRB_IP_PKT | SRB_GENERIC_SERVICES_PKT | 2948 SRB_COMMAND_TIMEOUT | SRB_ABORTING | SRB_IN_DEVICE_QUEUE | 2949 SRB_IN_TOKEN_ARRAY | SRB_UB_FREE_REQUESTED | SRB_UB_ACQUIRED | 2950 SRB_MS_PKT | SRB_ELS_PKT); 2951 2952 pkt->pkt_resp_fhdr.d_id = ha->d_id.b24; 2953 pkt->pkt_resp_fhdr.r_ctl = R_CTL_STATUS; 2954 pkt->pkt_resp_fhdr.s_id = pkt->pkt_cmd_fhdr.d_id; 2955 pkt->pkt_resp_fhdr.f_ctl = pkt->pkt_cmd_fhdr.f_ctl; 2956 pkt->pkt_resp_fhdr.type = pkt->pkt_cmd_fhdr.type; 2957 2958 switch (pkt->pkt_cmd_fhdr.r_ctl) { 2959 case R_CTL_COMMAND: 2960 if (pkt->pkt_cmd_fhdr.type == FC_TYPE_SCSI_FCP) { 2961 sp->flags |= SRB_FCP_CMD_PKT; 2962 rval = ql_fcp_scsi_cmd(ha, pkt, sp); 2963 } 2964 break; 2965 2966 default: 2967 /* Setup response header and buffer. */ 2968 if (pkt->pkt_rsplen) { 2969 bzero((void *)pkt->pkt_resp, pkt->pkt_rsplen); 2970 } 2971 2972 switch (pkt->pkt_cmd_fhdr.r_ctl) { 2973 case R_CTL_UNSOL_DATA: 2974 if (pkt->pkt_cmd_fhdr.type == FC_TYPE_IS8802_SNAP) { 2975 sp->flags |= SRB_IP_PKT; 2976 rval = ql_fcp_ip_cmd(ha, pkt, sp); 2977 } 2978 break; 2979 2980 case R_CTL_UNSOL_CONTROL: 2981 if (pkt->pkt_cmd_fhdr.type == FC_TYPE_FC_SERVICES) { 2982 sp->flags |= SRB_GENERIC_SERVICES_PKT; 2983 rval = ql_fc_services(ha, pkt); 2984 } 2985 break; 2986 2987 case R_CTL_SOLICITED_DATA: 2988 case R_CTL_STATUS: 2989 default: 2990 pkt->pkt_state = FC_PKT_LOCAL_RJT; 2991 pkt->pkt_reason = FC_REASON_UNSUPPORTED; 2992 rval = FC_TRANSPORT_ERROR; 2993 EL(ha, "unknown, r_ctl=%xh\n", 2994 pkt->pkt_cmd_fhdr.r_ctl); 2995 break; 2996 } 2997 } 2998 2999 if (rval != FC_SUCCESS) { 3000 EL(ha, "failed, rval = %xh\n", rval); 3001 } else { 3002 /*EMPTY*/ 3003 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance); 3004 } 3005 3006 return (rval); 3007} 3008 3009/* 3010 * ql_ub_alloc 3011 * Allocate buffers for unsolicited exchanges. 3012 * 3013 * Input: 3014 * fca_handle = handle setup by ql_bind_port(). 3015 * tokens = token array for each buffer. 3016 * size = size of each buffer. 3017 * count = pointer to number of buffers. 3018 * type = the FC-4 type the buffers are reserved for. 3019 * 1 = Extended Link Services, 5 = LLC/SNAP 3020 * 3021 * Returns: 3022 * FC_FAILURE - buffers could not be allocated. 3023 * FC_TOOMANY - the FCA could not allocate the requested 3024 * number of buffers. 3025 * FC_SUCCESS - unsolicited buffers were allocated. 3026 * FC_UNBOUND - the fca_handle specified is not bound. 3027 * 3028 * Context: 3029 * Kernel context. 3030 */ 3031static int 3032ql_ub_alloc(opaque_t fca_handle, uint64_t tokens[], uint32_t size, 3033 uint32_t *count, uint32_t type) 3034{ 3035 ql_adapter_state_t *ha; 3036 caddr_t bufp = NULL; 3037 fc_unsol_buf_t *ubp; 3038 ql_srb_t *sp; 3039 uint32_t index; 3040 uint32_t cnt; 3041 uint32_t ub_array_index = 0; 3042 int rval = FC_SUCCESS; 3043 int ub_updated = FALSE; 3044 3045 /* Check handle. */ 3046 ha = ql_fca_handle_to_state(fca_handle); 3047 if (ha == NULL) { 3048 QL_PRINT_2(CE_CONT, "failed, no adapter=%ph\n", 3049 (void *)fca_handle); 3050 return (FC_UNBOUND); 3051 } 3052 QL_PRINT_3(CE_CONT, "(%d,%d): started, count = %xh\n", 3053 ha->instance, ha->vp_index, *count); 3054 3055 QL_PM_LOCK(ha); 3056 if (ha->power_level != PM_LEVEL_D0) { 3057 QL_PM_UNLOCK(ha); 3058 QL_PRINT_3(CE_CONT, "(%d,%d): down done\n", ha->instance, 3059 ha->vp_index); 3060 return (FC_FAILURE); 3061 } 3062 QL_PM_UNLOCK(ha); 3063 3064 /* Acquire adapter state lock. */ 3065 ADAPTER_STATE_LOCK(ha); 3066 3067 /* Check the count. */ 3068 if ((*count + ha->ub_allocated) > QL_UB_LIMIT) { 3069 *count = 0; 3070 EL(ha, "failed, FC_TOOMANY\n"); 3071 rval = FC_TOOMANY; 3072 } 3073 3074 /* 3075 * reset ub_array_index 3076 */ 3077 ub_array_index = 0; 3078 3079 /* 3080 * Now proceed to allocate any buffers required 3081 */ 3082 for (index = 0; index < *count && rval == FC_SUCCESS; index++) { 3083 /* Allocate all memory needed. */ 3084 ubp = (fc_unsol_buf_t *)kmem_zalloc(sizeof (fc_unsol_buf_t), 3085 KM_SLEEP); 3086 if (ubp == NULL) { 3087 EL(ha, "failed, FC_FAILURE\n"); 3088 rval = FC_FAILURE; 3089 } else { 3090 sp = kmem_zalloc(sizeof (ql_srb_t), KM_SLEEP); 3091 if (sp == NULL) { 3092 kmem_free(ubp, sizeof (fc_unsol_buf_t)); 3093 rval = FC_FAILURE; 3094 } else { 3095 if (type == FC_TYPE_IS8802_SNAP) { 3096#ifdef __sparc 3097 if (ql_get_dma_mem(ha, 3098 &sp->ub_buffer, size, 3099 BIG_ENDIAN_DMA, 3100 QL_DMA_DATA_ALIGN) != QL_SUCCESS) { 3101 rval = FC_FAILURE; 3102 kmem_free(ubp, 3103 sizeof (fc_unsol_buf_t)); 3104 kmem_free(sp, 3105 sizeof (ql_srb_t)); 3106 } else { 3107 bufp = sp->ub_buffer.bp; 3108 sp->ub_size = size; 3109 } 3110#else 3111 if (ql_get_dma_mem(ha, 3112 &sp->ub_buffer, size, 3113 LITTLE_ENDIAN_DMA, 3114 QL_DMA_DATA_ALIGN) != QL_SUCCESS) { 3115 rval = FC_FAILURE; 3116 kmem_free(ubp, 3117 sizeof (fc_unsol_buf_t)); 3118 kmem_free(sp, 3119 sizeof (ql_srb_t)); 3120 } else { 3121 bufp = sp->ub_buffer.bp; 3122 sp->ub_size = size; 3123 } 3124#endif 3125 } else { 3126 bufp = kmem_zalloc(size, KM_SLEEP); 3127 if (bufp == NULL) { 3128 rval = FC_FAILURE; 3129 kmem_free(ubp, 3130 sizeof (fc_unsol_buf_t)); 3131 kmem_free(sp, 3132 sizeof (ql_srb_t)); 3133 } else { 3134 sp->ub_size = size; 3135 } 3136 } 3137 } 3138 } 3139 3140 if (rval == FC_SUCCESS) { 3141 /* Find next available slot. */ 3142 QL_UB_LOCK(ha); 3143 while (ha->ub_array[ub_array_index] != NULL) { 3144 ub_array_index++; 3145 } 3146 3147 ubp->ub_fca_private = (void *)sp; 3148 3149 /* init cmd links */ 3150 sp->cmd.base_address = sp; 3151 sp->cmd.prev = NULL; 3152 sp->cmd.next = NULL; 3153 sp->cmd.head = NULL; 3154 3155 /* init wdg links */ 3156 sp->wdg.base_address = sp; 3157 sp->wdg.prev = NULL; 3158 sp->wdg.next = NULL; 3159 sp->wdg.head = NULL; 3160 sp->ha = ha; 3161 3162 ubp->ub_buffer = bufp; 3163 ubp->ub_bufsize = size; 3164 ubp->ub_port_handle = fca_handle; 3165 ubp->ub_token = ub_array_index; 3166 3167 /* Save the token. */ 3168 tokens[index] = ub_array_index; 3169 3170 /* Setup FCA private information. */ 3171 sp->ub_type = type; 3172 sp->handle = ub_array_index; 3173 sp->flags |= SRB_UB_IN_FCA; 3174 3175 ha->ub_array[ub_array_index] = ubp; 3176 ha->ub_allocated++; 3177 ub_updated = TRUE; 3178 QL_UB_UNLOCK(ha); 3179 } 3180 } 3181 3182 /* Release adapter state lock. */ 3183 ADAPTER_STATE_UNLOCK(ha); 3184 3185 /* IP buffer. */ 3186 if (ub_updated) { 3187 if ((type == FC_TYPE_IS8802_SNAP) && 3188 (!(CFG_IST(ha, (CFG_CTRL_6322 | CFG_CTRL_2581))))) { 3189 3190 ADAPTER_STATE_LOCK(ha); 3191 ha->flags |= IP_ENABLED; 3192 ADAPTER_STATE_UNLOCK(ha); 3193 3194 if (!(ha->flags & IP_INITIALIZED)) { 3195 if (CFG_IST(ha, CFG_CTRL_2422)) { 3196 ha->ip_init_ctrl_blk.cb24.mtu_size[0] = 3197 LSB(ql_ip_mtu); 3198 ha->ip_init_ctrl_blk.cb24.mtu_size[1] = 3199 MSB(ql_ip_mtu); 3200 ha->ip_init_ctrl_blk.cb24.buf_size[0] = 3201 LSB(size); 3202 ha->ip_init_ctrl_blk.cb24.buf_size[1] = 3203 MSB(size); 3204 3205 cnt = CHAR_TO_SHORT( 3206 ha->ip_init_ctrl_blk.cb24.cc[0], 3207 ha->ip_init_ctrl_blk.cb24.cc[1]); 3208 3209 if (cnt < *count) { 3210 ha->ip_init_ctrl_blk.cb24.cc[0] 3211 = LSB(*count); 3212 ha->ip_init_ctrl_blk.cb24.cc[1] 3213 = MSB(*count); 3214 } 3215 } else { 3216 ha->ip_init_ctrl_blk.cb.mtu_size[0] = 3217 LSB(ql_ip_mtu); 3218 ha->ip_init_ctrl_blk.cb.mtu_size[1] = 3219 MSB(ql_ip_mtu); 3220 ha->ip_init_ctrl_blk.cb.buf_size[0] = 3221 LSB(size); 3222 ha->ip_init_ctrl_blk.cb.buf_size[1] = 3223 MSB(size); 3224 3225 cnt = CHAR_TO_SHORT( 3226 ha->ip_init_ctrl_blk.cb.cc[0], 3227 ha->ip_init_ctrl_blk.cb.cc[1]); 3228 3229 if (cnt < *count) { 3230 ha->ip_init_ctrl_blk.cb.cc[0] = 3231 LSB(*count); 3232 ha->ip_init_ctrl_blk.cb.cc[1] = 3233 MSB(*count); 3234 } 3235 } 3236 3237 (void) ql_initialize_ip(ha); 3238 } 3239 ql_isp_rcvbuf(ha); 3240 } 3241 } 3242 3243 if (rval != FC_SUCCESS) { 3244 EL(ha, "failed=%xh\n", rval); 3245 } else { 3246 /*EMPTY*/ 3247 QL_PRINT_3(CE_CONT, "(%d,%d): done\n", ha->instance, 3248 ha->vp_index); 3249 } 3250 return (rval); 3251} 3252 3253/* 3254 * ql_ub_free 3255 * Free unsolicited buffers. 3256 * 3257 * Input: 3258 * fca_handle = handle setup by ql_bind_port(). 3259 * count = number of buffers. 3260 * tokens = token array for each buffer. 3261 * 3262 * Returns: 3263 * FC_SUCCESS - the requested buffers have been freed. 3264 * FC_UNBOUND - the fca_handle specified is not bound. 3265 * FC_UB_BADTOKEN - an invalid token was encountered. 3266 * No buffers have been released. 3267 * 3268 * Context: 3269 * Kernel context. 3270 */ 3271static int 3272ql_ub_free(opaque_t fca_handle, uint32_t count, uint64_t tokens[]) 3273{ 3274 ql_adapter_state_t *ha; 3275 ql_srb_t *sp; 3276 uint32_t index; 3277 uint64_t ub_array_index; 3278 int rval = FC_SUCCESS; 3279 3280 /* Check handle. */ 3281 ha = ql_fca_handle_to_state(fca_handle); 3282 if (ha == NULL) { 3283 QL_PRINT_2(CE_CONT, "failed, no adapter=%ph\n", 3284 (void *)fca_handle); 3285 return (FC_UNBOUND); 3286 } 3287 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance); 3288 3289 /* Acquire adapter state lock. */ 3290 ADAPTER_STATE_LOCK(ha); 3291 3292 /* Check all returned tokens. */ 3293 for (index = 0; index < count; index++) { 3294 fc_unsol_buf_t *ubp; 3295 3296 /* Check the token range. */ 3297 if ((ub_array_index = tokens[index]) >= QL_UB_LIMIT) { 3298 EL(ha, "failed, FC_UB_BADTOKEN\n"); 3299 rval = FC_UB_BADTOKEN; 3300 break; 3301 } 3302 3303 /* Check the unsolicited buffer array. */ 3304 QL_UB_LOCK(ha); 3305 ubp = ha->ub_array[ub_array_index]; 3306 3307 if (ubp == NULL) { 3308 EL(ha, "failed, FC_UB_BADTOKEN-2\n"); 3309 rval = FC_UB_BADTOKEN; 3310 QL_UB_UNLOCK(ha); 3311 break; 3312 } 3313 3314 /* Check the state of the unsolicited buffer. */ 3315 sp = ha->ub_array[ub_array_index]->ub_fca_private; 3316 sp->flags |= SRB_UB_FREE_REQUESTED; 3317 3318 while (!(sp->flags & SRB_UB_IN_FCA) || 3319 (sp->flags & (SRB_UB_CALLBACK | SRB_UB_ACQUIRED))) { 3320 QL_UB_UNLOCK(ha); 3321 ADAPTER_STATE_UNLOCK(ha); 3322 delay(drv_usectohz(100000)); 3323 ADAPTER_STATE_LOCK(ha); 3324 QL_UB_LOCK(ha); 3325 } 3326 ha->ub_array[ub_array_index] = NULL; 3327 QL_UB_UNLOCK(ha); 3328 ql_free_unsolicited_buffer(ha, ubp); 3329 } 3330 3331 if (rval == FC_SUCCESS) { 3332 /* 3333 * Signal any pending hardware reset when there are 3334 * no more unsolicited buffers in use. 3335 */ 3336 if (ha->ub_allocated == 0) { 3337 cv_broadcast(&ha->pha->cv_ub); 3338 } 3339 } 3340 3341 /* Release adapter state lock. */ 3342 ADAPTER_STATE_UNLOCK(ha); 3343 3344 if (rval != FC_SUCCESS) { 3345 EL(ha, "failed=%xh\n", rval); 3346 } else { 3347 /*EMPTY*/ 3348 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance); 3349 } 3350 return (rval); 3351} 3352 3353/* 3354 * ql_ub_release 3355 * Release unsolicited buffers from FC Transport 3356 * to FCA for future use. 3357 * 3358 * Input: 3359 * fca_handle = handle setup by ql_bind_port(). 3360 * count = number of buffers. 3361 * tokens = token array for each buffer. 3362 * 3363 * Returns: 3364 * FC_SUCCESS - the requested buffers have been released. 3365 * FC_UNBOUND - the fca_handle specified is not bound. 3366 * FC_UB_BADTOKEN - an invalid token was encountered. 3367 * No buffers have been released. 3368 * 3369 * Context: 3370 * Kernel context. 3371 */ 3372static int 3373ql_ub_release(opaque_t fca_handle, uint32_t count, uint64_t tokens[]) 3374{ 3375 ql_adapter_state_t *ha; 3376 ql_srb_t *sp; 3377 uint32_t index; 3378 uint64_t ub_array_index; 3379 int rval = FC_SUCCESS; 3380 int ub_ip_updated = FALSE; 3381 3382 /* Check handle. */ 3383 ha = ql_fca_handle_to_state(fca_handle); 3384 if (ha == NULL) { 3385 QL_PRINT_2(CE_CONT, ": failed, no adapter=%ph\n", 3386 (void *)fca_handle); 3387 return (FC_UNBOUND); 3388 } 3389 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance); 3390 3391 /* Acquire adapter state lock. */ 3392 ADAPTER_STATE_LOCK(ha); 3393 QL_UB_LOCK(ha); 3394 3395 /* Check all returned tokens. */ 3396 for (index = 0; index < count; index++) { 3397 /* Check the token range. */ 3398 if ((ub_array_index = tokens[index]) >= QL_UB_LIMIT) { 3399 EL(ha, "failed, FC_UB_BADTOKEN\n"); 3400 rval = FC_UB_BADTOKEN; 3401 break; 3402 } 3403 3404 /* Check the unsolicited buffer array. */ 3405 if (ha->ub_array[ub_array_index] == NULL) { 3406 EL(ha, "failed, FC_UB_BADTOKEN-2\n"); 3407 rval = FC_UB_BADTOKEN; 3408 break; 3409 } 3410 3411 /* Check the state of the unsolicited buffer. */ 3412 sp = ha->ub_array[ub_array_index]->ub_fca_private; 3413 if (sp->flags & SRB_UB_IN_FCA) { 3414 EL(ha, "failed, FC_UB_BADTOKEN-3\n"); 3415 rval = FC_UB_BADTOKEN; 3416 break; 3417 } 3418 } 3419 3420 /* If all tokens checkout, release the buffers. */ 3421 if (rval == FC_SUCCESS) { 3422 /* Check all returned tokens. */ 3423 for (index = 0; index < count; index++) { 3424 fc_unsol_buf_t *ubp; 3425 3426 ub_array_index = tokens[index]; 3427 ubp = ha->ub_array[ub_array_index]; 3428 sp = ubp->ub_fca_private; 3429 3430 ubp->ub_resp_flags = 0; 3431 sp->flags &= ~(SRB_UB_ACQUIRED | SRB_UB_CALLBACK); 3432 sp->flags |= SRB_UB_IN_FCA; 3433 3434 /* IP buffer. */ 3435 if (sp->ub_type == FC_TYPE_IS8802_SNAP) { 3436 ub_ip_updated = TRUE; 3437 } 3438 } 3439 } 3440 3441 QL_UB_UNLOCK(ha); 3442 /* Release adapter state lock. */ 3443 ADAPTER_STATE_UNLOCK(ha); 3444 3445 /* 3446 * XXX: We should call ql_isp_rcvbuf() to return a 3447 * buffer to ISP only if the number of buffers fall below 3448 * the low water mark. 3449 */ 3450 if (ub_ip_updated) { 3451 ql_isp_rcvbuf(ha); 3452 } 3453 3454 if (rval != FC_SUCCESS) { 3455 EL(ha, "failed, rval = %xh\n", rval); 3456 } else { 3457 /*EMPTY*/ 3458 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance); 3459 } 3460 return (rval); 3461} 3462 3463/* 3464 * ql_abort 3465 * Abort a packet. 3466 * 3467 * Input: 3468 * fca_handle = handle setup by ql_bind_port(). 3469 * pkt = pointer to fc_packet. 3470 * flags = KM_SLEEP flag. 3471 * 3472 * Returns: 3473 * FC_SUCCESS - the packet has successfully aborted. 3474 * FC_ABORTED - the packet has successfully aborted. 3475 * FC_ABORTING - the packet is being aborted. 3476 * FC_ABORT_FAILED - the packet could not be aborted. 3477 * FC_TRANSPORT_ERROR - a transport error occurred while attempting 3478 * to abort the packet. 3479 * FC_BADEXCHANGE - no packet found. 3480 * FC_UNBOUND - the fca_handle specified is not bound. 3481 * 3482 * Context: 3483 * Kernel context. 3484 */ 3485static int 3486ql_abort(opaque_t fca_handle, fc_packet_t *pkt, int flags) 3487{ 3488 port_id_t d_id; 3489 ql_link_t *link; 3490 ql_adapter_state_t *ha, *pha; 3491 ql_srb_t *sp; 3492 ql_tgt_t *tq; 3493 ql_lun_t *lq; 3494 int rval = FC_ABORTED; 3495 3496 ha = ql_fca_handle_to_state(fca_handle); 3497 if (ha == NULL) { 3498 QL_PRINT_2(CE_CONT, "failed, no adapter=%ph\n", 3499 (void *)fca_handle); 3500 return (FC_UNBOUND); 3501 } 3502 3503 pha = ha->pha; 3504 3505 QL_PRINT_3(CE_CONT, "(%d,%d): started\n", ha->instance, ha->vp_index); 3506 3507 /* Get target queue pointer. */ 3508 d_id.b24 = pkt->pkt_cmd_fhdr.d_id; 3509 tq = ql_d_id_to_queue(ha, d_id); 3510 3511 if ((tq == NULL) || (pha->task_daemon_flags & LOOP_DOWN)) { 3512 if (tq == NULL) { 3513 EL(ha, "failed, FC_TRANSPORT_ERROR\n"); 3514 rval = FC_TRANSPORT_ERROR; 3515 } else { 3516 EL(ha, "failed, FC_OFFLINE\n"); 3517 rval = FC_OFFLINE; 3518 } 3519 return (rval); 3520 } 3521 3522 sp = (ql_srb_t *)pkt->pkt_fca_private; 3523 lq = sp->lun_queue; 3524 3525 /* Set poll flag if sleep wanted. */ 3526 if (flags == KM_SLEEP) { 3527 sp->flags |= SRB_POLL; 3528 } 3529 3530 /* Acquire target queue lock. */ 3531 DEVICE_QUEUE_LOCK(tq); 3532 REQUEST_RING_LOCK(ha); 3533 3534 /* If command not already started. */ 3535 if (!(sp->flags & SRB_ISP_STARTED)) { 3536 /* Check pending queue for command. */ 3537 sp = NULL; 3538 for (link = pha->pending_cmds.first; link != NULL; 3539 link = link->next) { 3540 sp = link->base_address; 3541 if (sp == (ql_srb_t *)pkt->pkt_fca_private) { 3542 /* Remove srb from q. */ 3543 ql_remove_link(&pha->pending_cmds, &sp->cmd); 3544 break; 3545 } else { 3546 sp = NULL; 3547 } 3548 } 3549 REQUEST_RING_UNLOCK(ha); 3550 3551 if (sp == NULL) { 3552 /* Check for cmd on device queue. */ 3553 for (link = lq->cmd.first; link != NULL; 3554 link = link->next) { 3555 sp = link->base_address; 3556 if (sp == (ql_srb_t *)pkt->pkt_fca_private) { 3557 /* Remove srb from q. */ 3558 ql_remove_link(&lq->cmd, &sp->cmd); 3559 break; 3560 } else { 3561 sp = NULL; 3562 } 3563 } 3564 } 3565 /* Release device lock */ 3566 DEVICE_QUEUE_UNLOCK(tq); 3567 3568 /* If command on target queue. */ 3569 if (sp != NULL) { 3570 sp->flags &= ~SRB_IN_DEVICE_QUEUE; 3571 3572 /* Set return status */ 3573 pkt->pkt_reason = CS_ABORTED; 3574 3575 sp->cmd.next = NULL; 3576 ql_done(&sp->cmd); 3577 rval = FC_ABORTED; 3578 } else { 3579 EL(ha, "failed, FC_BADEXCHANGE\n"); 3580 rval = FC_BADEXCHANGE; 3581 } 3582 } else if (sp->flags & SRB_ISP_COMPLETED) { 3583 /* Release device queue lock. */ 3584 REQUEST_RING_UNLOCK(ha); 3585 DEVICE_QUEUE_UNLOCK(tq); 3586 EL(ha, "failed, already done, FC_FAILURE\n"); 3587 rval = FC_FAILURE; 3588 } else if ((sp->pkt->pkt_cmd_fhdr.r_ctl == R_CTL_SOLICITED_DATA) || 3589 (sp->pkt->pkt_cmd_fhdr.r_ctl == R_CTL_STATUS)) { 3590 /* 3591 * If here, target data/resp ctio is with Fw. 3592 * Since firmware is supposed to terminate such I/Os 3593 * with an error, we need not do any thing. If FW 3594 * decides not to terminate those IOs and simply keep 3595 * quite then we need to initiate cleanup here by 3596 * calling ql_done. 3597 */ 3598 REQUEST_RING_UNLOCK(ha); 3599 DEVICE_QUEUE_UNLOCK(tq); 3600 rval = FC_ABORTED; 3601 } else { 3602 request_t *ep = pha->request_ring_bp; 3603 uint16_t cnt; 3604 3605 if (sp->handle != 0) { 3606 for (cnt = 0; cnt < REQUEST_ENTRY_CNT; cnt++) { 3607 if (sp->handle == ddi_get32( 3608 pha->hba_buf.acc_handle, &ep->handle)) { 3609 ep->entry_type = INVALID_ENTRY_TYPE; 3610 break; 3611 } 3612 ep++; 3613 } 3614 } 3615 3616 /* Release device queue lock. */ 3617 REQUEST_RING_UNLOCK(ha); 3618 DEVICE_QUEUE_UNLOCK(tq); 3619 3620 sp->flags |= SRB_ABORTING; 3621 (void) ql_abort_command(ha, sp); 3622 pkt->pkt_reason = CS_ABORTED; 3623 rval = FC_ABORTED; 3624 } 3625 3626 QL_PRINT_3(CE_CONT, "(%d,%d): done\n", ha->instance, ha->vp_index); 3627 3628 return (rval); 3629} 3630 3631/* 3632 * ql_reset 3633 * Reset link or hardware. 3634 * 3635 * Input: 3636 * fca_handle = handle setup by ql_bind_port(). 3637 * cmd = reset type command. 3638 * 3639 * Returns: 3640 * FC_SUCCESS - reset has successfully finished. 3641 * FC_UNBOUND - the fca_handle specified is not bound. 3642 * FC_FAILURE - reset failed. 3643 * 3644 * Context: 3645 * Kernel context. 3646 */ 3647static int 3648ql_reset(opaque_t fca_handle, uint32_t cmd) 3649{ 3650 ql_adapter_state_t *ha; 3651 int rval = FC_SUCCESS, rval2; 3652 3653 ha = ql_fca_handle_to_state(fca_handle); 3654 if (ha == NULL) { 3655 QL_PRINT_2(CE_CONT, "failed, no adapter=%ph\n", 3656 (void *)fca_handle); 3657 return (FC_UNBOUND); 3658 } 3659 3660 QL_PRINT_3(CE_CONT, "(%d,%d): started, cmd=%d\n", ha->instance, 3661 ha->vp_index, cmd); 3662 3663 switch (cmd) { 3664 case FC_FCA_CORE: 3665 /* dump firmware core if specified. */ 3666 if (ha->vp_index == 0) { 3667 if (ql_dump_firmware(ha) != QL_SUCCESS) { 3668 EL(ha, "failed, FC_FAILURE\n"); 3669 rval = FC_FAILURE; 3670 } 3671 } 3672 break; 3673 case FC_FCA_LINK_RESET: 3674 if (!(ha->pha->task_daemon_flags & LOOP_DOWN)) { 3675 if (ql_loop_reset(ha) != QL_SUCCESS) { 3676 EL(ha, "failed, FC_FAILURE-2\n"); 3677 rval = FC_FAILURE; 3678 } 3679 } 3680 break; 3681 case FC_FCA_RESET_CORE: 3682 case FC_FCA_RESET: 3683 /* if dump firmware core if specified. */ 3684 if (cmd == FC_FCA_RESET_CORE) { 3685 if (ha->vp_index != 0) { 3686 rval2 = ha->pha->task_daemon_flags & LOOP_DOWN 3687 ? QL_SUCCESS : ql_loop_reset(ha); 3688 } else { 3689 rval2 = ql_dump_firmware(ha); 3690 } 3691 if (rval2 != QL_SUCCESS) { 3692 EL(ha, "failed, FC_FAILURE-3\n"); 3693 rval = FC_FAILURE; 3694 } 3695 } 3696 3697 /* Free up all unsolicited buffers. */ 3698 if (ha->ub_allocated != 0) { 3699 /* Inform to release buffers. */ 3700 ha->state = FC_PORT_SPEED_MASK(ha->state); 3701 ha->state |= FC_STATE_RESET_REQUESTED; 3702 if (ha->flags & FCA_BOUND) { 3703 (ha->bind_info.port_statec_cb) 3704 (ha->bind_info.port_handle, 3705 ha->state); 3706 } 3707 } 3708 3709 ha->state = FC_PORT_SPEED_MASK(ha->state); 3710 3711 /* All buffers freed */ 3712 if (ha->ub_allocated == 0) { 3713 /* Hardware reset. */ 3714 if (cmd == FC_FCA_RESET) { 3715 if (ha->vp_index == 0) { 3716 (void) ql_abort_isp(ha); 3717 } else if (!(ha->pha->task_daemon_flags & 3718 LOOP_DOWN)) { 3719 (void) ql_loop_reset(ha); 3720 } 3721 } 3722 3723 /* Inform that the hardware has been reset */ 3724 ha->state |= FC_STATE_RESET; 3725 } else { 3726 /* 3727 * the port driver expects an online if 3728 * buffers are not freed. 3729 */ 3730 if (ha->topology & QL_LOOP_CONNECTION) { 3731 ha->state |= FC_STATE_LOOP; 3732 } else { 3733 ha->state |= FC_STATE_ONLINE; 3734 } 3735 } 3736 3737 TASK_DAEMON_LOCK(ha); 3738 ha->task_daemon_flags |= FC_STATE_CHANGE; 3739 TASK_DAEMON_UNLOCK(ha); 3740 3741 ql_awaken_task_daemon(ha, NULL, FC_STATE_CHANGE, 0); 3742 3743 break; 3744 default: 3745 EL(ha, "unknown cmd=%xh\n", cmd); 3746 break; 3747 } 3748 3749 if (rval != FC_SUCCESS) { 3750 EL(ha, "cmd=%xh, failed=%xh\n", cmd, rval); 3751 } else { 3752 /*EMPTY*/ 3753 QL_PRINT_3(CE_CONT, "(%d,%d): done\n", ha->instance, 3754 ha->vp_index); 3755 } 3756 3757 return (rval); 3758} 3759 3760/* 3761 * ql_port_manage 3762 * Perform port management or diagnostics. 3763 * 3764 * Input: 3765 * fca_handle = handle setup by ql_bind_port(). 3766 * cmd = pointer to command structure. 3767 * 3768 * Returns: 3769 * FC_SUCCESS - the request completed successfully. 3770 * FC_FAILURE - the request did not complete successfully. 3771 * FC_UNBOUND - the fca_handle specified is not bound. 3772 * 3773 * Context: 3774 * Kernel context. 3775 */ 3776static int 3777ql_port_manage(opaque_t fca_handle, fc_fca_pm_t *cmd) 3778{ 3779 clock_t timer; 3780 uint16_t index; 3781 uint32_t *bp; 3782 port_id_t d_id; 3783 ql_link_t *link; 3784 ql_adapter_state_t *ha, *pha; 3785 ql_tgt_t *tq; 3786 dma_mem_t buffer_xmt, buffer_rcv; 3787 size_t length; 3788 uint32_t cnt; 3789 char buf[80]; 3790 lbp_t *lb; 3791 ql_mbx_data_t mr; 3792 app_mbx_cmd_t *mcp; 3793 int i0; 3794 uint8_t *bptr; 3795 int rval2, rval = FC_SUCCESS; 3796 uint32_t opcode; 3797 uint32_t set_flags = 0; 3798 3799 ha = ql_fca_handle_to_state(fca_handle); 3800 if (ha == NULL) { 3801 QL_PRINT_2(CE_CONT, ": failed, no adapter=%ph\n", 3802 (void *)fca_handle); 3803 return (FC_UNBOUND); 3804 } 3805 pha = ha->pha; 3806 3807 QL_PRINT_3(CE_CONT, "(%d): started=%xh\n", ha->instance, 3808 cmd->pm_cmd_code); 3809 3810 ql_awaken_task_daemon(ha, NULL, DRIVER_STALL, 0); 3811 3812 /* 3813 * Wait for all outstanding commands to complete 3814 */ 3815 index = (uint16_t)ql_wait_outstanding(ha); 3816 3817 if (index != MAX_OUTSTANDING_COMMANDS) { 3818 ql_awaken_task_daemon(ha, NULL, 0, DRIVER_STALL); 3819 ql_restart_queues(ha); 3820 EL(ha, "failed, FC_TRAN_BUSY\n"); 3821 return (FC_TRAN_BUSY); 3822 } 3823 3824 switch (cmd->pm_cmd_code) { 3825 case FC_PORT_BYPASS: 3826 d_id.b24 = *cmd->pm_cmd_buf; 3827 tq = ql_d_id_to_queue(ha, d_id); 3828 if (tq == NULL || ql_loop_port_bypass(ha, tq) != QL_SUCCESS) { 3829 EL(ha, "failed, FC_PORT_BYPASS FC_FAILURE\n"); 3830 rval = FC_FAILURE; 3831 } 3832 break; 3833 case FC_PORT_UNBYPASS: 3834 d_id.b24 = *cmd->pm_cmd_buf; 3835 tq = ql_d_id_to_queue(ha, d_id); 3836 if (tq == NULL || ql_loop_port_enable(ha, tq) != QL_SUCCESS) { 3837 EL(ha, "failed, FC_PORT_UNBYPASS FC_FAILURE\n"); 3838 rval = FC_FAILURE; 3839 } 3840 break; 3841 case FC_PORT_GET_FW_REV: 3842 (void) sprintf(buf, "%d.%d.%d", pha->fw_major_version, 3843 pha->fw_minor_version, pha->fw_subminor_version); 3844 length = strlen(buf) + 1; 3845 if (cmd->pm_data_len < length) { 3846 cmd->pm_data_len = length; 3847 EL(ha, "failed, FC_PORT_GET_FW_REV FC_FAILURE\n"); 3848 rval = FC_FAILURE; 3849 } else { 3850 (void) strcpy(cmd->pm_data_buf, buf); 3851 } 3852 break; 3853 3854 case FC_PORT_GET_FCODE_REV: { 3855 caddr_t fcode_ver_buf = NULL; 3856 3857 i0 = 0; 3858 /*LINTED [Solaris DDI_DEV_T_ANY Lint warning]*/ 3859 rval2 = ddi_getlongprop(DDI_DEV_T_ANY, ha->dip, 3860 DDI_PROP_DONTPASS | DDI_PROP_CANSLEEP, "version", 3861 (caddr_t)&fcode_ver_buf, &i0); 3862 length = (uint_t)i0; 3863 3864 if (rval2 != DDI_PROP_SUCCESS) { 3865 EL(ha, "failed, getting version = %xh\n", rval2); 3866 length = 20; 3867 fcode_ver_buf = kmem_alloc(length, KM_SLEEP); 3868 if (fcode_ver_buf != NULL) { 3869 (void) sprintf(fcode_ver_buf, 3870 "NO FCODE FOUND"); 3871 } 3872 } 3873 3874 if (cmd->pm_data_len < length) { 3875 EL(ha, "length error, FC_PORT_GET_FCODE_REV " 3876 "dst=%ld, src=%ld\n", cmd->pm_data_len, length); 3877 cmd->pm_data_len = length; 3878 rval = FC_FAILURE; 3879 } else if (fcode_ver_buf != NULL) { 3880 bcopy((void *)fcode_ver_buf, (void *)cmd->pm_data_buf, 3881 length); 3882 } 3883 3884 if (fcode_ver_buf != NULL) { 3885 kmem_free(fcode_ver_buf, length); 3886 } 3887 break; 3888 } 3889 3890 case FC_PORT_GET_DUMP: 3891 QL_DUMP_LOCK(pha); 3892 if (cmd->pm_data_len < (size_t)pha->risc_dump_size) { 3893 EL(ha, "failed, FC_PORT_GET_DUMP incorrect " 3894 "length=%lxh\n", cmd->pm_data_len); 3895 cmd->pm_data_len = pha->risc_dump_size; 3896 rval = FC_FAILURE; 3897 } else if (pha->ql_dump_state & QL_DUMPING) { 3898 EL(ha, "failed, FC_PORT_GET_DUMP FC_TRAN_BUSY\n"); 3899 rval = FC_TRAN_BUSY; 3900 } else if (pha->ql_dump_state & QL_DUMP_VALID) { 3901 (void) ql_ascii_fw_dump(ha, cmd->pm_data_buf); 3902 pha->ql_dump_state |= QL_DUMP_UPLOADED; 3903 } else { 3904 EL(ha, "failed, FC_PORT_GET_DUMP no dump file\n"); 3905 rval = FC_FAILURE; 3906 } 3907 QL_DUMP_UNLOCK(pha); 3908 break; 3909 case FC_PORT_FORCE_DUMP: 3910 PORTMANAGE_LOCK(ha); 3911 if (ql_dump_firmware(ha) != QL_SUCCESS) { 3912 EL(ha, "failed, FC_PORT_FORCE_DUMP FC_FAILURE\n"); 3913 rval = FC_FAILURE; 3914 } 3915 PORTMANAGE_UNLOCK(ha); 3916 break; 3917 case FC_PORT_DOWNLOAD_FW: 3918 PORTMANAGE_LOCK(ha); 3919 if (CFG_IST(ha, CFG_CTRL_242581)) { 3920 if (ql_24xx_load_flash(ha, (uint8_t *)cmd->pm_data_buf, 3921 (uint32_t)cmd->pm_data_len, 3922 ha->flash_fw_addr << 2) != QL_SUCCESS) { 3923 EL(ha, "failed, FC_PORT_DOWNLOAD_FW\n"); 3924 rval = FC_FAILURE; 3925 } 3926 ql_reset_chip(ha); 3927 set_flags |= ISP_ABORT_NEEDED; 3928 } else { 3929 /* Save copy of the firmware. */ 3930 if (pha->risc_code != NULL) { 3931 kmem_free(pha->risc_code, pha->risc_code_size); 3932 pha->risc_code = NULL; 3933 pha->risc_code_size = 0; 3934 } 3935 3936 pha->risc_code = kmem_alloc(cmd->pm_data_len, 3937 KM_SLEEP); 3938 if (pha->risc_code != NULL) { 3939 pha->risc_code_size = 3940 (uint32_t)cmd->pm_data_len; 3941 bcopy(cmd->pm_data_buf, pha->risc_code, 3942 cmd->pm_data_len); 3943 3944 /* Do abort to force reload. */ 3945 ql_reset_chip(ha); 3946 if (ql_abort_isp(ha) != QL_SUCCESS) { 3947 kmem_free(pha->risc_code, 3948 pha->risc_code_size); 3949 pha->risc_code = NULL; 3950 pha->risc_code_size = 0; 3951 ql_reset_chip(ha); 3952 (void) ql_abort_isp(ha); 3953 EL(ha, "failed, FC_PORT_DOWNLOAD_FW" 3954 " FC_FAILURE\n"); 3955 rval = FC_FAILURE; 3956 } 3957 } 3958 } 3959 PORTMANAGE_UNLOCK(ha); 3960 break; 3961 case FC_PORT_GET_DUMP_SIZE: 3962 bp = (uint32_t *)cmd->pm_data_buf; 3963 *bp = pha->risc_dump_size; 3964 break; 3965 case FC_PORT_DIAG: 3966 /* 3967 * Prevents concurrent diags 3968 */ 3969 PORTMANAGE_LOCK(ha); 3970 3971 /* Wait for suspension to end. */ 3972 for (timer = 0; timer < 3000 && 3973 pha->task_daemon_flags & QL_LOOP_TRANSITION; timer++) { 3974 ql_delay(ha, 10000); 3975 } 3976 3977 if (pha->task_daemon_flags & QL_LOOP_TRANSITION) { 3978 EL(ha, "failed, FC_TRAN_BUSY-2\n"); 3979 rval = FC_TRAN_BUSY; 3980 PORTMANAGE_UNLOCK(ha); 3981 break; 3982 } 3983 3984 switch (cmd->pm_cmd_flags) { 3985 case QL_DIAG_EXEFMW: 3986 if (ql_start_firmware(ha) != QL_SUCCESS) { 3987 EL(ha, "failed, QL_DIAG_EXEFMW FC_FAILURE\n"); 3988 rval = FC_FAILURE; 3989 } 3990 break; 3991 case QL_DIAG_CHKCMDQUE: 3992 for (i0 = 1, cnt = 0; i0 < MAX_OUTSTANDING_COMMANDS; 3993 i0++) { 3994 cnt += (pha->outstanding_cmds[i0] != NULL); 3995 } 3996 if (cnt != 0) { 3997 EL(ha, "failed, QL_DIAG_CHKCMDQUE " 3998 "FC_FAILURE\n"); 3999 rval = FC_FAILURE; 4000 } 4001 break; 4002 case QL_DIAG_FMWCHKSUM: 4003 if (ql_verify_checksum(ha) != QL_SUCCESS) { 4004 EL(ha, "failed, QL_DIAG_FMWCHKSUM " 4005 "FC_FAILURE\n"); 4006 rval = FC_FAILURE; 4007 } 4008 break; 4009 case QL_DIAG_SLFTST: 4010 if (ql_online_selftest(ha) != QL_SUCCESS) { 4011 EL(ha, "failed, QL_DIAG_SLFTST FC_FAILURE\n"); 4012 rval = FC_FAILURE; 4013 } 4014 ql_reset_chip(ha); 4015 set_flags |= ISP_ABORT_NEEDED; 4016 break; 4017 case QL_DIAG_REVLVL: 4018 if (cmd->pm_stat_len < 4019 sizeof (ql_adapter_revlvl_t)) { 4020 EL(ha, "failed, QL_DIAG_REVLVL FC_NOMEM, " 4021 "slen=%lxh, rlvllen=%lxh\n", 4022 cmd->pm_stat_len, 4023 sizeof (ql_adapter_revlvl_t)); 4024 rval = FC_NOMEM; 4025 } else { 4026 bcopy((void *)&(pha->adapter_stats->revlvl), 4027 cmd->pm_stat_buf, 4028 (size_t)cmd->pm_stat_len); 4029 cmd->pm_stat_len = 4030 sizeof (ql_adapter_revlvl_t); 4031 } 4032 break; 4033 case QL_DIAG_LPBMBX: 4034 4035 if (cmd->pm_data_len != sizeof (struct app_mbx_cmd)) { 4036 EL(ha, "failed, QL_DIAG_LPBMBX " 4037 "FC_INVALID_REQUEST, pmlen=%lxh, " 4038 "reqd=%lxh\n", cmd->pm_data_len, 4039 sizeof (struct app_mbx_cmd)); 4040 rval = FC_INVALID_REQUEST; 4041 break; 4042 } 4043 /* 4044 * Don't do the wrap test on a 2200 when the 4045 * firmware is running. 4046 */ 4047 if (!CFG_IST(ha, CFG_CTRL_2200)) { 4048 mcp = (app_mbx_cmd_t *)cmd->pm_data_buf; 4049 mr.mb[1] = mcp->mb[1]; 4050 mr.mb[2] = mcp->mb[2]; 4051 mr.mb[3] = mcp->mb[3]; 4052 mr.mb[4] = mcp->mb[4]; 4053 mr.mb[5] = mcp->mb[5]; 4054 mr.mb[6] = mcp->mb[6]; 4055 mr.mb[7] = mcp->mb[7]; 4056 4057 bcopy(&mr.mb[0], &mr.mb[10], 4058 sizeof (uint16_t) * 8); 4059 4060 if (ql_mbx_wrap_test(ha, &mr) != QL_SUCCESS) { 4061 EL(ha, "failed, QL_DIAG_LPBMBX " 4062 "FC_FAILURE\n"); 4063 rval = FC_FAILURE; 4064 break; 4065 } else { 4066 for (i0 = 1; i0 < 8; i0++) { 4067 if (mr.mb[i0] != 4068 mr.mb[i0 + 10]) { 4069 EL(ha, "failed, " 4070 "QL_DIAG_LPBMBX " 4071 "FC_FAILURE-2\n"); 4072 rval = FC_FAILURE; 4073 break; 4074 } 4075 } 4076 } 4077 4078 if (rval == FC_FAILURE) { 4079 (void) ql_flash_errlog(ha, 4080 FLASH_ERRLOG_ISP_ERR, 0, 4081 RD16_IO_REG(ha, hccr), 4082 RD16_IO_REG(ha, istatus)); 4083 set_flags |= ISP_ABORT_NEEDED; 4084 } 4085 } 4086 break; 4087 case QL_DIAG_LPBDTA: 4088 /* 4089 * For loopback data, we receive the 4090 * data back in pm_stat_buf. This provides 4091 * the user an opportunity to compare the 4092 * transmitted and received data. 4093 * 4094 * NB: lb->options are: 4095 * 0 --> Ten bit loopback 4096 * 1 --> One bit loopback 4097 * 2 --> External loopback 4098 */ 4099 if (cmd->pm_data_len > 65536) { 4100 rval = FC_TOOMANY; 4101 EL(ha, "failed, QL_DIAG_LPBDTA " 4102 "FC_TOOMANY=%lxh\n", cmd->pm_data_len); 4103 break; 4104 } 4105 if (ql_get_dma_mem(ha, &buffer_xmt, 4106 (uint32_t)cmd->pm_data_len, LITTLE_ENDIAN_DMA, 4107 QL_DMA_DATA_ALIGN) != QL_SUCCESS) { 4108 EL(ha, "failed, QL_DIAG_LPBDTA FC_NOMEM\n"); 4109 rval = FC_NOMEM; 4110 break; 4111 } 4112 if (ql_get_dma_mem(ha, &buffer_rcv, 4113 (uint32_t)cmd->pm_data_len, LITTLE_ENDIAN_DMA, 4114 QL_DMA_DATA_ALIGN) != QL_SUCCESS) { 4115 EL(ha, "failed, QL_DIAG_LPBDTA FC_NOMEM-2\n"); 4116 rval = FC_NOMEM; 4117 break; 4118 } 4119 ddi_rep_put8(buffer_xmt.acc_handle, 4120 (uint8_t *)cmd->pm_data_buf, 4121 (uint8_t *)buffer_xmt.bp, 4122 cmd->pm_data_len, DDI_DEV_AUTOINCR); 4123 4124 /* 22xx's adapter must be in loop mode for test. */ 4125 if (CFG_IST(ha, CFG_CTRL_2200)) { 4126 bptr = &ha->init_ctrl_blk.cb.add_fw_opt[0]; 4127 if (ha->flags & POINT_TO_POINT || 4128 (ha->task_daemon_flags & LOOP_DOWN && 4129 *bptr & (BIT_6 | BIT_5 | BIT_4))) { 4130 cnt = *bptr; 4131 *bptr = (uint8_t) 4132 (*bptr & ~(BIT_6|BIT_5|BIT_4)); 4133 (void) ql_abort_isp(ha); 4134 *bptr = (uint8_t)cnt; 4135 } 4136 } 4137 4138 /* Shutdown IP. */ 4139 if (pha->flags & IP_INITIALIZED) { 4140 (void) ql_shutdown_ip(pha); 4141 } 4142 4143 lb = (lbp_t *)cmd->pm_cmd_buf; 4144 lb->transfer_count = 4145 (uint32_t)cmd->pm_data_len; 4146 lb->transfer_segment_count = 0; 4147 lb->receive_segment_count = 0; 4148 lb->transfer_data_address = 4149 buffer_xmt.cookie.dmac_address; 4150 lb->receive_data_address = 4151 buffer_rcv.cookie.dmac_address; 4152 4153 if ((lb->options & 7) == 2 && 4154 pha->task_daemon_flags & 4155 (QL_LOOP_TRANSITION | LOOP_DOWN)) { 4156 /* Loop must be up for external */ 4157 EL(ha, "failed, QL_DIAG_LPBDTA FC_TRAN_BUSY\n"); 4158 rval = FC_TRAN_BUSY; 4159 } else if (ql_loop_back(ha, 0, lb, 4160 buffer_xmt.cookie.dmac_notused, 4161 buffer_rcv.cookie.dmac_notused) == QL_SUCCESS) { 4162 bzero((void *)cmd->pm_stat_buf, 4163 cmd->pm_stat_len); 4164 ddi_rep_get8(buffer_rcv.acc_handle, 4165 (uint8_t *)cmd->pm_stat_buf, 4166 (uint8_t *)buffer_rcv.bp, 4167 cmd->pm_stat_len, DDI_DEV_AUTOINCR); 4168 } else { 4169 EL(ha, "failed, QL_DIAG_LPBDTA FC_FAILURE\n"); 4170 rval = FC_FAILURE; 4171 } 4172 4173 ql_free_phys(ha, &buffer_xmt); 4174 ql_free_phys(ha, &buffer_rcv); 4175 4176 /* Needed to recover the f/w */ 4177 set_flags |= ISP_ABORT_NEEDED; 4178 4179 /* Restart IP if it was shutdown. */ 4180 if (pha->flags & IP_ENABLED && 4181 !(pha->flags & IP_INITIALIZED)) { 4182 (void) ql_initialize_ip(pha); 4183 ql_isp_rcvbuf(pha); 4184 } 4185 4186 break; 4187 case QL_DIAG_ECHO: { 4188 /* 4189 * issue an echo command with a user supplied 4190 * data pattern and destination address 4191 */ 4192 echo_t echo; /* temp echo struct */ 4193 4194 /* Setup echo cmd & adjust for platform */ 4195 opcode = QL_ECHO_CMD; 4196 BIG_ENDIAN_32(&opcode); 4197 4198 /* 4199 * due to limitations in the ql 4200 * firmaware the echo data field is 4201 * limited to 220 4202 */ 4203 if ((cmd->pm_cmd_len > QL_ECHO_CMD_LENGTH) || 4204 (cmd->pm_stat_len > QL_ECHO_CMD_LENGTH)) { 4205 EL(ha, "failed, QL_DIAG_ECHO FC_TOOMANY, " 4206 "cmdl1=%lxh, statl2=%lxh\n", 4207 cmd->pm_cmd_len, cmd->pm_stat_len); 4208 rval = FC_TOOMANY; 4209 break; 4210 } 4211 4212 /* 4213 * the input data buffer has the user 4214 * supplied data pattern. The "echoed" 4215 * data will be DMAed into the output 4216 * data buffer. Therefore the length 4217 * of the output buffer must be equal 4218 * to or greater then the input buffer 4219 * length 4220 */ 4221 if (cmd->pm_cmd_len > cmd->pm_stat_len) { 4222 EL(ha, "failed, QL_DIAG_ECHO FC_TOOMANY-2," 4223 " cmdl1=%lxh, statl2=%lxh\n", 4224 cmd->pm_cmd_len, cmd->pm_stat_len); 4225 rval = FC_TOOMANY; 4226 break; 4227 } 4228 /* add four bytes for the opcode */ 4229 echo.transfer_count = (uint32_t)(cmd->pm_cmd_len + 4); 4230 4231 /* 4232 * are we 32 or 64 bit addressed??? 4233 * We need to get the appropriate 4234 * DMA and set the command options; 4235 * 64 bit (bit 6) or 32 bit 4236 * (no bit 6) addressing. 4237 * while we are at it lets ask for 4238 * real echo (bit 15) 4239 */ 4240 echo.options = BIT_15; 4241 if (CFG_IST(ha, CFG_ENABLE_64BIT_ADDRESSING) && 4242 !(CFG_IST(ha, CFG_CTRL_81XX))) { 4243 echo.options = (uint16_t) 4244 (echo.options | BIT_6); 4245 } 4246 4247 /* 4248 * Set up the DMA mappings for the 4249 * output and input data buffers. 4250 * First the output buffer 4251 */ 4252 if (ql_get_dma_mem(ha, &buffer_xmt, 4253 (uint32_t)(cmd->pm_data_len + 4), 4254 LITTLE_ENDIAN_DMA, 4255 QL_DMA_DATA_ALIGN) != QL_SUCCESS) { 4256 EL(ha, "failed, QL_DIAG_ECHO FC_NOMEM\n"); 4257 rval = FC_NOMEM; 4258 break; 4259 } 4260 echo.transfer_data_address = buffer_xmt.cookie; 4261 4262 /* Next the input buffer */ 4263 if (ql_get_dma_mem(ha, &buffer_rcv, 4264 (uint32_t)(cmd->pm_data_len + 4), 4265 LITTLE_ENDIAN_DMA, 4266 QL_DMA_DATA_ALIGN) != QL_SUCCESS) { 4267 /* 4268 * since we could not allocate 4269 * DMA space for the input 4270 * buffer we need to clean up 4271 * by freeing the DMA space 4272 * we allocated for the output 4273 * buffer 4274 */ 4275 ql_free_phys(ha, &buffer_xmt); 4276 EL(ha, "failed, QL_DIAG_ECHO FC_NOMEM-2\n"); 4277 rval = FC_NOMEM; 4278 break; 4279 } 4280 echo.receive_data_address = buffer_rcv.cookie; 4281 4282 /* 4283 * copy the 4 byte ECHO op code to the 4284 * allocated DMA space 4285 */ 4286 ddi_rep_put8(buffer_xmt.acc_handle, (uint8_t *)&opcode, 4287 (uint8_t *)buffer_xmt.bp, 4, DDI_DEV_AUTOINCR); 4288 4289 /* 4290 * copy the user supplied data to the 4291 * allocated DMA space 4292 */ 4293 ddi_rep_put8(buffer_xmt.acc_handle, 4294 (uint8_t *)cmd->pm_cmd_buf, 4295 (uint8_t *)buffer_xmt.bp + 4, cmd->pm_cmd_len, 4296 DDI_DEV_AUTOINCR); 4297 4298 /* Shutdown IP. */ 4299 if (pha->flags & IP_INITIALIZED) { 4300 (void) ql_shutdown_ip(pha); 4301 } 4302 4303 /* send the echo */ 4304 if (ql_echo(ha, 0, &echo) == QL_SUCCESS) { 4305 ddi_rep_put8(buffer_rcv.acc_handle, 4306 (uint8_t *)buffer_rcv.bp + 4, 4307 (uint8_t *)cmd->pm_stat_buf, 4308 cmd->pm_stat_len, DDI_DEV_AUTOINCR); 4309 } else { 4310 EL(ha, "failed, QL_DIAG_ECHO FC_FAILURE\n"); 4311 rval = FC_FAILURE; 4312 } 4313 4314 /* Restart IP if it was shutdown. */ 4315 if (pha->flags & IP_ENABLED && 4316 !(pha->flags & IP_INITIALIZED)) { 4317 (void) ql_initialize_ip(pha); 4318 ql_isp_rcvbuf(pha); 4319 } 4320 /* free up our DMA buffers */ 4321 ql_free_phys(ha, &buffer_xmt); 4322 ql_free_phys(ha, &buffer_rcv); 4323 break; 4324 } 4325 default: 4326 EL(ha, "unknown=%xh, FC_PORT_DIAG " 4327 "FC_INVALID_REQUEST\n", cmd->pm_cmd_flags); 4328 rval = FC_INVALID_REQUEST; 4329 break; 4330 } 4331 PORTMANAGE_UNLOCK(ha); 4332 break; 4333 case FC_PORT_LINK_STATE: 4334 /* Check for name equal to null. */ 4335 for (index = 0; index < 8 && index < cmd->pm_cmd_len; 4336 index++) { 4337 if (cmd->pm_cmd_buf[index] != 0) { 4338 break; 4339 } 4340 } 4341 4342 /* If name not null. */ 4343 if (index < 8 && cmd->pm_cmd_len >= 8) { 4344 /* Locate device queue. */ 4345 tq = NULL; 4346 for (index = 0; index < DEVICE_HEAD_LIST_SIZE && 4347 tq == NULL; index++) { 4348 for (link = ha->dev[index].first; link != NULL; 4349 link = link->next) { 4350 tq = link->base_address; 4351 4352 if (bcmp((void *)&tq->port_name[0], 4353 (void *)cmd->pm_cmd_buf, 8) == 0) { 4354 break; 4355 } else { 4356 tq = NULL; 4357 } 4358 } 4359 } 4360 4361 if (tq != NULL && VALID_DEVICE_ID(ha, tq->loop_id)) { 4362 cmd->pm_stat_buf[0] = (int8_t)LSB(ha->state); 4363 cmd->pm_stat_buf[1] = (int8_t)MSB(ha->state); 4364 } else { 4365 cnt = FC_PORT_SPEED_MASK(ha->state) | 4366 FC_STATE_OFFLINE; 4367 cmd->pm_stat_buf[0] = (int8_t)LSB(cnt); 4368 cmd->pm_stat_buf[1] = (int8_t)MSB(cnt); 4369 } 4370 } else { 4371 cmd->pm_stat_buf[0] = (int8_t)LSB(ha->state); 4372 cmd->pm_stat_buf[1] = (int8_t)MSB(ha->state); 4373 } 4374 break; 4375 case FC_PORT_INITIALIZE: 4376 if (cmd->pm_cmd_len >= 8) { 4377 tq = NULL; 4378 for (index = 0; index < DEVICE_HEAD_LIST_SIZE && 4379 tq == NULL; index++) { 4380 for (link = ha->dev[index].first; link != NULL; 4381 link = link->next) { 4382 tq = link->base_address; 4383 4384 if (bcmp((void *)&tq->port_name[0], 4385 (void *)cmd->pm_cmd_buf, 8) == 0) { 4386 if (!VALID_DEVICE_ID(ha, 4387 tq->loop_id)) { 4388 tq = NULL; 4389 } 4390 break; 4391 } else { 4392 tq = NULL; 4393 } 4394 } 4395 } 4396 4397 if (tq == NULL || ql_target_reset(ha, tq, 4398 ha->loop_reset_delay) != QL_SUCCESS) { 4399 EL(ha, "failed, FC_PORT_INITIALIZE " 4400 "FC_FAILURE\n"); 4401 rval = FC_FAILURE; 4402 } 4403 } else { 4404 EL(ha, "failed, FC_PORT_INITIALIZE FC_FAILURE-2, " 4405 "clen=%lxh\n", cmd->pm_cmd_len); 4406 4407 rval = FC_FAILURE; 4408 } 4409 break; 4410 case FC_PORT_RLS: 4411 if (cmd->pm_data_len < sizeof (fc_rls_acc_t)) { 4412 EL(ha, "failed, buffer size passed: %lxh, " 4413 "req: %lxh\n", cmd->pm_data_len, 4414 (sizeof (fc_rls_acc_t))); 4415 rval = FC_FAILURE; 4416 } else if (LOOP_NOT_READY(pha)) { 4417 EL(ha, "loop NOT ready\n"); 4418 bzero(cmd->pm_data_buf, cmd->pm_data_len); 4419 } else if (ql_get_link_status(ha, ha->loop_id, 4420 cmd->pm_data_len, cmd->pm_data_buf, 0) != QL_SUCCESS) { 4421 EL(ha, "failed, FC_PORT_RLS FC_FAILURE\n"); 4422 rval = FC_FAILURE; 4423#ifdef _BIG_ENDIAN 4424 } else { 4425 fc_rls_acc_t *rls; 4426 4427 rls = (fc_rls_acc_t *)cmd->pm_data_buf; 4428 LITTLE_ENDIAN_32(&rls->rls_link_fail); 4429 LITTLE_ENDIAN_32(&rls->rls_sync_loss); 4430 LITTLE_ENDIAN_32(&rls->rls_sig_loss); 4431 LITTLE_ENDIAN_32(&rls->rls_invalid_crc); 4432#endif /* _BIG_ENDIAN */ 4433 } 4434 break; 4435 case FC_PORT_GET_NODE_ID: 4436 if (ql_get_rnid_params(ha, cmd->pm_data_len, 4437 cmd->pm_data_buf) != QL_SUCCESS) { 4438 EL(ha, "failed, FC_PORT_GET_NODE_ID FC_FAILURE\n"); 4439 rval = FC_FAILURE; 4440 } 4441 break; 4442 case FC_PORT_SET_NODE_ID: 4443 if (ql_set_rnid_params(ha, cmd->pm_data_len, 4444 cmd->pm_data_buf) != QL_SUCCESS) { 4445 EL(ha, "failed, FC_PORT_SET_NODE_ID FC_FAILURE\n"); 4446 rval = FC_FAILURE; 4447 } 4448 break; 4449 case FC_PORT_DOWNLOAD_FCODE: 4450 PORTMANAGE_LOCK(ha); 4451 if ((CFG_IST(ha, CFG_CTRL_242581)) == 0) { 4452 rval = ql_load_flash(ha, (uint8_t *)cmd->pm_data_buf, 4453 (uint32_t)cmd->pm_data_len); 4454 } else { 4455 if (cmd->pm_data_buf[0] == 4 && 4456 cmd->pm_data_buf[8] == 0 && 4457 cmd->pm_data_buf[9] == 0x10 && 4458 cmd->pm_data_buf[10] == 0 && 4459 cmd->pm_data_buf[11] == 0) { 4460 rval = ql_24xx_load_flash(ha, 4461 (uint8_t *)cmd->pm_data_buf, 4462 (uint32_t)cmd->pm_data_len, 4463 ha->flash_fw_addr << 2); 4464 } else { 4465 rval = ql_24xx_load_flash(ha, 4466 (uint8_t *)cmd->pm_data_buf, 4467 (uint32_t)cmd->pm_data_len, 0); 4468 } 4469 } 4470 4471 if (rval != QL_SUCCESS) { 4472 EL(ha, "failed, FC_PORT_DOWNLOAD_FCODE FC_FAILURE\n"); 4473 rval = FC_FAILURE; 4474 } else { 4475 rval = FC_SUCCESS; 4476 } 4477 ql_reset_chip(ha); 4478 set_flags |= ISP_ABORT_NEEDED; 4479 PORTMANAGE_UNLOCK(ha); 4480 break; 4481 default: 4482 EL(ha, "unknown=%xh, FC_BADCMD\n", cmd->pm_cmd_code); 4483 rval = FC_BADCMD; 4484 break; 4485 } 4486 4487 /* Wait for suspension to end. */ 4488 ql_awaken_task_daemon(ha, NULL, set_flags, DRIVER_STALL); 4489 timer = 0; 4490 4491 while (timer++ < 3000 && 4492 ha->task_daemon_flags & (QL_LOOP_TRANSITION | DRIVER_STALL)) { 4493 ql_delay(ha, 10000); 4494 } 4495 4496 ql_restart_queues(ha); 4497 4498 if (rval != FC_SUCCESS) { 4499 EL(ha, "failed, rval = %xh\n", rval); 4500 } else { 4501 /*EMPTY*/ 4502 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance); 4503 } 4504 4505 return (rval); 4506} 4507 4508static opaque_t 4509ql_get_device(opaque_t fca_handle, fc_portid_t d_id) 4510{ 4511 port_id_t id; 4512 ql_adapter_state_t *ha; 4513 ql_tgt_t *tq; 4514 4515 id.r.rsvd_1 = 0; 4516 id.b24 = d_id.port_id; 4517 4518 ha = ql_fca_handle_to_state(fca_handle); 4519 if (ha == NULL) { 4520 QL_PRINT_2(CE_CONT, "failed, no adapter=%ph\n", 4521 (void *)fca_handle); 4522 return (NULL); 4523 } 4524 QL_PRINT_3(CE_CONT, "(%d): started, d_id=%xh\n", ha->instance, id.b24); 4525 4526 tq = ql_d_id_to_queue(ha, id); 4527 4528 if (tq == NULL) { 4529 EL(ha, "failed, tq=NULL\n"); 4530 } else { 4531 /*EMPTY*/ 4532 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance); 4533 } 4534 return (tq); 4535} 4536 4537/* ************************************************************************ */ 4538/* FCA Driver Local Support Functions. */ 4539/* ************************************************************************ */ 4540 4541/* 4542 * ql_cmd_setup 4543 * Verifies proper command. 4544 * 4545 * Input: 4546 * fca_handle = handle setup by ql_bind_port(). 4547 * pkt = pointer to fc_packet. 4548 * rval = pointer for return value. 4549 * 4550 * Returns: 4551 * Adapter state pointer, NULL = failure. 4552 * 4553 * Context: 4554 * Kernel context. 4555 */ 4556static ql_adapter_state_t * 4557ql_cmd_setup(opaque_t fca_handle, fc_packet_t *pkt, int *rval) 4558{ 4559 ql_adapter_state_t *ha, *pha; 4560 ql_srb_t *sp = (ql_srb_t *)pkt->pkt_fca_private; 4561 ql_tgt_t *tq; 4562 port_id_t d_id; 4563 4564 pkt->pkt_resp_resid = 0; 4565 pkt->pkt_data_resid = 0; 4566 4567 /* check that the handle is assigned by this FCA */ 4568 ha = ql_fca_handle_to_state(fca_handle); 4569 if (ha == NULL) { 4570 *rval = FC_UNBOUND; 4571 QL_PRINT_2(CE_CONT, "failed, no adapter=%ph\n", 4572 (void *)fca_handle); 4573 return (NULL); 4574 } 4575 pha = ha->pha; 4576 4577 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance); 4578 4579 if (ddi_in_panic() || pkt->pkt_tran_flags & FC_TRAN_DUMPING) { 4580 return (ha); 4581 } 4582 4583 if (!(pha->flags & ONLINE)) { 4584 pkt->pkt_state = FC_PKT_LOCAL_RJT; 4585 pkt->pkt_reason = FC_REASON_HW_ERROR; 4586 *rval = FC_TRANSPORT_ERROR; 4587 EL(ha, "failed, not online hf=%xh\n", pha->flags); 4588 return (NULL); 4589 } 4590 4591 /* Exit on loop down. */ 4592 if (CFG_IST(ha, CFG_ENABLE_LINK_DOWN_REPORTING) && 4593 pha->task_daemon_flags & LOOP_DOWN && 4594 pha->loop_down_timer <= pha->loop_down_abort_time) { 4595 pkt->pkt_state = FC_PKT_PORT_OFFLINE; 4596 pkt->pkt_reason = FC_REASON_NO_CONNECTION; 4597 *rval = FC_OFFLINE; 4598 EL(ha, "failed, loop down tdf=%xh\n", pha->task_daemon_flags); 4599 return (NULL); 4600 } 4601 4602 if (pkt->pkt_cmd_fhdr.r_ctl == R_CTL_COMMAND && 4603 pkt->pkt_cmd_fhdr.type == FC_TYPE_SCSI_FCP) { 4604 tq = (ql_tgt_t *)pkt->pkt_fca_device; 4605 if ((tq == NULL) || (!VALID_DEVICE_ID(ha, tq->loop_id))) { 4606 d_id.r.rsvd_1 = 0; 4607 d_id.b24 = pkt->pkt_cmd_fhdr.d_id; 4608 tq = ql_d_id_to_queue(ha, d_id); 4609 4610 pkt->pkt_fca_device = (opaque_t)tq; 4611 } 4612 4613 if (tq != NULL) { 4614 DEVICE_QUEUE_LOCK(tq); 4615 if (tq->flags & (TQF_RSCN_RCVD | 4616 TQF_NEED_AUTHENTICATION)) { 4617 *rval = FC_DEVICE_BUSY; 4618 DEVICE_QUEUE_UNLOCK(tq); 4619 EL(ha, "failed, busy qf=%xh, d_id=%xh\n", 4620 tq->flags, tq->d_id.b24); 4621 return (NULL); 4622 } 4623 DEVICE_QUEUE_UNLOCK(tq); 4624 } 4625 } 4626 4627 /* 4628 * Check DMA pointers. 4629 */ 4630 *rval = DDI_SUCCESS; 4631 if (pkt->pkt_cmd_acc != NULL && pkt->pkt_cmdlen) { 4632 QL_CLEAR_DMA_HANDLE(pkt->pkt_cmd_dma); 4633 *rval = ddi_check_dma_handle(pkt->pkt_cmd_dma); 4634 if (*rval == DDI_SUCCESS) { 4635 *rval = ddi_check_acc_handle(pkt->pkt_cmd_acc); 4636 } 4637 } 4638 4639 if (pkt->pkt_resp_acc != NULL && *rval == DDI_SUCCESS && 4640 pkt->pkt_rsplen != 0) { 4641 QL_CLEAR_DMA_HANDLE(pkt->pkt_resp_dma); 4642 *rval = ddi_check_dma_handle(pkt->pkt_resp_dma); 4643 if (*rval == DDI_SUCCESS) { 4644 *rval = ddi_check_acc_handle(pkt->pkt_resp_acc); 4645 } 4646 } 4647 4648 /* 4649 * Minimum branch conditional; Change it with care. 4650 */ 4651 if (((pkt->pkt_data_acc != NULL) & (*rval == DDI_SUCCESS) & 4652 (pkt->pkt_datalen != 0)) != 0) { 4653 QL_CLEAR_DMA_HANDLE(pkt->pkt_data_dma); 4654 *rval = ddi_check_dma_handle(pkt->pkt_data_dma); 4655 if (*rval == DDI_SUCCESS) { 4656 *rval = ddi_check_acc_handle(pkt->pkt_data_acc); 4657 } 4658 } 4659 4660 if (*rval != DDI_SUCCESS) { 4661 pkt->pkt_state = FC_PKT_TRAN_ERROR; 4662 pkt->pkt_reason = FC_REASON_DMA_ERROR; 4663 4664 /* Do command callback. */ 4665 if (!(pkt->pkt_tran_flags & FC_TRAN_NO_INTR) && pkt->pkt_comp) { 4666 ql_awaken_task_daemon(ha, sp, 0, 0); 4667 } 4668 *rval = FC_BADPACKET; 4669 EL(ha, "failed, bad DMA pointers\n"); 4670 return (NULL); 4671 } 4672 4673 if (sp->magic_number != QL_FCA_BRAND) { 4674 *rval = FC_BADPACKET; 4675 EL(ha, "failed, magic number=%xh\n", sp->magic_number); 4676 return (NULL); 4677 } 4678 *rval = FC_SUCCESS; 4679 4680 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance); 4681 4682 return (ha); 4683} 4684 4685/* 4686 * ql_els_plogi 4687 * Issue a extended link service port login request. 4688 * 4689 * Input: 4690 * ha = adapter state pointer. 4691 * pkt = pointer to fc_packet. 4692 * 4693 * Returns: 4694 * FC_SUCCESS - the packet was accepted for transport. 4695 * FC_TRANSPORT_ERROR - a transport error occurred. 4696 * 4697 * Context: 4698 * Kernel context. 4699 */ 4700static int 4701ql_els_plogi(ql_adapter_state_t *ha, fc_packet_t *pkt) 4702{ 4703 ql_tgt_t *tq = NULL; 4704 port_id_t d_id; 4705 la_els_logi_t acc; 4706 class_svc_param_t *class3_param; 4707 int ret; 4708 int rval = FC_SUCCESS; 4709 4710 QL_PRINT_3(CE_CONT, "(%d): started, d_id=%xh\n", ha->instance, 4711 pkt->pkt_cmd_fhdr.d_id); 4712 4713 TASK_DAEMON_LOCK(ha); 4714 if (!(ha->task_daemon_flags & STATE_ONLINE)) { 4715 TASK_DAEMON_UNLOCK(ha); 4716 QL_PRINT_3(CE_CONT, "(%d): offline done\n", ha->instance); 4717 return (FC_OFFLINE); 4718 } 4719 TASK_DAEMON_UNLOCK(ha); 4720 4721 bzero(&acc, sizeof (acc)); 4722 d_id.b24 = pkt->pkt_cmd_fhdr.d_id; 4723 4724 ret = QL_SUCCESS; 4725 4726 if (CFG_IST(ha, CFG_CTRL_2425) && ha->topology & QL_N_PORT) { 4727 /* 4728 * In p2p topology he sends a PLOGI after determining 4729 * he has the N_Port login initiative. 4730 */ 4731 ret = ql_p2p_plogi(ha, pkt); 4732 } 4733 if (ret == QL_CONSUMED) { 4734 return (ret); 4735 } 4736 4737 switch (ret = ql_login_port(ha, d_id)) { 4738 case QL_SUCCESS: 4739 tq = ql_d_id_to_queue(ha, d_id); 4740 break; 4741 4742 case QL_LOOP_ID_USED: 4743 if ((ret = ql_login_port(ha, d_id)) == QL_SUCCESS) { 4744 tq = ql_d_id_to_queue(ha, d_id); 4745 } 4746 break; 4747 4748 default: 4749 break; 4750 } 4751 4752 if (ret != QL_SUCCESS) { 4753 /* 4754 * Invalidate this entry so as to seek a fresh loop ID 4755 * in case firmware reassigns it to something else 4756 */ 4757 tq = ql_d_id_to_queue(ha, d_id); 4758 if (tq && (ret != QL_MEMORY_ALLOC_FAILED)) { 4759 tq->loop_id = PORT_NO_LOOP_ID; 4760 } 4761 } else if (tq) { 4762 (void) ql_get_port_database(ha, tq, PDF_ADISC); 4763 } 4764 4765 if (tq != NULL && VALID_DEVICE_ID(ha, tq->loop_id) && 4766 (ret != QL_MEMORY_ALLOC_FAILED) && PD_PORT_LOGIN(tq)) { 4767 4768 /* Build ACC. */ 4769 acc.ls_code.ls_code = LA_ELS_ACC; 4770 acc.common_service.fcph_version = 0x2006; 4771 acc.common_service.cmn_features = 0x8800; 4772 CFG_IST(ha, CFG_CTRL_242581) ? 4773 (acc.common_service.rx_bufsize = CHAR_TO_SHORT( 4774 ha->init_ctrl_blk.cb24.max_frame_length[0], 4775 ha->init_ctrl_blk.cb24.max_frame_length[1])) : 4776 (acc.common_service.rx_bufsize = CHAR_TO_SHORT( 4777 ha->init_ctrl_blk.cb.max_frame_length[0], 4778 ha->init_ctrl_blk.cb.max_frame_length[1])); 4779 acc.common_service.conc_sequences = 0xff; 4780 acc.common_service.relative_offset = 0x03; 4781 acc.common_service.e_d_tov = 0x7d0; 4782 4783 bcopy((void *)&tq->port_name[0], 4784 (void *)&acc.nport_ww_name.raw_wwn[0], 8); 4785 bcopy((void *)&tq->node_name[0], 4786 (void *)&acc.node_ww_name.raw_wwn[0], 8); 4787 4788 class3_param = (class_svc_param_t *)&acc.class_3; 4789 class3_param->class_valid_svc_opt = 0x8000; 4790 class3_param->recipient_ctl = tq->class3_recipient_ctl; 4791 class3_param->rcv_data_size = tq->class3_rcv_data_size; 4792 class3_param->conc_sequences = tq->class3_conc_sequences; 4793 class3_param->open_sequences_per_exch = 4794 tq->class3_open_sequences_per_exch; 4795 4796 if ((ql_busy_plogi(ha, pkt, tq) == FC_TRAN_BUSY)) { 4797 acc.ls_code.ls_code = LA_ELS_RJT; 4798 pkt->pkt_state = FC_PKT_TRAN_BSY; 4799 pkt->pkt_reason = FC_REASON_XCHG_BSY; 4800 EL(ha, "LA_ELS_RJT, FC_REASON_XCHG_BSY\n"); 4801 rval = FC_TRAN_BUSY; 4802 } else { 4803 DEVICE_QUEUE_LOCK(tq); 4804 tq->logout_sent = 0; 4805 tq->flags &= ~TQF_NEED_AUTHENTICATION; 4806 if (CFG_IST(ha, CFG_CTRL_242581)) { 4807 tq->flags |= TQF_IIDMA_NEEDED; 4808 } 4809 DEVICE_QUEUE_UNLOCK(tq); 4810 4811 if (CFG_IST(ha, CFG_CTRL_242581)) { 4812 TASK_DAEMON_LOCK(ha); 4813 ha->task_daemon_flags |= TD_IIDMA_NEEDED; 4814 TASK_DAEMON_UNLOCK(ha); 4815 } 4816 4817 pkt->pkt_state = FC_PKT_SUCCESS; 4818 } 4819 } else { 4820 /* Build RJT. */ 4821 acc.ls_code.ls_code = LA_ELS_RJT; 4822 4823 switch (ret) { 4824 case QL_FUNCTION_TIMEOUT: 4825 pkt->pkt_state = FC_PKT_TIMEOUT; 4826 pkt->pkt_reason = FC_REASON_HW_ERROR; 4827 break; 4828 4829 case QL_MEMORY_ALLOC_FAILED: 4830 pkt->pkt_state = FC_PKT_LOCAL_BSY; 4831 pkt->pkt_reason = FC_REASON_NOMEM; 4832 rval = FC_TRAN_BUSY; 4833 break; 4834 4835 case QL_FABRIC_NOT_INITIALIZED: 4836 pkt->pkt_state = FC_PKT_FABRIC_BSY; 4837 pkt->pkt_reason = FC_REASON_NO_CONNECTION; 4838 rval = FC_TRAN_BUSY; 4839 break; 4840 4841 default: 4842 pkt->pkt_state = FC_PKT_TRAN_ERROR; 4843 pkt->pkt_reason = FC_REASON_NO_CONNECTION; 4844 break; 4845 } 4846 4847 EL(ha, "Plogi unsuccess for %xh state %xh reason %xh " 4848 "ret %xh rval %xh\n", d_id.b24, pkt->pkt_state, 4849 pkt->pkt_reason, ret, rval); 4850 } 4851 4852 if (tq != NULL) { 4853 DEVICE_QUEUE_LOCK(tq); 4854 tq->flags &= ~(TQF_PLOGI_PROGRS | TQF_QUEUE_SUSPENDED); 4855 if (rval == FC_TRAN_BUSY) { 4856 if (tq->d_id.b24 != BROADCAST_ADDR) { 4857 tq->flags |= TQF_NEED_AUTHENTICATION; 4858 } 4859 } 4860 DEVICE_QUEUE_UNLOCK(tq); 4861 } 4862 4863 ddi_rep_put8(pkt->pkt_resp_acc, (uint8_t *)&acc, 4864 (uint8_t *)pkt->pkt_resp, sizeof (acc), DDI_DEV_AUTOINCR); 4865 4866 if (rval != FC_SUCCESS) { 4867 EL(ha, "failed, rval = %xh\n", rval); 4868 } else { 4869 /*EMPTY*/ 4870 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance); 4871 } 4872 return (rval); 4873} 4874 4875/* 4876 * ql_p2p_plogi 4877 * Start an extended link service port login request using 4878 * an ELS Passthru iocb. 4879 * 4880 * Input: 4881 * ha = adapter state pointer. 4882 * pkt = pointer to fc_packet. 4883 * 4884 * Returns: 4885 * QL_CONSUMMED - the iocb was queued for transport. 4886 * 4887 * Context: 4888 * Kernel context. 4889 */ 4890static int 4891ql_p2p_plogi(ql_adapter_state_t *ha, fc_packet_t *pkt) 4892{ 4893 uint16_t id; 4894 ql_tgt_t tmp; 4895 ql_tgt_t *tq = &tmp; 4896 int rval; 4897 4898 tq->d_id.b.al_pa = 0; 4899 tq->d_id.b.area = 0; 4900 tq->d_id.b.domain = 0; 4901 4902 /* 4903 * Verify that the port database hasn't moved beneath our feet by 4904 * switching to the appropriate n_port_handle if necessary. This is 4905 * less unplesant than the error recovery if the wrong one is used. 4906 */ 4907 for (id = 0; id <= LAST_LOCAL_LOOP_ID; id++) { 4908 tq->loop_id = id; 4909 rval = ql_get_port_database(ha, tq, PDF_NONE); 4910 EL(ha, "rval=%xh\n", rval); 4911 /* check all the ones not logged in for possible use */ 4912 if (rval == QL_NOT_LOGGED_IN) { 4913 if (tq->master_state == PD_STATE_PLOGI_PENDING) { 4914 ha->n_port->n_port_handle = tq->loop_id; 4915 EL(ha, "n_port_handle =%xh, master state=%x\n", 4916 tq->loop_id, tq->master_state); 4917 break; 4918 } 4919 /* 4920 * Use a 'port unavailable' entry only 4921 * if we used it before. 4922 */ 4923 if (tq->master_state == PD_STATE_PORT_UNAVAILABLE) { 4924 /* if the port_id matches, reuse it */ 4925 if (pkt->pkt_cmd_fhdr.d_id == tq->d_id.b24) { 4926 EL(ha, "n_port_handle =%xh," 4927 "master state=%xh\n", 4928 tq->loop_id, tq->master_state); 4929 break; 4930 } else if (tq->loop_id == 4931 ha->n_port->n_port_handle) { 4932 // avoid a lint error 4933 uint16_t *hndl; 4934 uint16_t val; 4935 4936 hndl = &ha->n_port->n_port_handle; 4937 val = *hndl; 4938 val++; 4939 val++; 4940 *hndl = val; 4941 } 4942 EL(ha, "rval=%xh, id=%d, n_port_handle =%xh, " 4943 "master state=%x\n", rval, id, tq->loop_id, 4944 tq->master_state); 4945 } 4946 4947 } 4948 if (rval == QL_SUCCESS) { 4949 if ((tq->flags & TQF_INITIATOR_DEVICE) == 0) { 4950 ha->n_port->n_port_handle = tq->loop_id; 4951 EL(ha, "n_port_handle =%xh, master state=%x\n", 4952 tq->loop_id, tq->master_state); 4953 break; 4954 } 4955 EL(ha, "rval=%xh, id=%d, n_port_handle =%xh, " 4956 "master state=%x\n", rval, id, tq->loop_id, 4957 tq->master_state); 4958 } 4959 } 4960 (void) ddi_dma_sync(pkt->pkt_cmd_dma, 0, 0, DDI_DMA_SYNC_FORDEV); 4961 4962 ql_start_iocb(ha, (ql_srb_t *)pkt->pkt_fca_private); 4963 4964 return (QL_CONSUMED); 4965} 4966 4967 4968/* 4969 * ql_els_flogi 4970 * Issue a extended link service fabric login request. 4971 * 4972 * Input: 4973 * ha = adapter state pointer. 4974 * pkt = pointer to fc_packet. 4975 * 4976 * Returns: 4977 * FC_SUCCESS - the packet was accepted for transport. 4978 * FC_TRANSPORT_ERROR - a transport error occurred. 4979 * 4980 * Context: 4981 * Kernel context. 4982 */ 4983static int 4984ql_els_flogi(ql_adapter_state_t *ha, fc_packet_t *pkt) 4985{ 4986 ql_tgt_t *tq = NULL; 4987 port_id_t d_id; 4988 la_els_logi_t acc; 4989 class_svc_param_t *class3_param; 4990 int rval = FC_SUCCESS; 4991 int accept = 0; 4992 4993 QL_PRINT_3(CE_CONT, "(%d): started, d_id=%xh\n", ha->instance, 4994 pkt->pkt_cmd_fhdr.d_id); 4995 4996 bzero(&acc, sizeof (acc)); 4997 d_id.b24 = pkt->pkt_cmd_fhdr.d_id; 4998 4999 if (CFG_IST(ha, CFG_CTRL_2425) && ha->topology & QL_N_PORT) { 5000 /* 5001 * d_id of zero in a FLOGI accept response in a point to point 5002 * topology triggers evaluation of N Port login initiative. 5003 */ 5004 pkt->pkt_resp_fhdr.d_id = 0; 5005 /* 5006 * An N_Port already logged in with the firmware 5007 * will have the only database entry. 5008 */ 5009 if (LOCAL_LOOP_ID(ha->n_port->n_port_handle)) { 5010 tq = ql_loop_id_to_queue(ha, ha->n_port->n_port_handle); 5011 } 5012 5013 if (tq != NULL) { 5014 /* 5015 * If the target port has initiative send 5016 * up a PLOGI about the new device. 5017 */ 5018 if ((ql_wwn_cmp(ha, (la_wwn_t *)&tq->port_name[0], 5019 (la_wwn_t *)(CFG_IST(ha, CFG_CTRL_2425) ? 5020 &ha->init_ctrl_blk.cb24.port_name[0] : 5021 &ha->init_ctrl_blk.cb.port_name[0])) == 1)) { 5022 ha->send_plogi_timer = 3; 5023 } else { 5024 ha->send_plogi_timer = 0; 5025 } 5026 pkt->pkt_resp_fhdr.s_id = tq->d_id.b24; 5027 } else { 5028 /* 5029 * An N_Port not logged in with the firmware will not 5030 * have a database entry. We accept anyway and rely 5031 * on a PLOGI from the upper layers to set the d_id 5032 * and s_id. 5033 */ 5034 accept = 1; 5035 } 5036 } else { 5037 tq = ql_d_id_to_queue(ha, d_id); 5038 } 5039 if ((tq != NULL) || (accept != NULL)) { 5040 /* Build ACC. */ 5041 pkt->pkt_state = FC_PKT_SUCCESS; 5042 class3_param = (class_svc_param_t *)&acc.class_3; 5043 5044 acc.ls_code.ls_code = LA_ELS_ACC; 5045 acc.common_service.fcph_version = 0x2006; 5046 if (ha->topology & QL_N_PORT) { 5047 /* clear F_Port indicator */ 5048 acc.common_service.cmn_features = 0x0800; 5049 } else { 5050 acc.common_service.cmn_features = 0x1b00; 5051 } 5052 CFG_IST(ha, CFG_CTRL_242581) ? 5053 (acc.common_service.rx_bufsize = CHAR_TO_SHORT( 5054 ha->init_ctrl_blk.cb24.max_frame_length[0], 5055 ha->init_ctrl_blk.cb24.max_frame_length[1])) : 5056 (acc.common_service.rx_bufsize = CHAR_TO_SHORT( 5057 ha->init_ctrl_blk.cb.max_frame_length[0], 5058 ha->init_ctrl_blk.cb.max_frame_length[1])); 5059 acc.common_service.conc_sequences = 0xff; 5060 acc.common_service.relative_offset = 0x03; 5061 acc.common_service.e_d_tov = 0x7d0; 5062 if (accept) { 5063 /* Use the saved N_Port WWNN and WWPN */ 5064 if (ha->n_port != NULL) { 5065 bcopy((void *)&ha->n_port->port_name[0], 5066 (void *)&acc.nport_ww_name.raw_wwn[0], 8); 5067 bcopy((void *)&ha->n_port->node_name[0], 5068 (void *)&acc.node_ww_name.raw_wwn[0], 8); 5069 /* mark service options invalid */ 5070 class3_param->class_valid_svc_opt = 0x0800; 5071 } else { 5072 EL(ha, "ha->n_port is NULL\n"); 5073 /* Build RJT. */ 5074 acc.ls_code.ls_code = LA_ELS_RJT; 5075 5076 pkt->pkt_state = FC_PKT_TRAN_ERROR; 5077 pkt->pkt_reason = FC_REASON_NO_CONNECTION; 5078 } 5079 } else { 5080 bcopy((void *)&tq->port_name[0], 5081 (void *)&acc.nport_ww_name.raw_wwn[0], 8); 5082 bcopy((void *)&tq->node_name[0], 5083 (void *)&acc.node_ww_name.raw_wwn[0], 8); 5084 5085 class3_param = (class_svc_param_t *)&acc.class_3; 5086 class3_param->class_valid_svc_opt = 0x8800; 5087 class3_param->recipient_ctl = tq->class3_recipient_ctl; 5088 class3_param->rcv_data_size = tq->class3_rcv_data_size; 5089 class3_param->conc_sequences = 5090 tq->class3_conc_sequences; 5091 class3_param->open_sequences_per_exch = 5092 tq->class3_open_sequences_per_exch; 5093 } 5094 } else { 5095 /* Build RJT. */ 5096 acc.ls_code.ls_code = LA_ELS_RJT; 5097 5098 pkt->pkt_state = FC_PKT_TRAN_ERROR; 5099 pkt->pkt_reason = FC_REASON_NO_CONNECTION; 5100 EL(ha, "LA_ELS_RJT, FC_REASON_NO_CONNECTION\n"); 5101 } 5102 5103 ddi_rep_put8(pkt->pkt_resp_acc, (uint8_t *)&acc, 5104 (uint8_t *)pkt->pkt_resp, sizeof (acc), DDI_DEV_AUTOINCR); 5105 5106 if (rval != FC_SUCCESS) { 5107 EL(ha, "failed, rval = %xh\n", rval); 5108 } else { 5109 /*EMPTY*/ 5110 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance); 5111 } 5112 return (rval); 5113} 5114 5115/* 5116 * ql_els_logo 5117 * Issue a extended link service logout request. 5118 * 5119 * Input: 5120 * ha = adapter state pointer. 5121 * pkt = pointer to fc_packet. 5122 * 5123 * Returns: 5124 * FC_SUCCESS - the packet was accepted for transport. 5125 * FC_TRANSPORT_ERROR - a transport error occurred. 5126 * 5127 * Context: 5128 * Kernel context. 5129 */ 5130static int 5131ql_els_logo(ql_adapter_state_t *ha, fc_packet_t *pkt) 5132{ 5133 port_id_t d_id; 5134 ql_tgt_t *tq; 5135 la_els_logo_t acc; 5136 int rval = FC_SUCCESS; 5137 5138 QL_PRINT_3(CE_CONT, "(%d): started, d_id=%xh\n", ha->instance, 5139 pkt->pkt_cmd_fhdr.d_id); 5140 5141 bzero(&acc, sizeof (acc)); 5142 d_id.b24 = pkt->pkt_cmd_fhdr.d_id; 5143 5144 tq = ql_d_id_to_queue(ha, d_id); 5145 if (tq) { 5146 DEVICE_QUEUE_LOCK(tq); 5147 if (tq->d_id.b24 == BROADCAST_ADDR) { 5148 DEVICE_QUEUE_UNLOCK(tq); 5149 return (FC_SUCCESS); 5150 } 5151 5152 tq->flags |= TQF_NEED_AUTHENTICATION; 5153 5154 do { 5155 DEVICE_QUEUE_UNLOCK(tq); 5156 (void) ql_abort_device(ha, tq, 1); 5157 5158 /* 5159 * Wait for commands to drain in F/W (doesn't 5160 * take more than a few milliseconds) 5161 */ 5162 ql_delay(ha, 10000); 5163 5164 DEVICE_QUEUE_LOCK(tq); 5165 } while (tq->outcnt); 5166 5167 DEVICE_QUEUE_UNLOCK(tq); 5168 } 5169 5170 if (ql_logout_port(ha, d_id) == QL_SUCCESS) { 5171 /* Build ACC. */ 5172 acc.ls_code.ls_code = LA_ELS_ACC; 5173 5174 pkt->pkt_state = FC_PKT_SUCCESS; 5175 } else { 5176 /* Build RJT. */ 5177 acc.ls_code.ls_code = LA_ELS_RJT; 5178 5179 pkt->pkt_state = FC_PKT_TRAN_ERROR; 5180 pkt->pkt_reason = FC_REASON_NO_CONNECTION; 5181 EL(ha, "LA_ELS_RJT, FC_REASON_NO_CONNECTION\n"); 5182 } 5183 5184 ddi_rep_put8(pkt->pkt_resp_acc, (uint8_t *)&acc, 5185 (uint8_t *)pkt->pkt_resp, sizeof (acc), DDI_DEV_AUTOINCR); 5186 5187 if (rval != FC_SUCCESS) { 5188 EL(ha, "failed, rval = %xh\n", rval); 5189 } else { 5190 /*EMPTY*/ 5191 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance); 5192 } 5193 return (rval); 5194} 5195 5196/* 5197 * ql_els_prli 5198 * Issue a extended link service process login request. 5199 * 5200 * Input: 5201 * ha = adapter state pointer. 5202 * pkt = pointer to fc_packet. 5203 * 5204 * Returns: 5205 * FC_SUCCESS - the packet was accepted for transport. 5206 * FC_TRANSPORT_ERROR - a transport error occurred. 5207 * 5208 * Context: 5209 * Kernel context. 5210 */ 5211static int 5212ql_els_prli(ql_adapter_state_t *ha, fc_packet_t *pkt) 5213{ 5214 ql_tgt_t *tq; 5215 port_id_t d_id; 5216 la_els_prli_t acc; 5217 prli_svc_param_t *param; 5218 int rval = FC_SUCCESS; 5219 5220 QL_PRINT_3(CE_CONT, "(%d): started, d_id=%xh\n", ha->instance, 5221 pkt->pkt_cmd_fhdr.d_id); 5222 5223 d_id.b24 = pkt->pkt_cmd_fhdr.d_id; 5224 5225 tq = ql_d_id_to_queue(ha, d_id); 5226 if (tq != NULL) { 5227 (void) ql_get_port_database(ha, tq, PDF_NONE); 5228 5229 if ((ha->topology & QL_N_PORT) && 5230 (tq->master_state == PD_STATE_PLOGI_COMPLETED)) { 5231 ql_start_iocb(ha, (ql_srb_t *)pkt->pkt_fca_private); 5232 rval = QL_CONSUMED; 5233 } else { 5234 /* Build ACC. */ 5235 bzero(&acc, sizeof (acc)); 5236 acc.ls_code = LA_ELS_ACC; 5237 acc.page_length = 0x10; 5238 acc.payload_length = tq->prli_payload_length; 5239 5240 param = (prli_svc_param_t *)&acc.service_params[0]; 5241 param->type = 0x08; 5242 param->rsvd = 0x00; 5243 param->process_assoc_flags = tq->prli_svc_param_word_0; 5244 param->process_flags = tq->prli_svc_param_word_3; 5245 5246 ddi_rep_put8(pkt->pkt_resp_acc, (uint8_t *)&acc, 5247 (uint8_t *)pkt->pkt_resp, sizeof (acc), 5248 DDI_DEV_AUTOINCR); 5249 5250 pkt->pkt_state = FC_PKT_SUCCESS; 5251 } 5252 } else { 5253 la_els_rjt_t rjt; 5254 5255 /* Build RJT. */ 5256 bzero(&rjt, sizeof (rjt)); 5257 rjt.ls_code.ls_code = LA_ELS_RJT; 5258 5259 ddi_rep_put8(pkt->pkt_resp_acc, (uint8_t *)&rjt, 5260 (uint8_t *)pkt->pkt_resp, sizeof (rjt), DDI_DEV_AUTOINCR); 5261 5262 pkt->pkt_state = FC_PKT_TRAN_ERROR; 5263 pkt->pkt_reason = FC_REASON_NO_CONNECTION; 5264 EL(ha, "LA_ELS_RJT, FC_REASON_NO_CONNECTION\n"); 5265 } 5266 5267 if ((rval != FC_SUCCESS) && (rval != QL_CONSUMED)) { 5268 EL(ha, "failed, rval = %xh\n", rval); 5269 } else { 5270 /*EMPTY*/ 5271 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance); 5272 } 5273 return (rval); 5274} 5275 5276/* 5277 * ql_els_prlo 5278 * Issue a extended link service process logout request. 5279 * 5280 * Input: 5281 * ha = adapter state pointer. 5282 * pkt = pointer to fc_packet. 5283 * 5284 * Returns: 5285 * FC_SUCCESS - the packet was accepted for transport. 5286 * FC_TRANSPORT_ERROR - a transport error occurred. 5287 * 5288 * Context: 5289 * Kernel context. 5290 */ 5291/* ARGSUSED */ 5292static int 5293ql_els_prlo(ql_adapter_state_t *ha, fc_packet_t *pkt) 5294{ 5295 la_els_prli_t acc; 5296 int rval = FC_SUCCESS; 5297 5298 QL_PRINT_3(CE_CONT, "(%d): started, d_id=%xh\n", ha->instance, 5299 pkt->pkt_cmd_fhdr.d_id); 5300 5301 /* Build ACC. */ 5302 ddi_rep_get8(pkt->pkt_cmd_acc, (uint8_t *)&acc, 5303 (uint8_t *)pkt->pkt_cmd, sizeof (acc), DDI_DEV_AUTOINCR); 5304 5305 acc.ls_code = LA_ELS_ACC; 5306 acc.service_params[2] = 1; 5307 5308 ddi_rep_put8(pkt->pkt_resp_acc, (uint8_t *)&acc, 5309 (uint8_t *)pkt->pkt_resp, sizeof (acc), DDI_DEV_AUTOINCR); 5310 5311 pkt->pkt_state = FC_PKT_SUCCESS; 5312 5313 if (rval != FC_SUCCESS) { 5314 EL(ha, "failed, rval = %xh\n", rval); 5315 } else { 5316 /*EMPTY*/ 5317 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance); 5318 } 5319 return (rval); 5320} 5321 5322/* 5323 * ql_els_adisc 5324 * Issue a extended link service address discovery request. 5325 * 5326 * Input: 5327 * ha = adapter state pointer. 5328 * pkt = pointer to fc_packet. 5329 * 5330 * Returns: 5331 * FC_SUCCESS - the packet was accepted for transport. 5332 * FC_TRANSPORT_ERROR - a transport error occurred. 5333 * 5334 * Context: 5335 * Kernel context. 5336 */ 5337static int 5338ql_els_adisc(ql_adapter_state_t *ha, fc_packet_t *pkt) 5339{ 5340 ql_dev_id_list_t *list; 5341 uint32_t list_size; 5342 ql_link_t *link; 5343 ql_tgt_t *tq; 5344 ql_lun_t *lq; 5345 port_id_t d_id; 5346 la_els_adisc_t acc; 5347 uint16_t index, loop_id; 5348 ql_mbx_data_t mr; 5349 int rval = FC_SUCCESS; 5350 5351 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance); 5352 5353 bzero(&acc, sizeof (acc)); 5354 d_id.b24 = pkt->pkt_cmd_fhdr.d_id; 5355 5356 /* 5357 * MBC_GET_PORT_DATABASE causes ADISC to go out to 5358 * the device from the firmware 5359 */ 5360 index = ql_alpa_to_index[d_id.b.al_pa]; 5361 tq = NULL; 5362 for (link = ha->dev[index].first; link != NULL; link = link->next) { 5363 tq = link->base_address; 5364 if (tq->d_id.b24 == d_id.b24) { 5365 break; 5366 } else { 5367 tq = NULL; 5368 } 5369 } 5370 5371 if ((tq != NULL) && (!VALID_DEVICE_ID(ha, tq->loop_id))) { 5372 list_size = sizeof (ql_dev_id_list_t) * DEVICE_LIST_ENTRIES; 5373 list = (ql_dev_id_list_t *)kmem_zalloc(list_size, KM_SLEEP); 5374 5375 if (list != NULL && 5376 ql_get_id_list(ha, (caddr_t)list, list_size, &mr) == 5377 QL_SUCCESS) { 5378 5379 for (index = 0; index < mr.mb[1]; index++) { 5380 ql_dev_list(ha, list, index, &d_id, &loop_id); 5381 5382 if (tq->d_id.b24 == d_id.b24) { 5383 tq->loop_id = loop_id; 5384 break; 5385 } 5386 } 5387 } else { 5388 cmn_err(CE_WARN, "!%s(%d) didn't get list for %xh", 5389 QL_NAME, ha->instance, d_id.b24); 5390 tq = NULL; 5391 } 5392 if ((tq != NULL) && (!VALID_DEVICE_ID(ha, tq->loop_id))) { 5393 cmn_err(CE_WARN, "!%s(%d) no loop_id for adisc %xh", 5394 QL_NAME, ha->instance, tq->d_id.b24); 5395 tq = NULL; 5396 } 5397 5398 if (list != NULL) { 5399 kmem_free(list, list_size); 5400 } 5401 } 5402 5403 if ((tq != NULL) && (VALID_DEVICE_ID(ha, tq->loop_id)) && 5404 ql_get_port_database(ha, tq, PDF_ADISC) == QL_SUCCESS) { 5405 5406 /* Build ACC. */ 5407 5408 DEVICE_QUEUE_LOCK(tq); 5409 tq->flags &= ~TQF_NEED_AUTHENTICATION; 5410 if (tq->prli_svc_param_word_3 & PRLI_W3_RETRY) { 5411 for (link = tq->lun_queues.first; link != NULL; 5412 link = link->next) { 5413 lq = link->base_address; 5414 5415 if (lq->cmd.first != NULL) { 5416 ql_next(ha, lq); 5417 DEVICE_QUEUE_LOCK(tq); 5418 } 5419 } 5420 } 5421 DEVICE_QUEUE_UNLOCK(tq); 5422 5423 acc.ls_code.ls_code = LA_ELS_ACC; 5424 acc.hard_addr.hard_addr = tq->hard_addr.b24; 5425 5426 bcopy((void *)&tq->port_name[0], 5427 (void *)&acc.port_wwn.raw_wwn[0], 8); 5428 bcopy((void *)&tq->node_name[0], 5429 (void *)&acc.node_wwn.raw_wwn[0], 8); 5430 5431 acc.nport_id.port_id = tq->d_id.b24; 5432 5433 pkt->pkt_state = FC_PKT_SUCCESS; 5434 } else { 5435 /* Build RJT. */ 5436 acc.ls_code.ls_code = LA_ELS_RJT; 5437 5438 pkt->pkt_state = FC_PKT_TRAN_ERROR; 5439 pkt->pkt_reason = FC_REASON_NO_CONNECTION; 5440 EL(ha, "LA_ELS_RJT, FC_REASON_NO_CONNECTION\n"); 5441 } 5442 5443 ddi_rep_put8(pkt->pkt_resp_acc, (uint8_t *)&acc, 5444 (uint8_t *)pkt->pkt_resp, sizeof (acc), DDI_DEV_AUTOINCR); 5445 5446 if (rval != FC_SUCCESS) { 5447 EL(ha, "failed, rval = %xh\n", rval); 5448 } else { 5449 /*EMPTY*/ 5450 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance); 5451 } 5452 return (rval); 5453} 5454 5455/* 5456 * ql_els_linit 5457 * Issue a extended link service loop initialize request. 5458 * 5459 * Input: 5460 * ha = adapter state pointer. 5461 * pkt = pointer to fc_packet. 5462 * 5463 * Returns: 5464 * FC_SUCCESS - the packet was accepted for transport. 5465 * FC_TRANSPORT_ERROR - a transport error occurred. 5466 * 5467 * Context: 5468 * Kernel context. 5469 */ 5470static int 5471ql_els_linit(ql_adapter_state_t *ha, fc_packet_t *pkt) 5472{ 5473 ddi_dma_cookie_t *cp; 5474 uint32_t cnt; 5475 conv_num_t n; 5476 port_id_t d_id; 5477 int rval = FC_SUCCESS; 5478 5479 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance); 5480 5481 d_id.b24 = pkt->pkt_cmd_fhdr.d_id; 5482 if (ha->topology & QL_SNS_CONNECTION) { 5483 fc_linit_req_t els; 5484 lfa_cmd_t lfa; 5485 5486 ddi_rep_get8(pkt->pkt_cmd_acc, (uint8_t *)&els, 5487 (uint8_t *)pkt->pkt_cmd, sizeof (els), DDI_DEV_AUTOINCR); 5488 5489 /* Setup LFA mailbox command data. */ 5490 bzero((void *)&lfa, sizeof (lfa_cmd_t)); 5491 5492 lfa.resp_buffer_length[0] = 4; 5493 5494 cp = pkt->pkt_resp_cookie; 5495 if (CFG_IST(ha, CFG_ENABLE_64BIT_ADDRESSING)) { 5496 n.size64 = (uint64_t)cp->dmac_laddress; 5497 LITTLE_ENDIAN_64(&n.size64); 5498 } else { 5499 n.size32[0] = LSD(cp->dmac_laddress); 5500 LITTLE_ENDIAN_32(&n.size32[0]); 5501 n.size32[1] = MSD(cp->dmac_laddress); 5502 LITTLE_ENDIAN_32(&n.size32[1]); 5503 } 5504 5505 /* Set buffer address. */ 5506 for (cnt = 0; cnt < 8; cnt++) { 5507 lfa.resp_buffer_address[cnt] = n.size8[cnt]; 5508 } 5509 5510 lfa.subcommand_length[0] = 4; 5511 n.size32[0] = d_id.b24; 5512 LITTLE_ENDIAN_32(&n.size32[0]); 5513 lfa.addr[0] = n.size8[0]; 5514 lfa.addr[1] = n.size8[1]; 5515 lfa.addr[2] = n.size8[2]; 5516 lfa.subcommand[1] = 0x70; 5517 lfa.payload[2] = els.func; 5518 lfa.payload[4] = els.lip_b3; 5519 lfa.payload[5] = els.lip_b4; 5520 5521 if (ql_send_lfa(ha, &lfa) != QL_SUCCESS) { 5522 pkt->pkt_state = FC_PKT_TRAN_ERROR; 5523 } else { 5524 pkt->pkt_state = FC_PKT_SUCCESS; 5525 } 5526 } else { 5527 fc_linit_resp_t rjt; 5528 5529 /* Build RJT. */ 5530 bzero(&rjt, sizeof (rjt)); 5531 rjt.ls_code.ls_code = LA_ELS_RJT; 5532 5533 ddi_rep_put8(pkt->pkt_resp_acc, (uint8_t *)&rjt, 5534 (uint8_t *)pkt->pkt_resp, sizeof (rjt), DDI_DEV_AUTOINCR); 5535 5536 pkt->pkt_state = FC_PKT_TRAN_ERROR; 5537 pkt->pkt_reason = FC_REASON_NO_CONNECTION; 5538 EL(ha, "LA_ELS_RJT, FC_REASON_NO_CONNECTION\n"); 5539 } 5540 5541 if (rval != FC_SUCCESS) { 5542 EL(ha, "failed, rval = %xh\n", rval); 5543 } else { 5544 /*EMPTY*/ 5545 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance); 5546 } 5547 return (rval); 5548} 5549 5550/* 5551 * ql_els_lpc 5552 * Issue a extended link service loop control request. 5553 * 5554 * Input: 5555 * ha = adapter state pointer. 5556 * pkt = pointer to fc_packet. 5557 * 5558 * Returns: 5559 * FC_SUCCESS - the packet was accepted for transport. 5560 * FC_TRANSPORT_ERROR - a transport error occurred. 5561 * 5562 * Context: 5563 * Kernel context. 5564 */ 5565static int 5566ql_els_lpc(ql_adapter_state_t *ha, fc_packet_t *pkt) 5567{ 5568 ddi_dma_cookie_t *cp; 5569 uint32_t cnt; 5570 conv_num_t n; 5571 port_id_t d_id; 5572 int rval = FC_SUCCESS; 5573 5574 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance); 5575 5576 d_id.b24 = pkt->pkt_cmd_fhdr.d_id; 5577 if (ha->topology & QL_SNS_CONNECTION) { 5578 ql_lpc_t els; 5579 lfa_cmd_t lfa; 5580 5581 ddi_rep_get8(pkt->pkt_cmd_acc, (uint8_t *)&els, 5582 (uint8_t *)pkt->pkt_cmd, sizeof (els), DDI_DEV_AUTOINCR); 5583 5584 /* Setup LFA mailbox command data. */ 5585 bzero((void *)&lfa, sizeof (lfa_cmd_t)); 5586 5587 lfa.resp_buffer_length[0] = 4; 5588 5589 cp = pkt->pkt_resp_cookie; 5590 if (CFG_IST(ha, CFG_ENABLE_64BIT_ADDRESSING)) { 5591 n.size64 = (uint64_t)(cp->dmac_laddress); 5592 LITTLE_ENDIAN_64(&n.size64); 5593 } else { 5594 n.size32[0] = cp->dmac_address; 5595 LITTLE_ENDIAN_32(&n.size32[0]); 5596 n.size32[1] = 0; 5597 } 5598 5599 /* Set buffer address. */ 5600 for (cnt = 0; cnt < 8; cnt++) { 5601 lfa.resp_buffer_address[cnt] = n.size8[cnt]; 5602 } 5603 5604 lfa.subcommand_length[0] = 20; 5605 n.size32[0] = d_id.b24; 5606 LITTLE_ENDIAN_32(&n.size32[0]); 5607 lfa.addr[0] = n.size8[0]; 5608 lfa.addr[1] = n.size8[1]; 5609 lfa.addr[2] = n.size8[2]; 5610 lfa.subcommand[1] = 0x71; 5611 lfa.payload[4] = els.port_control; 5612 bcopy((void *)&els.lpb[0], (void *)&lfa.payload[6], 32); 5613 5614 if (ql_send_lfa(ha, &lfa) != QL_SUCCESS) { 5615 pkt->pkt_state = FC_PKT_TRAN_ERROR; 5616 } else { 5617 pkt->pkt_state = FC_PKT_SUCCESS; 5618 } 5619 } else { 5620 ql_lpc_resp_t rjt; 5621 5622 /* Build RJT. */ 5623 bzero(&rjt, sizeof (rjt)); 5624 rjt.ls_code.ls_code = LA_ELS_RJT; 5625 5626 ddi_rep_put8(pkt->pkt_resp_acc, (uint8_t *)&rjt, 5627 (uint8_t *)pkt->pkt_resp, sizeof (rjt), DDI_DEV_AUTOINCR); 5628 5629 pkt->pkt_state = FC_PKT_TRAN_ERROR; 5630 pkt->pkt_reason = FC_REASON_NO_CONNECTION; 5631 EL(ha, "LA_ELS_RJT, FC_REASON_NO_CONNECTION\n"); 5632 } 5633 5634 if (rval != FC_SUCCESS) { 5635 EL(ha, "failed, rval = %xh\n", rval); 5636 } else { 5637 /*EMPTY*/ 5638 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance); 5639 } 5640 return (rval); 5641} 5642 5643/* 5644 * ql_els_lsts 5645 * Issue a extended link service loop status request. 5646 * 5647 * Input: 5648 * ha = adapter state pointer. 5649 * pkt = pointer to fc_packet. 5650 * 5651 * Returns: 5652 * FC_SUCCESS - the packet was accepted for transport. 5653 * FC_TRANSPORT_ERROR - a transport error occurred. 5654 * 5655 * Context: 5656 * Kernel context. 5657 */ 5658static int 5659ql_els_lsts(ql_adapter_state_t *ha, fc_packet_t *pkt) 5660{ 5661 ddi_dma_cookie_t *cp; 5662 uint32_t cnt; 5663 conv_num_t n; 5664 port_id_t d_id; 5665 int rval = FC_SUCCESS; 5666 5667 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance); 5668 5669 d_id.b24 = pkt->pkt_cmd_fhdr.d_id; 5670 if (ha->topology & QL_SNS_CONNECTION) { 5671 fc_lsts_req_t els; 5672 lfa_cmd_t lfa; 5673 5674 ddi_rep_get8(pkt->pkt_cmd_acc, (uint8_t *)&els, 5675 (uint8_t *)pkt->pkt_cmd, sizeof (els), DDI_DEV_AUTOINCR); 5676 5677 /* Setup LFA mailbox command data. */ 5678 bzero((void *)&lfa, sizeof (lfa_cmd_t)); 5679 5680 lfa.resp_buffer_length[0] = 84; 5681 5682 cp = pkt->pkt_resp_cookie; 5683 if (CFG_IST(ha, CFG_ENABLE_64BIT_ADDRESSING)) { 5684 n.size64 = cp->dmac_laddress; 5685 LITTLE_ENDIAN_64(&n.size64); 5686 } else { 5687 n.size32[0] = cp->dmac_address; 5688 LITTLE_ENDIAN_32(&n.size32[0]); 5689 n.size32[1] = 0; 5690 } 5691 5692 /* Set buffer address. */ 5693 for (cnt = 0; cnt < 8; cnt++) { 5694 lfa.resp_buffer_address[cnt] = n.size8[cnt]; 5695 } 5696 5697 lfa.subcommand_length[0] = 2; 5698 n.size32[0] = d_id.b24; 5699 LITTLE_ENDIAN_32(&n.size32[0]); 5700 lfa.addr[0] = n.size8[0]; 5701 lfa.addr[1] = n.size8[1]; 5702 lfa.addr[2] = n.size8[2]; 5703 lfa.subcommand[1] = 0x72; 5704 5705 if (ql_send_lfa(ha, &lfa) != QL_SUCCESS) { 5706 pkt->pkt_state = FC_PKT_TRAN_ERROR; 5707 } else { 5708 pkt->pkt_state = FC_PKT_SUCCESS; 5709 } 5710 } else { 5711 fc_lsts_resp_t rjt; 5712 5713 /* Build RJT. */ 5714 bzero(&rjt, sizeof (rjt)); 5715 rjt.lsts_ls_code.ls_code = LA_ELS_RJT; 5716 5717 ddi_rep_put8(pkt->pkt_resp_acc, (uint8_t *)&rjt, 5718 (uint8_t *)pkt->pkt_resp, sizeof (rjt), DDI_DEV_AUTOINCR); 5719 5720 pkt->pkt_state = FC_PKT_TRAN_ERROR; 5721 pkt->pkt_reason = FC_REASON_NO_CONNECTION; 5722 EL(ha, "LA_ELS_RJT, FC_REASON_NO_CONNECTION\n"); 5723 } 5724 5725 if (rval != FC_SUCCESS) { 5726 EL(ha, "failed=%xh\n", rval); 5727 } else { 5728 /*EMPTY*/ 5729 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance); 5730 } 5731 return (rval); 5732} 5733 5734/* 5735 * ql_els_scr 5736 * Issue a extended link service state change registration request. 5737 * 5738 * Input: 5739 * ha = adapter state pointer. 5740 * pkt = pointer to fc_packet. 5741 * 5742 * Returns: 5743 * FC_SUCCESS - the packet was accepted for transport. 5744 * FC_TRANSPORT_ERROR - a transport error occurred. 5745 * 5746 * Context: 5747 * Kernel context. 5748 */ 5749static int 5750ql_els_scr(ql_adapter_state_t *ha, fc_packet_t *pkt) 5751{ 5752 fc_scr_resp_t acc; 5753 int rval = FC_SUCCESS; 5754 5755 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance); 5756 5757 bzero(&acc, sizeof (acc)); 5758 if (ha->topology & QL_SNS_CONNECTION) { 5759 fc_scr_req_t els; 5760 5761 ddi_rep_get8(pkt->pkt_cmd_acc, (uint8_t *)&els, 5762 (uint8_t *)pkt->pkt_cmd, sizeof (els), DDI_DEV_AUTOINCR); 5763 5764 if (ql_send_change_request(ha, els.scr_func) == 5765 QL_SUCCESS) { 5766 /* Build ACC. */ 5767 acc.scr_acc = LA_ELS_ACC; 5768 5769 pkt->pkt_state = FC_PKT_SUCCESS; 5770 } else { 5771 /* Build RJT. */ 5772 acc.scr_acc = LA_ELS_RJT; 5773 5774 pkt->pkt_state = FC_PKT_TRAN_ERROR; 5775 pkt->pkt_reason = FC_REASON_HW_ERROR; 5776 EL(ha, "LA_ELS_RJT, FC_REASON_HW_ERROR\n"); 5777 } 5778 } else { 5779 /* Build RJT. */ 5780 acc.scr_acc = LA_ELS_RJT; 5781 5782 pkt->pkt_state = FC_PKT_TRAN_ERROR; 5783 pkt->pkt_reason = FC_REASON_NO_CONNECTION; 5784 EL(ha, "LA_ELS_RJT, FC_REASON_NO_CONNECTION\n"); 5785 } 5786 5787 ddi_rep_put8(pkt->pkt_resp_acc, (uint8_t *)&acc, 5788 (uint8_t *)pkt->pkt_resp, sizeof (acc), DDI_DEV_AUTOINCR); 5789 5790 if (rval != FC_SUCCESS) { 5791 EL(ha, "failed, rval = %xh\n", rval); 5792 } else { 5793 /*EMPTY*/ 5794 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance); 5795 } 5796 return (rval); 5797} 5798 5799/* 5800 * ql_els_rscn 5801 * Issue a extended link service register state 5802 * change notification request. 5803 * 5804 * Input: 5805 * ha = adapter state pointer. 5806 * pkt = pointer to fc_packet. 5807 * 5808 * Returns: 5809 * FC_SUCCESS - the packet was accepted for transport. 5810 * FC_TRANSPORT_ERROR - a transport error occurred. 5811 * 5812 * Context: 5813 * Kernel context. 5814 */ 5815static int 5816ql_els_rscn(ql_adapter_state_t *ha, fc_packet_t *pkt) 5817{ 5818 ql_rscn_resp_t acc; 5819 int rval = FC_SUCCESS; 5820 5821 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance); 5822 5823 bzero(&acc, sizeof (acc)); 5824 if (ha->topology & QL_SNS_CONNECTION) { 5825 /* Build ACC. */ 5826 acc.scr_acc = LA_ELS_ACC; 5827 5828 pkt->pkt_state = FC_PKT_SUCCESS; 5829 } else { 5830 /* Build RJT. */ 5831 acc.scr_acc = LA_ELS_RJT; 5832 5833 pkt->pkt_state = FC_PKT_TRAN_ERROR; 5834 pkt->pkt_reason = FC_REASON_NO_CONNECTION; 5835 EL(ha, "LA_ELS_RJT, FC_REASON_NO_CONNECTION\n"); 5836 } 5837 5838 ddi_rep_put8(pkt->pkt_resp_acc, (uint8_t *)&acc, 5839 (uint8_t *)pkt->pkt_resp, sizeof (acc), DDI_DEV_AUTOINCR); 5840 5841 if (rval != FC_SUCCESS) { 5842 EL(ha, "failed, rval = %xh\n", rval); 5843 } else { 5844 /*EMPTY*/ 5845 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance); 5846 } 5847 return (rval); 5848} 5849 5850/* 5851 * ql_els_farp_req 5852 * Issue FC Address Resolution Protocol (FARP) 5853 * extended link service request. 5854 * 5855 * Note: not supported. 5856 * 5857 * Input: 5858 * ha = adapter state pointer. 5859 * pkt = pointer to fc_packet. 5860 * 5861 * Returns: 5862 * FC_SUCCESS - the packet was accepted for transport. 5863 * FC_TRANSPORT_ERROR - a transport error occurred. 5864 * 5865 * Context: 5866 * Kernel context. 5867 */ 5868static int 5869ql_els_farp_req(ql_adapter_state_t *ha, fc_packet_t *pkt) 5870{ 5871 ql_acc_rjt_t acc; 5872 int rval = FC_SUCCESS; 5873 5874 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance); 5875 5876 bzero(&acc, sizeof (acc)); 5877 5878 /* Build ACC. */ 5879 acc.ls_code.ls_code = LA_ELS_ACC; 5880 5881 pkt->pkt_state = FC_PKT_SUCCESS; 5882 5883 ddi_rep_put8(pkt->pkt_resp_acc, (uint8_t *)&acc, 5884 (uint8_t *)pkt->pkt_resp, sizeof (acc), DDI_DEV_AUTOINCR); 5885 5886 if (rval != FC_SUCCESS) { 5887 EL(ha, "failed, rval = %xh\n", rval); 5888 } else { 5889 /*EMPTY*/ 5890 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance); 5891 } 5892 return (rval); 5893} 5894 5895/* 5896 * ql_els_farp_reply 5897 * Issue FC Address Resolution Protocol (FARP) 5898 * extended link service reply. 5899 * 5900 * Note: not supported. 5901 * 5902 * Input: 5903 * ha = adapter state pointer. 5904 * pkt = pointer to fc_packet. 5905 * 5906 * Returns: 5907 * FC_SUCCESS - the packet was accepted for transport. 5908 * FC_TRANSPORT_ERROR - a transport error occurred. 5909 * 5910 * Context: 5911 * Kernel context. 5912 */ 5913/* ARGSUSED */ 5914static int 5915ql_els_farp_reply(ql_adapter_state_t *ha, fc_packet_t *pkt) 5916{ 5917 ql_acc_rjt_t acc; 5918 int rval = FC_SUCCESS; 5919 5920 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance); 5921 5922 bzero(&acc, sizeof (acc)); 5923 5924 /* Build ACC. */ 5925 acc.ls_code.ls_code = LA_ELS_ACC; 5926 5927 pkt->pkt_state = FC_PKT_SUCCESS; 5928 5929 ddi_rep_put8(pkt->pkt_resp_acc, (uint8_t *)&acc, 5930 (uint8_t *)pkt->pkt_resp, sizeof (acc), DDI_DEV_AUTOINCR); 5931 5932 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance); 5933 5934 return (rval); 5935} 5936 5937static int 5938ql_els_rnid(ql_adapter_state_t *ha, fc_packet_t *pkt) 5939{ 5940 uchar_t *rnid_acc; 5941 port_id_t d_id; 5942 ql_link_t *link; 5943 ql_tgt_t *tq; 5944 uint16_t index; 5945 la_els_rnid_acc_t acc; 5946 la_els_rnid_t *req; 5947 size_t req_len; 5948 5949 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance); 5950 5951 req_len = FCIO_RNID_MAX_DATA_LEN + sizeof (fc_rnid_hdr_t); 5952 d_id.b24 = pkt->pkt_cmd_fhdr.d_id; 5953 index = ql_alpa_to_index[d_id.b.al_pa]; 5954 5955 tq = NULL; 5956 for (link = ha->dev[index].first; link != NULL; link = link->next) { 5957 tq = link->base_address; 5958 if (tq->d_id.b24 == d_id.b24) { 5959 break; 5960 } else { 5961 tq = NULL; 5962 } 5963 } 5964 5965 /* Allocate memory for rnid status block */ 5966 rnid_acc = kmem_zalloc(req_len, KM_SLEEP); 5967 5968 bzero(&acc, sizeof (acc)); 5969 5970 req = (la_els_rnid_t *)pkt->pkt_cmd; 5971 if ((tq == NULL) || (!VALID_DEVICE_ID(ha, tq->loop_id)) || 5972 (ql_send_rnid_els(ha, tq->loop_id, req->data_format, req_len, 5973 (caddr_t)rnid_acc) != QL_SUCCESS)) { 5974 5975 kmem_free(rnid_acc, req_len); 5976 acc.ls_code.ls_code = LA_ELS_RJT; 5977 5978 ddi_rep_put8(pkt->pkt_resp_acc, (uint8_t *)&acc, 5979 (uint8_t *)pkt->pkt_resp, sizeof (acc), DDI_DEV_AUTOINCR); 5980 5981 pkt->pkt_state = FC_PKT_TRAN_ERROR; 5982 pkt->pkt_reason = FC_REASON_NO_CONNECTION; 5983 EL(ha, "LA_ELS_RJT, FC_REASON_NO_CONNECTION\n"); 5984 5985 return (FC_FAILURE); 5986 } 5987 5988 acc.ls_code.ls_code = LA_ELS_ACC; 5989 bcopy(rnid_acc, &acc.hdr, req_len); 5990 ddi_rep_put8(pkt->pkt_resp_acc, (uint8_t *)&acc, 5991 (uint8_t *)pkt->pkt_resp, sizeof (acc), DDI_DEV_AUTOINCR); 5992 5993 kmem_free(rnid_acc, req_len); 5994 pkt->pkt_state = FC_PKT_SUCCESS; 5995 5996 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance); 5997 5998 return (FC_SUCCESS); 5999} 6000 6001static int 6002ql_els_rls(ql_adapter_state_t *ha, fc_packet_t *pkt) 6003{ 6004 fc_rls_acc_t *rls_acc; 6005 port_id_t d_id; 6006 ql_link_t *link; 6007 ql_tgt_t *tq; 6008 uint16_t index; 6009 la_els_rls_acc_t acc; 6010 6011 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance); 6012 6013 d_id.b24 = pkt->pkt_cmd_fhdr.d_id; 6014 index = ql_alpa_to_index[d_id.b.al_pa]; 6015 6016 tq = NULL; 6017 for (link = ha->dev[index].first; link != NULL; link = link->next) { 6018 tq = link->base_address; 6019 if (tq->d_id.b24 == d_id.b24) { 6020 break; 6021 } else { 6022 tq = NULL; 6023 } 6024 } 6025 6026 /* Allocate memory for link error status block */ 6027 rls_acc = kmem_zalloc(sizeof (*rls_acc), KM_SLEEP); 6028 6029 bzero(&acc, sizeof (la_els_rls_acc_t)); 6030 6031 if ((tq == NULL) || (!VALID_DEVICE_ID(ha, tq->loop_id)) || 6032 (ql_get_link_status(ha, tq->loop_id, sizeof (*rls_acc), 6033 (caddr_t)rls_acc, 0) != QL_SUCCESS)) { 6034 6035 kmem_free(rls_acc, sizeof (*rls_acc)); 6036 acc.ls_code.ls_code = LA_ELS_RJT; 6037 6038 ddi_rep_put8(pkt->pkt_resp_acc, (uint8_t *)&acc, 6039 (uint8_t *)pkt->pkt_resp, sizeof (acc), DDI_DEV_AUTOINCR); 6040 6041 pkt->pkt_state = FC_PKT_TRAN_ERROR; 6042 pkt->pkt_reason = FC_REASON_NO_CONNECTION; 6043 EL(ha, "LA_ELS_RJT, FC_REASON_NO_CONNECTION\n"); 6044 6045 return (FC_FAILURE); 6046 } 6047 6048 LITTLE_ENDIAN_32(&rls_acc->rls_link_fail); 6049 LITTLE_ENDIAN_32(&rls_acc->rls_sync_loss); 6050 LITTLE_ENDIAN_32(&rls_acc->rls_sig_loss); 6051 LITTLE_ENDIAN_32(&rls_acc->rls_invalid_word); 6052 LITTLE_ENDIAN_32(&rls_acc->rls_invalid_crc); 6053 6054 acc.ls_code.ls_code = LA_ELS_ACC; 6055 acc.rls_link_params.rls_link_fail = rls_acc->rls_link_fail; 6056 acc.rls_link_params.rls_sync_loss = rls_acc->rls_sync_loss; 6057 acc.rls_link_params.rls_sig_loss = rls_acc->rls_sig_loss; 6058 acc.rls_link_params.rls_invalid_word = rls_acc->rls_invalid_word; 6059 acc.rls_link_params.rls_invalid_crc = rls_acc->rls_invalid_crc; 6060 ddi_rep_put8(pkt->pkt_resp_acc, (uint8_t *)&acc, 6061 (uint8_t *)pkt->pkt_resp, sizeof (acc), DDI_DEV_AUTOINCR); 6062 6063 kmem_free(rls_acc, sizeof (*rls_acc)); 6064 pkt->pkt_state = FC_PKT_SUCCESS; 6065 6066 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance); 6067 6068 return (FC_SUCCESS); 6069} 6070 6071static int 6072ql_busy_plogi(ql_adapter_state_t *ha, fc_packet_t *pkt, ql_tgt_t *tq) 6073{ 6074 port_id_t d_id; 6075 ql_srb_t *sp; 6076 fc_unsol_buf_t *ubp; 6077 ql_link_t *link, *next_link; 6078 int rval = FC_SUCCESS; 6079 int cnt = 5; 6080 6081 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance); 6082 6083 /* 6084 * we need to ensure that q->outcnt == 0, otherwise 6085 * any cmd completed with PKT_PORT_OFFLINE after PLOGI 6086 * will confuse ulps. 6087 */ 6088 6089 DEVICE_QUEUE_LOCK(tq); 6090 do { 6091 /* 6092 * wait for the cmds to get drained. If they 6093 * don't get drained then the transport will 6094 * retry PLOGI after few secs. 6095 */ 6096 if (tq->outcnt != 0) { 6097 rval = FC_TRAN_BUSY; 6098 DEVICE_QUEUE_UNLOCK(tq); 6099 ql_delay(ha, 10000); 6100 DEVICE_QUEUE_LOCK(tq); 6101 cnt--; 6102 if (!cnt) { 6103 cmn_err(CE_NOTE, "!%s(%d) Plogi busy" 6104 " for %xh outcount %xh", QL_NAME, 6105 ha->instance, tq->d_id.b24, tq->outcnt); 6106 } 6107 } else { 6108 rval = FC_SUCCESS; 6109 break; 6110 } 6111 } while (cnt > 0); 6112 DEVICE_QUEUE_UNLOCK(tq); 6113 6114 /* 6115 * return, if busy or if the plogi was asynchronous. 6116 */ 6117 if ((rval != FC_SUCCESS) || 6118 (!(pkt->pkt_tran_flags & FC_TRAN_NO_INTR) && 6119 pkt->pkt_comp)) { 6120 QL_PRINT_3(CE_CONT, "(%d): done, busy or async\n", 6121 ha->instance); 6122 return (rval); 6123 } 6124 6125 /* 6126 * Let us give daemon sufficient time and hopefully 6127 * when transport retries PLOGI, it would have flushed 6128 * callback queue. 6129 */ 6130 TASK_DAEMON_LOCK(ha); 6131 for (link = ha->callback_queue.first; link != NULL; 6132 link = next_link) { 6133 next_link = link->next; 6134 sp = link->base_address; 6135 if (sp->flags & SRB_UB_CALLBACK) { 6136 ubp = ha->ub_array[sp->handle]; 6137 d_id.b24 = ubp->ub_frame.s_id; 6138 } else { 6139 d_id.b24 = sp->pkt->pkt_cmd_fhdr.d_id; 6140 } 6141 if (tq->d_id.b24 == d_id.b24) { 6142 cmn_err(CE_NOTE, "!%s(%d) Plogi busy for %xh", QL_NAME, 6143 ha->instance, tq->d_id.b24); 6144 rval = FC_TRAN_BUSY; 6145 break; 6146 } 6147 } 6148 TASK_DAEMON_UNLOCK(ha); 6149 6150 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance); 6151 6152 return (rval); 6153} 6154 6155/* 6156 * ql_login_port 6157 * Logs in a device if not already logged in. 6158 * 6159 * Input: 6160 * ha = adapter state pointer. 6161 * d_id = 24 bit port ID. 6162 * DEVICE_QUEUE_LOCK must be released. 6163 * 6164 * Returns: 6165 * QL local function return status code. 6166 * 6167 * Context: 6168 * Kernel context. 6169 */ 6170static int 6171ql_login_port(ql_adapter_state_t *ha, port_id_t d_id) 6172{ 6173 ql_adapter_state_t *vha; 6174 ql_link_t *link; 6175 uint16_t index; 6176 ql_tgt_t *tq, *tq2; 6177 uint16_t loop_id, first_loop_id, last_loop_id; 6178 int rval = QL_SUCCESS; 6179 6180 QL_PRINT_3(CE_CONT, "(%d): started, d_id=%xh\n", ha->instance, 6181 d_id.b24); 6182 6183 /* Get head queue index. */ 6184 index = ql_alpa_to_index[d_id.b.al_pa]; 6185 6186 /* Check for device already has a queue. */ 6187 tq = NULL; 6188 for (link = ha->dev[index].first; link != NULL; link = link->next) { 6189 tq = link->base_address; 6190 if (tq->d_id.b24 == d_id.b24) { 6191 loop_id = tq->loop_id; 6192 break; 6193 } else { 6194 tq = NULL; 6195 } 6196 } 6197 6198 /* Let's stop issuing any IO and unsolicited logo */ 6199 if ((tq != NULL) && (!(ddi_in_panic()))) { 6200 DEVICE_QUEUE_LOCK(tq); 6201 tq->flags |= (TQF_QUEUE_SUSPENDED | TQF_PLOGI_PROGRS); 6202 tq->flags &= ~TQF_RSCN_RCVD; 6203 DEVICE_QUEUE_UNLOCK(tq); 6204 } 6205 if ((tq != NULL) && (tq->loop_id & PORT_LOST_ID) && 6206 !(tq->flags & TQF_FABRIC_DEVICE)) { 6207 loop_id = (uint16_t)(tq->loop_id & ~PORT_LOST_ID); 6208 } 6209 6210 /* Special case for Nameserver */ 6211 if (d_id.b24 == 0xFFFFFC) { 6212 loop_id = (uint16_t)(CFG_IST(ha, CFG_CTRL_242581) ? 6213 SNS_24XX_HDL : SIMPLE_NAME_SERVER_LOOP_ID); 6214 if (tq == NULL) { 6215 ADAPTER_STATE_LOCK(ha); 6216 tq = ql_dev_init(ha, d_id, loop_id); 6217 ADAPTER_STATE_UNLOCK(ha); 6218 if (tq == NULL) { 6219 EL(ha, "failed=%xh, d_id=%xh\n", 6220 QL_FUNCTION_FAILED, d_id.b24); 6221 return (QL_FUNCTION_FAILED); 6222 } 6223 } 6224 rval = ql_login_fabric_port(ha, tq, loop_id); 6225 if (rval == QL_SUCCESS) { 6226 tq->loop_id = loop_id; 6227 tq->flags |= TQF_FABRIC_DEVICE; 6228 (void) ql_get_port_database(ha, tq, PDF_NONE); 6229 ha->topology = (uint8_t) 6230 (ha->topology | QL_SNS_CONNECTION); 6231 } 6232 /* Check for device already logged in. */ 6233 } else if (tq != NULL && VALID_DEVICE_ID(ha, loop_id)) { 6234 if (tq->flags & TQF_FABRIC_DEVICE) { 6235 rval = ql_login_fabric_port(ha, tq, loop_id); 6236 if (rval == QL_PORT_ID_USED) { 6237 rval = QL_SUCCESS; 6238 } 6239 } else if (LOCAL_LOOP_ID(loop_id)) { 6240 rval = ql_login_lport(ha, tq, loop_id, (uint16_t) 6241 (tq->flags & TQF_INITIATOR_DEVICE ? 6242 LLF_NONE : LLF_PLOGI)); 6243 if (rval == QL_SUCCESS) { 6244 DEVICE_QUEUE_LOCK(tq); 6245 tq->loop_id = loop_id; 6246 DEVICE_QUEUE_UNLOCK(tq); 6247 } 6248 } 6249 } else if (ha->topology & QL_SNS_CONNECTION) { 6250 /* Locate unused loop ID. */ 6251 if (CFG_IST(ha, CFG_CTRL_242581)) { 6252 first_loop_id = 0; 6253 last_loop_id = LAST_N_PORT_HDL; 6254 } else if (ha->topology & QL_F_PORT) { 6255 first_loop_id = 0; 6256 last_loop_id = SNS_LAST_LOOP_ID; 6257 } else { 6258 first_loop_id = SNS_FIRST_LOOP_ID; 6259 last_loop_id = SNS_LAST_LOOP_ID; 6260 } 6261 6262 /* Acquire adapter state lock. */ 6263 ADAPTER_STATE_LOCK(ha); 6264 6265 tq = ql_dev_init(ha, d_id, PORT_NO_LOOP_ID); 6266 if (tq == NULL) { 6267 EL(ha, "failed=%xh, d_id=%xh\n", QL_FUNCTION_FAILED, 6268 d_id.b24); 6269 6270 ADAPTER_STATE_UNLOCK(ha); 6271 6272 return (QL_FUNCTION_FAILED); 6273 } 6274 6275 rval = QL_FUNCTION_FAILED; 6276 loop_id = ha->pha->free_loop_id++; 6277 for (index = (uint16_t)(last_loop_id - first_loop_id); index; 6278 index--) { 6279 if (loop_id < first_loop_id || 6280 loop_id > last_loop_id) { 6281 loop_id = first_loop_id; 6282 ha->pha->free_loop_id = (uint16_t) 6283 (loop_id + 1); 6284 } 6285 6286 /* Bypass if loop ID used. */ 6287 for (vha = ha->pha; vha != NULL; vha = vha->vp_next) { 6288 tq2 = ql_loop_id_to_queue(vha, loop_id); 6289 if (tq2 != NULL && tq2 != tq) { 6290 break; 6291 } 6292 } 6293 if (vha != NULL || RESERVED_LOOP_ID(ha, loop_id) || 6294 loop_id == ha->loop_id) { 6295 loop_id = ha->pha->free_loop_id++; 6296 continue; 6297 } 6298 6299 ADAPTER_STATE_UNLOCK(ha); 6300 rval = ql_login_fabric_port(ha, tq, loop_id); 6301 6302 /* 6303 * If PORT_ID_USED is returned 6304 * the login_fabric_port() updates 6305 * with the correct loop ID 6306 */ 6307 switch (rval) { 6308 case QL_PORT_ID_USED: 6309 /* 6310 * use f/w handle and try to 6311 * login again. 6312 */ 6313 ADAPTER_STATE_LOCK(ha); 6314 ha->pha->free_loop_id--; 6315 ADAPTER_STATE_UNLOCK(ha); 6316 loop_id = tq->loop_id; 6317 break; 6318 6319 case QL_SUCCESS: 6320 tq->flags |= TQF_FABRIC_DEVICE; 6321 (void) ql_get_port_database(ha, 6322 tq, PDF_NONE); 6323 index = 1; 6324 break; 6325 6326 case QL_LOOP_ID_USED: 6327 tq->loop_id = PORT_NO_LOOP_ID; 6328 loop_id = ha->pha->free_loop_id++; 6329 break; 6330 6331 case QL_ALL_IDS_IN_USE: 6332 tq->loop_id = PORT_NO_LOOP_ID; 6333 index = 1; 6334 break; 6335 6336 default: 6337 tq->loop_id = PORT_NO_LOOP_ID; 6338 index = 1; 6339 break; 6340 } 6341 6342 ADAPTER_STATE_LOCK(ha); 6343 } 6344 6345 ADAPTER_STATE_UNLOCK(ha); 6346 } else { 6347 rval = QL_FUNCTION_FAILED; 6348 } 6349 6350 if (rval != QL_SUCCESS) { 6351 EL(ha, "failed=%xh, d_id=%xh\n", rval, d_id.b24); 6352 } else { 6353 EL(ha, "d_id=%xh, loop_id=%xh, " 6354 "wwpn=%02x%02x%02x%02x%02x%02x%02x%02xh\n", tq->d_id.b24, 6355 tq->loop_id, tq->port_name[0], tq->port_name[1], 6356 tq->port_name[2], tq->port_name[3], tq->port_name[4], 6357 tq->port_name[5], tq->port_name[6], tq->port_name[7]); 6358 } 6359 return (rval); 6360} 6361 6362/* 6363 * ql_login_fabric_port 6364 * Issue login fabric port mailbox command. 6365 * 6366 * Input: 6367 * ha: adapter state pointer. 6368 * tq: target queue pointer. 6369 * loop_id: FC Loop ID. 6370 * 6371 * Returns: 6372 * ql local function return status code. 6373 * 6374 * Context: 6375 * Kernel context. 6376 */ 6377static int 6378ql_login_fabric_port(ql_adapter_state_t *ha, ql_tgt_t *tq, uint16_t loop_id) 6379{ 6380 int rval; 6381 int index; 6382 int retry = 0; 6383 port_id_t d_id; 6384 ql_tgt_t *newq; 6385 ql_mbx_data_t mr; 6386 6387 QL_PRINT_3(CE_CONT, "(%d): started, d_id=%xh\n", ha->instance, 6388 tq->d_id.b24); 6389 6390 /* 6391 * QL_PARAMETER_ERROR also means the firmware is 6392 * not able to allocate PCB entry due to resource 6393 * issues, or collision. 6394 */ 6395 do { 6396 rval = ql_login_fport(ha, tq, loop_id, LFF_NONE, &mr); 6397 if ((rval == QL_PARAMETER_ERROR) || 6398 ((rval == QL_COMMAND_ERROR) && (mr.mb[1] == 2 || 6399 mr.mb[1] == 3 || mr.mb[1] == 7 || mr.mb[1] == 0xd))) { 6400 retry++; 6401 drv_usecwait(10 * MILLISEC); 6402 } else { 6403 break; 6404 } 6405 } while (retry < 5); 6406 6407 switch (rval) { 6408 case QL_SUCCESS: 6409 tq->loop_id = loop_id; 6410 break; 6411 6412 case QL_PORT_ID_USED: 6413 /* 6414 * This Loop ID should NOT be in use in drivers 6415 */ 6416 newq = ql_loop_id_to_queue(ha, mr.mb[1]); 6417 6418 if (newq != NULL && newq != tq && tq->logout_sent == 0) { 6419 cmn_err(CE_WARN, "ql_login_fabric_port(%d): logout of " 6420 "dup loop_id=%xh, d_id=%xh", ha->instance, 6421 newq->loop_id, newq->d_id.b24); 6422 ql_send_logo(ha, newq, NULL); 6423 } 6424 6425 tq->loop_id = mr.mb[1]; 6426 break; 6427 6428 case QL_LOOP_ID_USED: 6429 d_id.b.al_pa = LSB(mr.mb[2]); 6430 d_id.b.area = MSB(mr.mb[2]); 6431 d_id.b.domain = LSB(mr.mb[1]); 6432 6433 newq = ql_d_id_to_queue(ha, d_id); 6434 if (newq && (newq->loop_id != loop_id)) { 6435 /* 6436 * This should NEVER ever happen; but this 6437 * code is needed to bail out when the worst 6438 * case happens - or as used to happen before 6439 */ 6440 QL_PRINT_2(CE_CONT, "(%d,%d): Loop ID is now " 6441 "reassigned; old pairs: [%xh, %xh] and [%xh, %xh];" 6442 "new pairs: [%xh, unknown] and [%xh, %xh]\n", 6443 ha->instance, ha->vp_index, tq->d_id.b24, loop_id, 6444 newq->d_id.b24, newq->loop_id, tq->d_id.b24, 6445 newq->d_id.b24, loop_id); 6446 6447 if ((newq->d_id.b24 & 0xff) != (d_id.b24 & 0xff)) { 6448 ADAPTER_STATE_LOCK(ha); 6449 6450 index = ql_alpa_to_index[newq->d_id.b.al_pa]; 6451 ql_add_link_b(&ha->dev[index], &newq->device); 6452 6453 newq->d_id.b24 = d_id.b24; 6454 6455 index = ql_alpa_to_index[d_id.b.al_pa]; 6456 ql_add_link_b(&ha->dev[index], &newq->device); 6457 6458 ADAPTER_STATE_UNLOCK(ha); 6459 } 6460 6461 (void) ql_get_port_database(ha, newq, PDF_NONE); 6462 6463 } 6464 6465 /* 6466 * Invalidate the loop ID for the 6467 * us to obtain a new one. 6468 */ 6469 tq->loop_id = PORT_NO_LOOP_ID; 6470 break; 6471 6472 case QL_ALL_IDS_IN_USE: 6473 rval = QL_FUNCTION_FAILED; 6474 EL(ha, "no loop id's available\n"); 6475 break; 6476 6477 default: 6478 if (rval == QL_COMMAND_ERROR) { 6479 switch (mr.mb[1]) { 6480 case 2: 6481 case 3: 6482 rval = QL_MEMORY_ALLOC_FAILED; 6483 break; 6484 6485 case 4: 6486 rval = QL_FUNCTION_TIMEOUT; 6487 break; 6488 case 7: 6489 rval = QL_FABRIC_NOT_INITIALIZED; 6490 break; 6491 default: 6492 EL(ha, "cmd rtn; mb1=%xh\n", mr.mb[1]); 6493 break; 6494 } 6495 } else { 6496 cmn_err(CE_WARN, "%s(%d): login fabric port failed" 6497 " D_ID=%xh, rval=%xh, mb1=%xh", QL_NAME, 6498 ha->instance, tq->d_id.b24, rval, mr.mb[1]); 6499 } 6500 break; 6501 } 6502 6503 if (rval != QL_SUCCESS && rval != QL_PORT_ID_USED && 6504 rval != QL_LOOP_ID_USED) { 6505 EL(ha, "failed=%xh\n", rval); 6506 } else { 6507 /*EMPTY*/ 6508 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance); 6509 } 6510 return (rval); 6511} 6512 6513/* 6514 * ql_logout_port 6515 * Logs out a device if possible. 6516 * 6517 * Input: 6518 * ha: adapter state pointer. 6519 * d_id: 24 bit port ID. 6520 * 6521 * Returns: 6522 * QL local function return status code. 6523 * 6524 * Context: 6525 * Kernel context. 6526 */ 6527static int 6528ql_logout_port(ql_adapter_state_t *ha, port_id_t d_id) 6529{ 6530 ql_link_t *link; 6531 ql_tgt_t *tq; 6532 uint16_t index; 6533 6534 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance); 6535 6536 /* Get head queue index. */ 6537 index = ql_alpa_to_index[d_id.b.al_pa]; 6538 6539 /* Get device queue. */ 6540 tq = NULL; 6541 for (link = ha->dev[index].first; link != NULL; link = link->next) { 6542 tq = link->base_address; 6543 if (tq->d_id.b24 == d_id.b24) { 6544 break; 6545 } else { 6546 tq = NULL; 6547 } 6548 } 6549 6550 if (tq != NULL && tq->flags & TQF_FABRIC_DEVICE) { 6551 (void) ql_logout_fabric_port(ha, tq); 6552 tq->loop_id = PORT_NO_LOOP_ID; 6553 } 6554 6555 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance); 6556 6557 return (QL_SUCCESS); 6558} 6559 6560/* 6561 * ql_dev_init 6562 * Initialize/allocate device queue. 6563 * 6564 * Input: 6565 * ha: adapter state pointer. 6566 * d_id: device destination ID 6567 * loop_id: device loop ID 6568 * ADAPTER_STATE_LOCK must be already obtained. 6569 * 6570 * Returns: 6571 * NULL = failure 6572 * 6573 * Context: 6574 * Kernel context. 6575 */ 6576ql_tgt_t * 6577ql_dev_init(ql_adapter_state_t *ha, port_id_t d_id, uint16_t loop_id) 6578{ 6579 ql_link_t *link; 6580 uint16_t index; 6581 ql_tgt_t *tq; 6582 6583 QL_PRINT_3(CE_CONT, "(%d): started, d_id=%xh, loop_id=%xh\n", 6584 ha->instance, d_id.b24, loop_id); 6585 6586 index = ql_alpa_to_index[d_id.b.al_pa]; 6587 6588 /* If device queue exists, set proper loop ID. */ 6589 tq = NULL; 6590 for (link = ha->dev[index].first; link != NULL; link = link->next) { 6591 tq = link->base_address; 6592 if (tq->d_id.b24 == d_id.b24) { 6593 tq->loop_id = loop_id; 6594 6595 /* Reset port down retry count. */ 6596 tq->port_down_retry_count = ha->port_down_retry_count; 6597 tq->qfull_retry_count = ha->qfull_retry_count; 6598 6599 break; 6600 } else { 6601 tq = NULL; 6602 } 6603 } 6604 6605 /* If device does not have queue. */ 6606 if (tq == NULL) { 6607 tq = (ql_tgt_t *)kmem_zalloc(sizeof (ql_tgt_t), KM_SLEEP); 6608 if (tq != NULL) { 6609 /* 6610 * mutex to protect the device queue, 6611 * does not block interrupts. 6612 */ 6613 mutex_init(&tq->mutex, NULL, MUTEX_DRIVER, 6614 (ha->iflags & IFLG_INTR_AIF) ? 6615 (void *)(uintptr_t)ha->intr_pri : 6616 (void *)(uintptr_t)ha->iblock_cookie); 6617 6618 tq->d_id.b24 = d_id.b24; 6619 tq->loop_id = loop_id; 6620 tq->device.base_address = tq; 6621 tq->iidma_rate = IIDMA_RATE_INIT; 6622 6623 /* Reset port down retry count. */ 6624 tq->port_down_retry_count = ha->port_down_retry_count; 6625 tq->qfull_retry_count = ha->qfull_retry_count; 6626 6627 /* Add device to device queue. */ 6628 ql_add_link_b(&ha->dev[index], &tq->device); 6629 } 6630 } 6631 6632 if (tq == NULL) { 6633 EL(ha, "failed, d_id=%xh, loop_id=%xh\n", d_id.b24, loop_id); 6634 } else { 6635 /*EMPTY*/ 6636 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance); 6637 } 6638 return (tq); 6639} 6640 6641/* 6642 * ql_dev_free 6643 * Remove queue from device list and frees resources used by queue. 6644 * 6645 * Input: 6646 * ha: adapter state pointer. 6647 * tq: target queue pointer. 6648 * ADAPTER_STATE_LOCK must be already obtained. 6649 * 6650 * Context: 6651 * Kernel context. 6652 */ 6653void 6654ql_dev_free(ql_adapter_state_t *ha, ql_tgt_t *tq) 6655{ 6656 ql_link_t *link; 6657 uint16_t index; 6658 ql_lun_t *lq; 6659 6660 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance); 6661 6662 for (link = tq->lun_queues.first; link != NULL; link = link->next) { 6663 lq = link->base_address; 6664 if (lq->cmd.first != NULL) { 6665 return; 6666 } 6667 } 6668 6669 if (tq->outcnt == 0) { 6670 /* Get head queue index. */ 6671 index = ql_alpa_to_index[tq->d_id.b.al_pa]; 6672 for (link = ha->dev[index].first; link != NULL; 6673 link = link->next) { 6674 if (link->base_address == tq) { 6675 ql_remove_link(&ha->dev[index], link); 6676 6677 link = tq->lun_queues.first; 6678 while (link != NULL) { 6679 lq = link->base_address; 6680 link = link->next; 6681 6682 ql_remove_link(&tq->lun_queues, 6683 &lq->link); 6684 kmem_free(lq, sizeof (ql_lun_t)); 6685 } 6686 6687 mutex_destroy(&tq->mutex); 6688 kmem_free(tq, sizeof (ql_tgt_t)); 6689 break; 6690 } 6691 } 6692 } 6693 6694 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance); 6695} 6696 6697/* 6698 * ql_lun_queue 6699 * Allocate LUN queue if does not exists. 6700 * 6701 * Input: 6702 * ha: adapter state pointer. 6703 * tq: target queue. 6704 * lun: LUN number. 6705 * 6706 * Returns: 6707 * NULL = failure 6708 * 6709 * Context: 6710 * Kernel context. 6711 */ 6712static ql_lun_t * 6713ql_lun_queue(ql_adapter_state_t *ha, ql_tgt_t *tq, uint16_t lun) 6714{ 6715 ql_lun_t *lq; 6716 ql_link_t *link; 6717 6718 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance); 6719 6720 /* Fast path. */ 6721 if (tq->last_lun_queue != NULL && tq->last_lun_queue->lun_no == lun) { 6722 QL_PRINT_3(CE_CONT, "(%d): fast done\n", ha->instance); 6723 return (tq->last_lun_queue); 6724 } 6725 6726 if (lun >= MAX_LUNS) { 6727 EL(ha, "Exceeded MAX_LUN=%d, lun=%d\n", MAX_LUNS, lun); 6728 return (NULL); 6729 } 6730 /* If device queue exists, set proper loop ID. */ 6731 lq = NULL; 6732 for (link = tq->lun_queues.first; link != NULL; link = link->next) { 6733 lq = link->base_address; 6734 if (lq->lun_no == lun) { 6735 QL_PRINT_3(CE_CONT, "(%d): found done\n", ha->instance); 6736 tq->last_lun_queue = lq; 6737 return (lq); 6738 } 6739 } 6740 6741 /* If queue does exist. */ 6742 lq = (ql_lun_t *)kmem_zalloc(sizeof (ql_lun_t), KM_SLEEP); 6743 6744 /* Initialize LUN queue. */ 6745 if (lq != NULL) { 6746 lq->link.base_address = lq; 6747 6748 lq->lun_no = lun; 6749 lq->target_queue = tq; 6750 6751 DEVICE_QUEUE_LOCK(tq); 6752 ql_add_link_b(&tq->lun_queues, &lq->link); 6753 DEVICE_QUEUE_UNLOCK(tq); 6754 tq->last_lun_queue = lq; 6755 } 6756 6757 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance); 6758 6759 return (lq); 6760} 6761 6762/* 6763 * ql_fcp_scsi_cmd 6764 * Process fibre channel (FCP) SCSI protocol commands. 6765 * 6766 * Input: 6767 * ha = adapter state pointer. 6768 * pkt = pointer to fc_packet. 6769 * sp = srb pointer. 6770 * 6771 * Returns: 6772 * FC_SUCCESS - the packet was accepted for transport. 6773 * FC_TRANSPORT_ERROR - a transport error occurred. 6774 * 6775 * Context: 6776 * Kernel context. 6777 */ 6778static int 6779ql_fcp_scsi_cmd(ql_adapter_state_t *ha, fc_packet_t *pkt, ql_srb_t *sp) 6780{ 6781 port_id_t d_id; 6782 ql_tgt_t *tq; 6783 uint64_t *ptr; 6784 uint16_t lun; 6785 6786 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance); 6787 6788 tq = (ql_tgt_t *)pkt->pkt_fca_device; 6789 if (tq == NULL) { 6790 d_id.r.rsvd_1 = 0; 6791 d_id.b24 = pkt->pkt_cmd_fhdr.d_id; 6792 tq = ql_d_id_to_queue(ha, d_id); 6793 } 6794 6795 sp->fcp = (struct fcp_cmd *)pkt->pkt_cmd; 6796 lun = CHAR_TO_SHORT(lobyte(sp->fcp->fcp_ent_addr.ent_addr_0), 6797 hibyte(sp->fcp->fcp_ent_addr.ent_addr_0)); 6798 6799 if (tq != NULL && 6800 (sp->lun_queue = ql_lun_queue(ha, tq, lun)) != NULL) { 6801 6802 /* 6803 * zero out FCP response; 24 Bytes 6804 */ 6805 ptr = (uint64_t *)pkt->pkt_resp; 6806 *ptr++ = 0; *ptr++ = 0; *ptr++ = 0; 6807 6808 /* Handle task management function. */ 6809 if ((sp->fcp->fcp_cntl.cntl_kill_tsk | 6810 sp->fcp->fcp_cntl.cntl_clr_aca | 6811 sp->fcp->fcp_cntl.cntl_reset_tgt | 6812 sp->fcp->fcp_cntl.cntl_reset_lun | 6813 sp->fcp->fcp_cntl.cntl_clr_tsk | 6814 sp->fcp->fcp_cntl.cntl_abort_tsk) != 0) { 6815 ql_task_mgmt(ha, tq, pkt, sp); 6816 } else { 6817 ha->pha->xioctl->IosRequested++; 6818 ha->pha->xioctl->BytesRequested += (uint32_t) 6819 sp->fcp->fcp_data_len; 6820 6821 /* 6822 * Setup for commands with data transfer 6823 */ 6824 sp->iocb = ha->fcp_cmd; 6825 if (sp->fcp->fcp_data_len != 0) { 6826 /* 6827 * FCP data is bound to pkt_data_dma 6828 */ 6829 if (sp->fcp->fcp_cntl.cntl_write_data) { 6830 (void) ddi_dma_sync(pkt->pkt_data_dma, 6831 0, 0, DDI_DMA_SYNC_FORDEV); 6832 } 6833 6834 /* Setup IOCB count. */ 6835 if (pkt->pkt_data_cookie_cnt > ha->cmd_segs) { 6836 uint32_t cnt; 6837 6838 cnt = pkt->pkt_data_cookie_cnt - 6839 ha->cmd_segs; 6840 sp->req_cnt = (uint16_t) 6841 (cnt / ha->cmd_cont_segs); 6842 if (cnt % ha->cmd_cont_segs) { 6843 sp->req_cnt = (uint16_t) 6844 (sp->req_cnt + 2); 6845 } else { 6846 sp->req_cnt++; 6847 } 6848 } else { 6849 sp->req_cnt = 1; 6850 } 6851 } else { 6852 sp->req_cnt = 1; 6853 } 6854 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance); 6855 6856 return (ql_start_cmd(ha, tq, pkt, sp)); 6857 } 6858 } else { 6859 pkt->pkt_state = FC_PKT_LOCAL_RJT; 6860 pkt->pkt_reason = FC_REASON_NO_CONNECTION; 6861 6862 if (!(pkt->pkt_tran_flags & FC_TRAN_NO_INTR) && pkt->pkt_comp) 6863 ql_awaken_task_daemon(ha, sp, 0, 0); 6864 } 6865 6866 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance); 6867 6868 return (FC_SUCCESS); 6869} 6870 6871/* 6872 * ql_task_mgmt 6873 * Task management function processor. 6874 * 6875 * Input: 6876 * ha: adapter state pointer. 6877 * tq: target queue pointer. 6878 * pkt: pointer to fc_packet. 6879 * sp: SRB pointer. 6880 * 6881 * Context: 6882 * Kernel context. 6883 */ 6884static void 6885ql_task_mgmt(ql_adapter_state_t *ha, ql_tgt_t *tq, fc_packet_t *pkt, 6886 ql_srb_t *sp) 6887{ 6888 fcp_rsp_t *fcpr; 6889 struct fcp_rsp_info *rsp; 6890 uint16_t lun; 6891 6892 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance); 6893 6894 fcpr = (fcp_rsp_t *)pkt->pkt_resp; 6895 rsp = (struct fcp_rsp_info *)pkt->pkt_resp + sizeof (fcp_rsp_t); 6896 6897 bzero(fcpr, pkt->pkt_rsplen); 6898 6899 fcpr->fcp_u.fcp_status.rsp_len_set = 1; 6900 fcpr->fcp_response_len = 8; 6901 lun = CHAR_TO_SHORT(lobyte(sp->fcp->fcp_ent_addr.ent_addr_0), 6902 hibyte(sp->fcp->fcp_ent_addr.ent_addr_0)); 6903 6904 if (sp->fcp->fcp_cntl.cntl_clr_aca) { 6905 if (ql_clear_aca(ha, tq, lun) != QL_SUCCESS) { 6906 rsp->rsp_code = FCP_TASK_MGMT_FAILED; 6907 } 6908 } else if (sp->fcp->fcp_cntl.cntl_reset_lun) { 6909 if (ql_lun_reset(ha, tq, lun) != QL_SUCCESS) { 6910 rsp->rsp_code = FCP_TASK_MGMT_FAILED; 6911 } 6912 } else if (sp->fcp->fcp_cntl.cntl_reset_tgt) { 6913 if (ql_target_reset(ha, tq, ha->loop_reset_delay) != 6914 QL_SUCCESS) { 6915 rsp->rsp_code = FCP_TASK_MGMT_FAILED; 6916 } 6917 } else if (sp->fcp->fcp_cntl.cntl_clr_tsk) { 6918 if (ql_clear_task_set(ha, tq, lun) != QL_SUCCESS) { 6919 rsp->rsp_code = FCP_TASK_MGMT_FAILED; 6920 } 6921 } else if (sp->fcp->fcp_cntl.cntl_abort_tsk) { 6922 if (ql_abort_task_set(ha, tq, lun) != QL_SUCCESS) { 6923 rsp->rsp_code = FCP_TASK_MGMT_FAILED; 6924 } 6925 } else { 6926 rsp->rsp_code = FCP_TASK_MGMT_NOT_SUPPTD; 6927 } 6928 6929 pkt->pkt_state = FC_PKT_SUCCESS; 6930 6931 /* Do command callback. */ 6932 if (!(pkt->pkt_tran_flags & FC_TRAN_NO_INTR) && pkt->pkt_comp) { 6933 ql_awaken_task_daemon(ha, sp, 0, 0); 6934 } 6935 6936 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance); 6937} 6938 6939/* 6940 * ql_fcp_ip_cmd 6941 * Process fibre channel (FCP) Internet (IP) protocols commands. 6942 * 6943 * Input: 6944 * ha: adapter state pointer. 6945 * pkt: pointer to fc_packet. 6946 * sp: SRB pointer. 6947 * 6948 * Returns: 6949 * FC_SUCCESS - the packet was accepted for transport. 6950 * FC_TRANSPORT_ERROR - a transport error occurred. 6951 * 6952 * Context: 6953 * Kernel context. 6954 */ 6955static int 6956ql_fcp_ip_cmd(ql_adapter_state_t *ha, fc_packet_t *pkt, ql_srb_t *sp) 6957{ 6958 port_id_t d_id; 6959 ql_tgt_t *tq; 6960 6961 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance); 6962 6963 tq = (ql_tgt_t *)pkt->pkt_fca_device; 6964 if (tq == NULL) { 6965 d_id.r.rsvd_1 = 0; 6966 d_id.b24 = pkt->pkt_cmd_fhdr.d_id; 6967 tq = ql_d_id_to_queue(ha, d_id); 6968 } 6969 6970 if (tq != NULL && (sp->lun_queue = ql_lun_queue(ha, tq, 0)) != NULL) { 6971 /* 6972 * IP data is bound to pkt_cmd_dma 6973 */ 6974 (void) ddi_dma_sync(pkt->pkt_cmd_dma, 6975 0, 0, DDI_DMA_SYNC_FORDEV); 6976 6977 /* Setup IOCB count. */ 6978 sp->iocb = ha->ip_cmd; 6979 if (pkt->pkt_cmd_cookie_cnt > ha->cmd_segs) { 6980 uint32_t cnt; 6981 6982 cnt = pkt->pkt_cmd_cookie_cnt - ha->cmd_segs; 6983 sp->req_cnt = (uint16_t)(cnt / ha->cmd_cont_segs); 6984 if (cnt % ha->cmd_cont_segs) { 6985 sp->req_cnt = (uint16_t)(sp->req_cnt + 2); 6986 } else { 6987 sp->req_cnt++; 6988 } 6989 } else { 6990 sp->req_cnt = 1; 6991 } 6992 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance); 6993 6994 return (ql_start_cmd(ha, tq, pkt, sp)); 6995 } else { 6996 pkt->pkt_state = FC_PKT_LOCAL_RJT; 6997 pkt->pkt_reason = FC_REASON_NO_CONNECTION; 6998 6999 if (!(pkt->pkt_tran_flags & FC_TRAN_NO_INTR) && pkt->pkt_comp) 7000 ql_awaken_task_daemon(ha, sp, 0, 0); 7001 } 7002 7003 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance); 7004 7005 return (FC_SUCCESS); 7006} 7007 7008/* 7009 * ql_fc_services 7010 * Process fibre channel services (name server). 7011 * 7012 * Input: 7013 * ha: adapter state pointer. 7014 * pkt: pointer to fc_packet. 7015 * 7016 * Returns: 7017 * FC_SUCCESS - the packet was accepted for transport. 7018 * FC_TRANSPORT_ERROR - a transport error occurred. 7019 * 7020 * Context: 7021 * Kernel context. 7022 */ 7023static int 7024ql_fc_services(ql_adapter_state_t *ha, fc_packet_t *pkt) 7025{ 7026 uint32_t cnt; 7027 fc_ct_header_t hdr; 7028 la_els_rjt_t rjt; 7029 port_id_t d_id; 7030 ql_tgt_t *tq; 7031 ql_srb_t *sp; 7032 int rval; 7033 7034 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance); 7035 7036 ddi_rep_get8(pkt->pkt_cmd_acc, (uint8_t *)&hdr, 7037 (uint8_t *)pkt->pkt_cmd, sizeof (hdr), DDI_DEV_AUTOINCR); 7038 7039 bzero(&rjt, sizeof (rjt)); 7040 7041 /* Do some sanity checks */ 7042 cnt = (uint32_t)((uint32_t)(hdr.ct_aiusize * 4) + 7043 sizeof (fc_ct_header_t)); 7044 if (cnt > (uint32_t)pkt->pkt_rsplen) { 7045 EL(ha, "FC_ELS_MALFORMED, cnt=%xh, size=%xh\n", cnt, 7046 pkt->pkt_rsplen); 7047 return (FC_ELS_MALFORMED); 7048 } 7049 7050 switch (hdr.ct_fcstype) { 7051 case FCSTYPE_DIRECTORY: 7052 case FCSTYPE_MGMTSERVICE: 7053 /* An FCA must make sure that the header is in big endian */ 7054 ql_cthdr_endian(pkt->pkt_cmd_acc, pkt->pkt_cmd, B_FALSE); 7055 7056 d_id.b24 = pkt->pkt_cmd_fhdr.d_id; 7057 tq = ql_d_id_to_queue(ha, d_id); 7058 sp = (ql_srb_t *)pkt->pkt_fca_private; 7059 if (tq == NULL || 7060 (sp->lun_queue = ql_lun_queue(ha, tq, 0)) == NULL) { 7061 pkt->pkt_state = FC_PKT_LOCAL_RJT; 7062 pkt->pkt_reason = FC_REASON_NO_CONNECTION; 7063 rval = QL_SUCCESS; 7064 break; 7065 } 7066 7067 /* 7068 * Services data is bound to pkt_cmd_dma 7069 */ 7070 (void) ddi_dma_sync(pkt->pkt_cmd_dma, 0, 0, 7071 DDI_DMA_SYNC_FORDEV); 7072 7073 sp->flags |= SRB_MS_PKT; 7074 sp->retry_count = 32; 7075 7076 /* Setup IOCB count. */ 7077 sp->iocb = ha->ms_cmd; 7078 if (pkt->pkt_resp_cookie_cnt > MS_DATA_SEGMENTS) { 7079 cnt = pkt->pkt_resp_cookie_cnt - MS_DATA_SEGMENTS; 7080 sp->req_cnt = 7081 (uint16_t)(cnt / CONT_TYPE_1_DATA_SEGMENTS); 7082 if (cnt % CONT_TYPE_1_DATA_SEGMENTS) { 7083 sp->req_cnt = (uint16_t)(sp->req_cnt + 2); 7084 } else { 7085 sp->req_cnt++; 7086 } 7087 } else { 7088 sp->req_cnt = 1; 7089 } 7090 rval = ql_start_cmd(ha, tq, pkt, sp); 7091 7092 QL_PRINT_3(CE_CONT, "(%d): done, ql_start_cmd=%xh\n", 7093 ha->instance, rval); 7094 7095 return (rval); 7096 7097 default: 7098 EL(ha, "unknown fcstype=%xh\n", hdr.ct_fcstype); 7099 rval = QL_FUNCTION_PARAMETER_ERROR; 7100 break; 7101 } 7102 7103 if (rval != QL_SUCCESS) { 7104 /* Build RJT. */ 7105 rjt.ls_code.ls_code = LA_ELS_RJT; 7106 rjt.reason = FC_REASON_CMD_UNSUPPORTED; 7107 7108 ddi_rep_put8(pkt->pkt_resp_acc, (uint8_t *)&rjt, 7109 (uint8_t *)pkt->pkt_resp, sizeof (rjt), DDI_DEV_AUTOINCR); 7110 7111 pkt->pkt_state = FC_PKT_LOCAL_RJT; 7112 pkt->pkt_reason = FC_REASON_UNSUPPORTED; 7113 EL(ha, "LA_ELS_RJT, FC_REASON_UNSUPPORTED\n"); 7114 } 7115 7116 /* Do command callback. */ 7117 if (!(pkt->pkt_tran_flags & FC_TRAN_NO_INTR) && pkt->pkt_comp) { 7118 ql_awaken_task_daemon(ha, (ql_srb_t *)pkt->pkt_fca_private, 7119 0, 0); 7120 } 7121 7122 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance); 7123 7124 return (FC_SUCCESS); 7125} 7126 7127/* 7128 * ql_cthdr_endian 7129 * Change endianess of ct passthrough header and payload. 7130 * 7131 * Input: 7132 * acc_handle: DMA buffer access handle. 7133 * ct_hdr: Pointer to header. 7134 * restore: Restore first flag. 7135 * 7136 * Context: 7137 * Interrupt or Kernel context, no mailbox commands allowed. 7138 */ 7139void 7140ql_cthdr_endian(ddi_acc_handle_t acc_handle, caddr_t ct_hdr, 7141 boolean_t restore) 7142{ 7143 uint8_t i, *bp; 7144 fc_ct_header_t hdr; 7145 uint32_t *hdrp = (uint32_t *)&hdr; 7146 7147 ddi_rep_get8(acc_handle, (uint8_t *)&hdr, 7148 (uint8_t *)ct_hdr, sizeof (hdr), DDI_DEV_AUTOINCR); 7149 7150 if (restore) { 7151 for (i = 0; i < ((sizeof (hdr)) / (sizeof (uint32_t))); i++) { 7152 *hdrp = BE_32(*hdrp); 7153 hdrp++; 7154 } 7155 } 7156 7157 if (hdr.ct_fcstype == FCSTYPE_DIRECTORY) { 7158 bp = (uint8_t *)ct_hdr + sizeof (fc_ct_header_t); 7159 7160 switch (hdr.ct_cmdrsp) { 7161 case NS_GA_NXT: 7162 case NS_GPN_ID: 7163 case NS_GNN_ID: 7164 case NS_GCS_ID: 7165 case NS_GFT_ID: 7166 case NS_GSPN_ID: 7167 case NS_GPT_ID: 7168 case NS_GID_FT: 7169 case NS_GID_PT: 7170 case NS_RPN_ID: 7171 case NS_RNN_ID: 7172 case NS_RSPN_ID: 7173 case NS_DA_ID: 7174 BIG_ENDIAN_32(bp); 7175 break; 7176 case NS_RFT_ID: 7177 case NS_RCS_ID: 7178 case NS_RPT_ID: 7179 BIG_ENDIAN_32(bp); 7180 bp += 4; 7181 BIG_ENDIAN_32(bp); 7182 break; 7183 case NS_GNN_IP: 7184 case NS_GIPA_IP: 7185 BIG_ENDIAN(bp, 16); 7186 break; 7187 case NS_RIP_NN: 7188 bp += 8; 7189 BIG_ENDIAN(bp, 16); 7190 break; 7191 case NS_RIPA_NN: 7192 bp += 8; 7193 BIG_ENDIAN_64(bp); 7194 break; 7195 default: 7196 break; 7197 } 7198 } 7199 7200 if (restore == B_FALSE) { 7201 for (i = 0; i < ((sizeof (hdr)) / (sizeof (uint32_t))); i++) { 7202 *hdrp = BE_32(*hdrp); 7203 hdrp++; 7204 } 7205 } 7206 7207 ddi_rep_put8(acc_handle, (uint8_t *)&hdr, 7208 (uint8_t *)ct_hdr, sizeof (hdr), DDI_DEV_AUTOINCR); 7209} 7210 7211/* 7212 * ql_start_cmd 7213 * Finishes starting fibre channel protocol (FCP) command. 7214 * 7215 * Input: 7216 * ha: adapter state pointer. 7217 * tq: target queue pointer. 7218 * pkt: pointer to fc_packet. 7219 * sp: SRB pointer. 7220 * 7221 * Context: 7222 * Kernel context. 7223 */ 7224static int 7225ql_start_cmd(ql_adapter_state_t *ha, ql_tgt_t *tq, fc_packet_t *pkt, 7226 ql_srb_t *sp) 7227{ 7228 int rval = FC_SUCCESS; 7229 time_t poll_wait = 0; 7230 ql_lun_t *lq = sp->lun_queue; 7231 7232 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance); 7233 7234 sp->handle = 0; 7235 7236 /* Set poll for finish. */ 7237 if (pkt->pkt_tran_flags & FC_TRAN_NO_INTR) { 7238 sp->flags |= SRB_POLL; 7239 if (pkt->pkt_timeout == 0) { 7240 pkt->pkt_timeout = SCSI_POLL_TIMEOUT; 7241 } 7242 } 7243 7244 /* Acquire device queue lock. */ 7245 DEVICE_QUEUE_LOCK(tq); 7246 7247 /* 7248 * If we need authentication, report device busy to 7249 * upper layers to retry later 7250 */ 7251 if (tq->flags & (TQF_RSCN_RCVD | TQF_NEED_AUTHENTICATION)) { 7252 DEVICE_QUEUE_UNLOCK(tq); 7253 EL(ha, "failed, FC_DEVICE_BUSY=%xh, d_id=%xh\n", tq->flags, 7254 tq->d_id.b24); 7255 return (FC_DEVICE_BUSY); 7256 } 7257 7258 /* Insert command onto watchdog queue. */ 7259 if (!(pkt->pkt_tran_flags & FC_TRAN_DUMPING)) { 7260 ql_timeout_insert(ha, tq, sp); 7261 } else { 7262 /* 7263 * Run dump requests in polled mode as kernel threads 7264 * and interrupts may have been disabled. 7265 */ 7266 sp->flags |= SRB_POLL; 7267 sp->init_wdg_q_time = 0; 7268 sp->isp_timeout = 0; 7269 } 7270 7271 /* If a polling command setup wait time. */ 7272 if (sp->flags & SRB_POLL) { 7273 if (sp->flags & SRB_WATCHDOG_ENABLED) { 7274 poll_wait = (sp->wdg_q_time + 2) * WATCHDOG_TIME; 7275 } else { 7276 poll_wait = pkt->pkt_timeout; 7277 } 7278 } 7279 7280 if (ha->pha->flags & ABORT_CMDS_LOOP_DOWN_TMO && 7281 (CFG_IST(ha, CFG_ENABLE_LINK_DOWN_REPORTING))) { 7282 /* Set ending status. */ 7283 sp->pkt->pkt_reason = CS_PORT_UNAVAILABLE; 7284 7285 /* Call done routine to handle completions. */ 7286 sp->cmd.next = NULL; 7287 DEVICE_QUEUE_UNLOCK(tq); 7288 ql_done(&sp->cmd); 7289 } else { 7290 if (ddi_in_panic() && (sp->flags & SRB_POLL)) { 7291 int do_lip = 0; 7292 7293 DEVICE_QUEUE_UNLOCK(tq); 7294 7295 ADAPTER_STATE_LOCK(ha); 7296 if ((do_lip = ha->pha->lip_on_panic) == 0) { 7297 ha->pha->lip_on_panic++; 7298 } 7299 ADAPTER_STATE_UNLOCK(ha); 7300 7301 if (!do_lip) { 7302 7303 /* 7304 * That Qlogic F/W performs PLOGI, PRLI, etc 7305 * is helpful here. If a PLOGI fails for some 7306 * reason, you would get CS_PORT_LOGGED_OUT 7307 * or some such error; and we should get a 7308 * careful polled mode login kicked off inside 7309 * of this driver itself. You don't have FC 7310 * transport's services as all threads are 7311 * suspended, interrupts disabled, and so 7312 * on. Right now we do re-login if the packet 7313 * state isn't FC_PKT_SUCCESS. 7314 */ 7315 (void) ql_abort_isp(ha); 7316 } 7317 7318 ql_start_iocb(ha, sp); 7319 } else { 7320 /* Add the command to the device queue */ 7321 if (pkt->pkt_tran_flags & FC_TRAN_HI_PRIORITY) { 7322 ql_add_link_t(&lq->cmd, &sp->cmd); 7323 } else { 7324 ql_add_link_b(&lq->cmd, &sp->cmd); 7325 } 7326 7327 sp->flags |= SRB_IN_DEVICE_QUEUE; 7328 7329 /* Check whether next message can be processed */ 7330 ql_next(ha, lq); 7331 } 7332 } 7333 7334 /* If polling, wait for finish. */ 7335 if (poll_wait) { 7336 if (ql_poll_cmd(ha, sp, poll_wait) != QL_SUCCESS) { 7337 int res; 7338 7339 res = ql_abort((opaque_t)ha, pkt, 0); 7340 if (res != FC_SUCCESS && res != FC_ABORTED) { 7341 DEVICE_QUEUE_LOCK(tq); 7342 ql_remove_link(&lq->cmd, &sp->cmd); 7343 sp->flags &= ~SRB_IN_DEVICE_QUEUE; 7344 DEVICE_QUEUE_UNLOCK(tq); 7345 } 7346 } 7347 7348 if (pkt->pkt_state != FC_PKT_SUCCESS) { 7349 EL(ha, "failed, FC_TRANSPORT_ERROR\n"); 7350 rval = FC_TRANSPORT_ERROR; 7351 } 7352 7353 if (ddi_in_panic()) { 7354 if (pkt->pkt_state != FC_PKT_SUCCESS) { 7355 port_id_t d_id; 7356 7357 /* 7358 * successful LOGIN implies by design 7359 * that PRLI also succeeded for disks 7360 * Note also that there is no special 7361 * mailbox command to send PRLI. 7362 */ 7363 d_id.b24 = pkt->pkt_cmd_fhdr.d_id; 7364 (void) ql_login_port(ha, d_id); 7365 } 7366 } 7367 7368 /* 7369 * This should only happen during CPR dumping 7370 */ 7371 if (!(pkt->pkt_tran_flags & FC_TRAN_NO_INTR) && 7372 pkt->pkt_comp) { 7373 sp->flags &= ~SRB_POLL; 7374 (*pkt->pkt_comp)(pkt); 7375 } 7376 } 7377 7378 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance); 7379 7380 return (rval); 7381} 7382 7383/* 7384 * ql_poll_cmd 7385 * Polls commands for completion. 7386 * 7387 * Input: 7388 * ha = adapter state pointer. 7389 * sp = SRB command pointer. 7390 * poll_wait = poll wait time in seconds. 7391 * 7392 * Returns: 7393 * QL local function return status code. 7394 * 7395 * Context: 7396 * Kernel context. 7397 */ 7398static int 7399ql_poll_cmd(ql_adapter_state_t *vha, ql_srb_t *sp, time_t poll_wait) 7400{ 7401 int rval = QL_SUCCESS; 7402 time_t msecs_left = poll_wait * 100; /* 10ms inc */ 7403 ql_adapter_state_t *ha = vha->pha; 7404 7405 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance); 7406 7407 while (sp->flags & SRB_POLL) { 7408 7409 if ((ha->flags & INTERRUPTS_ENABLED) == 0 || 7410 ha->idle_timer >= 15 || ddi_in_panic()) { 7411 7412 /* If waiting for restart, do it now. */ 7413 if (ha->port_retry_timer != 0) { 7414 ADAPTER_STATE_LOCK(ha); 7415 ha->port_retry_timer = 0; 7416 ADAPTER_STATE_UNLOCK(ha); 7417 7418 TASK_DAEMON_LOCK(ha); 7419 ha->task_daemon_flags |= PORT_RETRY_NEEDED; 7420 TASK_DAEMON_UNLOCK(ha); 7421 } 7422 7423 if ((CFG_IST(ha, CFG_CTRL_242581) ? 7424 RD32_IO_REG(ha, istatus) : 7425 RD16_IO_REG(ha, istatus)) & RISC_INT) { 7426 (void) ql_isr((caddr_t)ha); 7427 INTR_LOCK(ha); 7428 ha->intr_claimed = TRUE; 7429 INTR_UNLOCK(ha); 7430 } 7431 7432 /* 7433 * Call task thread function in case the 7434 * daemon is not running. 7435 */ 7436 TASK_DAEMON_LOCK(ha); 7437 7438 if (!ddi_in_panic() && QL_DAEMON_NOT_ACTIVE(ha) && 7439 QL_TASK_PENDING(ha)) { 7440 ha->task_daemon_flags |= TASK_THREAD_CALLED; 7441 ql_task_thread(ha); 7442 ha->task_daemon_flags &= ~TASK_THREAD_CALLED; 7443 } 7444 7445 TASK_DAEMON_UNLOCK(ha); 7446 } 7447 7448 if (msecs_left < 10) { 7449 rval = QL_FUNCTION_TIMEOUT; 7450 break; 7451 } 7452 7453 /* 7454 * Polling interval is 10 milli seconds; Increasing 7455 * the polling interval to seconds since disk IO 7456 * timeout values are ~60 seconds is tempting enough, 7457 * but CPR dump time increases, and so will the crash 7458 * dump time; Don't toy with the settings without due 7459 * consideration for all the scenarios that will be 7460 * impacted. 7461 */ 7462 ql_delay(ha, 10000); 7463 msecs_left -= 10; 7464 } 7465 7466 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance); 7467 7468 return (rval); 7469} 7470 7471/* 7472 * ql_next 7473 * Retrieve and process next job in the device queue. 7474 * 7475 * Input: 7476 * ha: adapter state pointer. 7477 * lq: LUN queue pointer. 7478 * DEVICE_QUEUE_LOCK must be already obtained. 7479 * 7480 * Output: 7481 * Releases DEVICE_QUEUE_LOCK upon exit. 7482 * 7483 * Context: 7484 * Interrupt or Kernel context, no mailbox commands allowed. 7485 */ 7486void 7487ql_next(ql_adapter_state_t *vha, ql_lun_t *lq) 7488{ 7489 ql_srb_t *sp; 7490 ql_link_t *link; 7491 ql_tgt_t *tq = lq->target_queue; 7492 ql_adapter_state_t *ha = vha->pha; 7493 7494 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance); 7495 7496 if (ddi_in_panic()) { 7497 DEVICE_QUEUE_UNLOCK(tq); 7498 QL_PRINT_3(CE_CONT, "(%d): panic/active exit\n", 7499 ha->instance); 7500 return; 7501 } 7502 7503 while ((link = lq->cmd.first) != NULL) { 7504 sp = link->base_address; 7505 7506 /* Exit if can not start commands. */ 7507 if (DRIVER_SUSPENDED(ha) || 7508 (ha->flags & ONLINE) == 0 || 7509 !VALID_DEVICE_ID(ha, tq->loop_id) || 7510 sp->flags & SRB_ABORT || 7511 tq->flags & (TQF_RSCN_RCVD | TQF_NEED_AUTHENTICATION | 7512 TQF_QUEUE_SUSPENDED)) { 7513 EL(vha, "break, d_id=%xh, tdf=%xh, tqf=%xh, spf=%xh, " 7514 "haf=%xh, loop_id=%xh\n", tq->d_id.b24, 7515 ha->task_daemon_flags, tq->flags, sp->flags, 7516 ha->flags, tq->loop_id); 7517 break; 7518 } 7519 7520 /* 7521 * Find out the LUN number for untagged command use. 7522 * If there is an untagged command pending for the LUN, 7523 * we would not submit another untagged command 7524 * or if reached LUN execution throttle. 7525 */ 7526 if (sp->flags & SRB_FCP_CMD_PKT) { 7527 if (lq->flags & LQF_UNTAGGED_PENDING || 7528 lq->lun_outcnt >= ha->execution_throttle) { 7529 QL_PRINT_8(CE_CONT, "(%d): break, d_id=%xh, " 7530 "lf=%xh, lun_outcnt=%xh\n", ha->instance, 7531 tq->d_id.b24, lq->flags, lq->lun_outcnt); 7532 break; 7533 } 7534 if (sp->fcp->fcp_cntl.cntl_qtype == 7535 FCP_QTYPE_UNTAGGED) { 7536 /* 7537 * Set the untagged-flag for the LUN 7538 * so that no more untagged commands 7539 * can be submitted for this LUN. 7540 */ 7541 lq->flags |= LQF_UNTAGGED_PENDING; 7542 } 7543 7544 /* Count command as sent. */ 7545 lq->lun_outcnt++; 7546 } 7547 7548 /* Remove srb from device queue. */ 7549 ql_remove_link(&lq->cmd, &sp->cmd); 7550 sp->flags &= ~SRB_IN_DEVICE_QUEUE; 7551 7552 tq->outcnt++; 7553 7554 ql_start_iocb(vha, sp); 7555 } 7556 7557 /* Release device queue lock. */ 7558 DEVICE_QUEUE_UNLOCK(tq); 7559 7560 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance); 7561} 7562 7563/* 7564 * ql_done 7565 * Process completed commands. 7566 * 7567 * Input: 7568 * link: first command link in chain. 7569 * 7570 * Context: 7571 * Interrupt or Kernel context, no mailbox commands allowed. 7572 */ 7573void 7574ql_done(ql_link_t *link) 7575{ 7576 ql_adapter_state_t *ha; 7577 ql_link_t *next_link; 7578 ql_srb_t *sp; 7579 ql_tgt_t *tq; 7580 ql_lun_t *lq; 7581 7582 QL_PRINT_3(CE_CONT, "started\n"); 7583 7584 for (; link != NULL; link = next_link) { 7585 next_link = link->next; 7586 sp = link->base_address; 7587 ha = sp->ha; 7588 7589 if (sp->flags & SRB_UB_CALLBACK) { 7590 QL_UB_LOCK(ha); 7591 if (sp->flags & SRB_UB_IN_ISP) { 7592 if (ha->ub_outcnt != 0) { 7593 ha->ub_outcnt--; 7594 } 7595 QL_UB_UNLOCK(ha); 7596 ql_isp_rcvbuf(ha); 7597 QL_UB_LOCK(ha); 7598 } 7599 QL_UB_UNLOCK(ha); 7600 ql_awaken_task_daemon(ha, sp, 0, 0); 7601 } else { 7602 /* Free outstanding command slot. */ 7603 if (sp->handle != 0) { 7604 ha->outstanding_cmds[ 7605 sp->handle & OSC_INDEX_MASK] = NULL; 7606 sp->handle = 0; 7607 sp->flags &= ~SRB_IN_TOKEN_ARRAY; 7608 } 7609 7610 /* Acquire device queue lock. */ 7611 lq = sp->lun_queue; 7612 tq = lq->target_queue; 7613 DEVICE_QUEUE_LOCK(tq); 7614 7615 /* Decrement outstanding commands on device. */ 7616 if (tq->outcnt != 0) { 7617 tq->outcnt--; 7618 } 7619 7620 if (sp->flags & SRB_FCP_CMD_PKT) { 7621 if (sp->fcp->fcp_cntl.cntl_qtype == 7622 FCP_QTYPE_UNTAGGED) { 7623 /* 7624 * Clear the flag for this LUN so that 7625 * untagged commands can be submitted 7626 * for it. 7627 */ 7628 lq->flags &= ~LQF_UNTAGGED_PENDING; 7629 } 7630 7631 if (lq->lun_outcnt != 0) { 7632 lq->lun_outcnt--; 7633 } 7634 } 7635 7636 /* Reset port down retry count on good completion. */ 7637 if (sp->pkt->pkt_reason == CS_COMPLETE) { 7638 tq->port_down_retry_count = 7639 ha->port_down_retry_count; 7640 tq->qfull_retry_count = ha->qfull_retry_count; 7641 } 7642 7643 /* Place request back on top of target command queue */ 7644 if ((sp->flags & (SRB_MS_PKT | SRB_ELS_PKT) || 7645 !(tq->flags & TQF_NEED_AUTHENTICATION)) && 7646 sp->flags & SRB_RETRY && 7647 (sp->flags & SRB_WATCHDOG_ENABLED && 7648 sp->wdg_q_time > 1)) { 7649 sp->flags &= ~(SRB_ISP_STARTED | 7650 SRB_ISP_COMPLETED | SRB_RETRY); 7651 7652 /* Reset watchdog timer */ 7653 sp->wdg_q_time = sp->init_wdg_q_time; 7654 7655 /* Issue marker command on reset status. */ 7656 if (!(ha->task_daemon_flags & LOOP_DOWN) && 7657 (sp->pkt->pkt_reason == CS_RESET || 7658 (CFG_IST(ha, CFG_CTRL_242581) && 7659 sp->pkt->pkt_reason == CS_ABORTED))) { 7660 (void) ql_marker(ha, tq->loop_id, 0, 7661 MK_SYNC_ID); 7662 } 7663 7664 ql_add_link_t(&lq->cmd, &sp->cmd); 7665 sp->flags |= SRB_IN_DEVICE_QUEUE; 7666 ql_next(ha, lq); 7667 } else { 7668 /* Remove command from watchdog queue. */ 7669 if (sp->flags & SRB_WATCHDOG_ENABLED) { 7670 ql_remove_link(&tq->wdg, &sp->wdg); 7671 sp->flags &= ~SRB_WATCHDOG_ENABLED; 7672 } 7673 7674 if (lq->cmd.first != NULL) { 7675 ql_next(ha, lq); 7676 } else { 7677 /* Release LU queue specific lock. */ 7678 DEVICE_QUEUE_UNLOCK(tq); 7679 if (ha->pha->pending_cmds.first != 7680 NULL) { 7681 ql_start_iocb(ha, NULL); 7682 } 7683 } 7684 7685 /* Sync buffers if required. */ 7686 if (sp->flags & (SRB_MS_PKT | SRB_ELS_PKT)) { 7687 (void) ddi_dma_sync( 7688 sp->pkt->pkt_resp_dma, 7689 0, 0, DDI_DMA_SYNC_FORCPU); 7690 } 7691 7692 /* Map ISP completion codes. */ 7693 sp->pkt->pkt_expln = FC_EXPLN_NONE; 7694 sp->pkt->pkt_action = FC_ACTION_RETRYABLE; 7695 switch (sp->pkt->pkt_reason) { 7696 case CS_COMPLETE: 7697 sp->pkt->pkt_state = FC_PKT_SUCCESS; 7698 break; 7699 case CS_RESET: 7700 /* Issue marker command. */ 7701 if (!(ha->task_daemon_flags & 7702 LOOP_DOWN)) { 7703 (void) ql_marker(ha, 7704 tq->loop_id, 0, 7705 MK_SYNC_ID); 7706 } 7707 sp->pkt->pkt_state = 7708 FC_PKT_PORT_OFFLINE; 7709 sp->pkt->pkt_reason = 7710 FC_REASON_ABORTED; 7711 break; 7712 case CS_RESOUCE_UNAVAILABLE: 7713 sp->pkt->pkt_state = FC_PKT_LOCAL_BSY; 7714 sp->pkt->pkt_reason = 7715 FC_REASON_PKT_BUSY; 7716 break; 7717 7718 case CS_TIMEOUT: 7719 sp->pkt->pkt_state = FC_PKT_TIMEOUT; 7720 sp->pkt->pkt_reason = 7721 FC_REASON_HW_ERROR; 7722 break; 7723 case CS_DATA_OVERRUN: 7724 sp->pkt->pkt_state = FC_PKT_LOCAL_RJT; 7725 sp->pkt->pkt_reason = 7726 FC_REASON_OVERRUN; 7727 break; 7728 case CS_PORT_UNAVAILABLE: 7729 case CS_PORT_LOGGED_OUT: 7730 sp->pkt->pkt_state = 7731 FC_PKT_PORT_OFFLINE; 7732 sp->pkt->pkt_reason = 7733 FC_REASON_LOGIN_REQUIRED; 7734 ql_send_logo(ha, tq, NULL); 7735 break; 7736 case CS_PORT_CONFIG_CHG: 7737 sp->pkt->pkt_state = 7738 FC_PKT_PORT_OFFLINE; 7739 sp->pkt->pkt_reason = 7740 FC_REASON_OFFLINE; 7741 break; 7742 case CS_QUEUE_FULL: 7743 sp->pkt->pkt_state = FC_PKT_LOCAL_RJT; 7744 sp->pkt->pkt_reason = FC_REASON_QFULL; 7745 break; 7746 7747 case CS_ABORTED: 7748 DEVICE_QUEUE_LOCK(tq); 7749 if (tq->flags & (TQF_RSCN_RCVD | 7750 TQF_NEED_AUTHENTICATION)) { 7751 sp->pkt->pkt_state = 7752 FC_PKT_PORT_OFFLINE; 7753 sp->pkt->pkt_reason = 7754 FC_REASON_LOGIN_REQUIRED; 7755 } else { 7756 sp->pkt->pkt_state = 7757 FC_PKT_LOCAL_RJT; 7758 sp->pkt->pkt_reason = 7759 FC_REASON_ABORTED; 7760 } 7761 DEVICE_QUEUE_UNLOCK(tq); 7762 break; 7763 7764 case CS_TRANSPORT: 7765 sp->pkt->pkt_state = FC_PKT_LOCAL_RJT; 7766 sp->pkt->pkt_reason = 7767 FC_PKT_TRAN_ERROR; 7768 break; 7769 7770 case CS_DATA_UNDERRUN: 7771 sp->pkt->pkt_state = FC_PKT_LOCAL_RJT; 7772 sp->pkt->pkt_reason = 7773 FC_REASON_UNDERRUN; 7774 break; 7775 case CS_DMA_ERROR: 7776 case CS_BAD_PAYLOAD: 7777 case CS_UNKNOWN: 7778 case CS_CMD_FAILED: 7779 default: 7780 sp->pkt->pkt_state = FC_PKT_LOCAL_RJT; 7781 sp->pkt->pkt_reason = 7782 FC_REASON_HW_ERROR; 7783 break; 7784 } 7785 7786 /* Now call the pkt completion callback */ 7787 if (sp->flags & SRB_POLL) { 7788 sp->flags &= ~SRB_POLL; 7789 } else if (sp->pkt->pkt_comp) { 7790 if (sp->pkt->pkt_tran_flags & 7791 FC_TRAN_IMMEDIATE_CB) { 7792 (*sp->pkt->pkt_comp)(sp->pkt); 7793 } else { 7794 ql_awaken_task_daemon(ha, sp, 7795 0, 0); 7796 } 7797 } 7798 } 7799 } 7800 } 7801 7802 QL_PRINT_3(CE_CONT, "done\n"); 7803} 7804 7805/* 7806 * ql_awaken_task_daemon 7807 * Adds command completion callback to callback queue and/or 7808 * awakens task daemon thread. 7809 * 7810 * Input: 7811 * ha: adapter state pointer. 7812 * sp: srb pointer. 7813 * set_flags: task daemon flags to set. 7814 * reset_flags: task daemon flags to reset. 7815 * 7816 * Context: 7817 * Interrupt or Kernel context, no mailbox commands allowed. 7818 */ 7819void 7820ql_awaken_task_daemon(ql_adapter_state_t *vha, ql_srb_t *sp, 7821 uint32_t set_flags, uint32_t reset_flags) 7822{ 7823 ql_adapter_state_t *ha = vha->pha; 7824 7825 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance); 7826 7827 /* Acquire task daemon lock. */ 7828 TASK_DAEMON_LOCK(ha); 7829 7830 if (set_flags & ISP_ABORT_NEEDED) { 7831 if (ha->task_daemon_flags & ABORT_ISP_ACTIVE) { 7832 set_flags &= ~ISP_ABORT_NEEDED; 7833 } 7834 } 7835 7836 ha->task_daemon_flags |= set_flags; 7837 ha->task_daemon_flags &= ~reset_flags; 7838 7839 if (QL_DAEMON_SUSPENDED(ha)) { 7840 if (sp != NULL) { 7841 TASK_DAEMON_UNLOCK(ha); 7842 7843 /* Do callback. */ 7844 if (sp->flags & SRB_UB_CALLBACK) { 7845 ql_unsol_callback(sp); 7846 } else { 7847 (*sp->pkt->pkt_comp)(sp->pkt); 7848 } 7849 } else { 7850 if (!(curthread->t_flag & T_INTR_THREAD) && 7851 !(ha->task_daemon_flags & TASK_THREAD_CALLED)) { 7852 ha->task_daemon_flags |= TASK_THREAD_CALLED; 7853 ql_task_thread(ha); 7854 ha->task_daemon_flags &= ~TASK_THREAD_CALLED; 7855 } 7856 7857 TASK_DAEMON_UNLOCK(ha); 7858 } 7859 } else { 7860 if (sp != NULL) { 7861 ql_add_link_b(&ha->callback_queue, &sp->cmd); 7862 } 7863 7864 if (ha->task_daemon_flags & TASK_DAEMON_SLEEPING_FLG) { 7865 cv_broadcast(&ha->cv_task_daemon); 7866 } 7867 TASK_DAEMON_UNLOCK(ha); 7868 } 7869 7870 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance); 7871} 7872 7873/* 7874 * ql_task_daemon 7875 * Thread that is awaken by the driver when a 7876 * background needs to be done. 7877 * 7878 * Input: 7879 * arg = adapter state pointer. 7880 * 7881 * Context: 7882 * Kernel context. 7883 */ 7884static void 7885ql_task_daemon(void *arg) 7886{ 7887 ql_adapter_state_t *ha = (void *)arg; 7888 7889 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance); 7890 7891 CALLB_CPR_INIT(&ha->cprinfo, &ha->task_daemon_mutex, callb_generic_cpr, 7892 "ql_task_daemon"); 7893 7894 /* Acquire task daemon lock. */ 7895 TASK_DAEMON_LOCK(ha); 7896 7897 ha->task_daemon_flags |= TASK_DAEMON_ALIVE_FLG; 7898 7899 while ((ha->task_daemon_flags & TASK_DAEMON_STOP_FLG) == 0) { 7900 ql_task_thread(ha); 7901 7902 QL_PRINT_3(CE_CONT, "(%d): Going to sleep\n", ha->instance); 7903 7904 /* 7905 * Before we wait on the conditional variable, we 7906 * need to check if STOP_FLG is set for us to terminate 7907 */ 7908 if (ha->task_daemon_flags & TASK_DAEMON_STOP_FLG) { 7909 break; 7910 } 7911 7912 /*LINTED [Solaris CALLB_CPR_SAFE_BEGIN Lint error]*/ 7913 CALLB_CPR_SAFE_BEGIN(&ha->cprinfo); 7914 7915 ha->task_daemon_flags |= TASK_DAEMON_SLEEPING_FLG; 7916 7917 /* If killed, stop task daemon */ 7918 if (cv_wait_sig(&ha->cv_task_daemon, 7919 &ha->task_daemon_mutex) == 0) { 7920 ha->task_daemon_flags |= TASK_DAEMON_STOP_FLG; 7921 } 7922 7923 ha->task_daemon_flags &= ~TASK_DAEMON_SLEEPING_FLG; 7924 7925 /*LINTED [Solaris CALLB_CPR_SAFE_END Lint error]*/ 7926 CALLB_CPR_SAFE_END(&ha->cprinfo, &ha->task_daemon_mutex); 7927 7928 QL_PRINT_3(CE_CONT, "(%d): Awakened\n", ha->instance); 7929 } 7930 7931 ha->task_daemon_flags &= ~(TASK_DAEMON_STOP_FLG | 7932 TASK_DAEMON_ALIVE_FLG); 7933 7934 /*LINTED [Solaris CALLB_CPR_EXIT Lint error]*/ 7935 CALLB_CPR_EXIT(&ha->cprinfo); 7936 7937 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance); 7938 7939 thread_exit(); 7940} 7941 7942/* 7943 * ql_task_thread 7944 * Thread run by daemon. 7945 * 7946 * Input: 7947 * ha = adapter state pointer. 7948 * TASK_DAEMON_LOCK must be acquired prior to call. 7949 * 7950 * Context: 7951 * Kernel context. 7952 */ 7953static void 7954ql_task_thread(ql_adapter_state_t *ha) 7955{ 7956 int loop_again, rval; 7957 ql_srb_t *sp; 7958 ql_head_t *head; 7959 ql_link_t *link; 7960 caddr_t msg; 7961 ql_adapter_state_t *vha; 7962 7963 do { 7964 QL_PRINT_3(CE_CONT, "(%d): task_daemon_flags=%xh\n", 7965 ha->instance, ha->task_daemon_flags); 7966 7967 loop_again = FALSE; 7968 7969 QL_PM_LOCK(ha); 7970 if (ha->power_level != PM_LEVEL_D0) { 7971 QL_PM_UNLOCK(ha); 7972 ha->task_daemon_flags |= TASK_DAEMON_STALLED_FLG; 7973 break; 7974 } 7975 QL_PM_UNLOCK(ha); 7976 7977 /* IDC acknowledge needed. */ 7978 if (ha->task_daemon_flags & IDC_ACK_NEEDED) { 7979 ha->task_daemon_flags &= ~IDC_ACK_NEEDED; 7980 ADAPTER_STATE_LOCK(ha); 7981 switch (ha->idc_mb[2]) { 7982 case IDC_OPC_DRV_START: 7983 if (ha->idc_restart_mpi != 0) { 7984 ha->idc_restart_mpi--; 7985 if (ha->idc_restart_mpi == 0) { 7986 ha->restart_mpi_timer = 0; 7987 ha->task_daemon_flags &= 7988 ~TASK_DAEMON_STALLED_FLG; 7989 } 7990 } 7991 if (ha->idc_flash_acc != 0) { 7992 ha->idc_flash_acc--; 7993 if (ha->idc_flash_acc == 0) { 7994 ha->flash_acc_timer = 0; 7995 GLOBAL_HW_LOCK(); 7996 } 7997 } 7998 break; 7999 case IDC_OPC_FLASH_ACC: 8000 ha->flash_acc_timer = 30; 8001 if (ha->idc_flash_acc == 0) { 8002 GLOBAL_HW_UNLOCK(); 8003 } 8004 ha->idc_flash_acc++; 8005 break; 8006 case IDC_OPC_RESTART_MPI: 8007 ha->restart_mpi_timer = 30; 8008 ha->idc_restart_mpi++; 8009 ha->task_daemon_flags |= 8010 TASK_DAEMON_STALLED_FLG; 8011 break; 8012 default: 8013 EL(ha, "Unknown IDC opcode=%xh\n", 8014 ha->idc_mb[2]); 8015 break; 8016 } 8017 ADAPTER_STATE_UNLOCK(ha); 8018 8019 if (ha->idc_mb[1] & IDC_TIMEOUT_MASK) { 8020 TASK_DAEMON_UNLOCK(ha); 8021 rval = ql_idc_ack(ha); 8022 if (rval != QL_SUCCESS) { 8023 EL(ha, "idc_ack status=%xh\n", rval); 8024 } 8025 TASK_DAEMON_LOCK(ha); 8026 loop_again = TRUE; 8027 } 8028 } 8029 8030 if (ha->flags & ADAPTER_SUSPENDED || 8031 ha->task_daemon_flags & (TASK_DAEMON_STOP_FLG | 8032 DRIVER_STALL) || 8033 (ha->flags & ONLINE) == 0) { 8034 ha->task_daemon_flags |= TASK_DAEMON_STALLED_FLG; 8035 break; 8036 } 8037 ha->task_daemon_flags &= ~TASK_DAEMON_STALLED_FLG; 8038 8039 if (ha->task_daemon_flags & ISP_ABORT_NEEDED) { 8040 TASK_DAEMON_UNLOCK(ha); 8041 ql_port_state(ha, FC_STATE_OFFLINE, FC_STATE_CHANGE); 8042 TASK_DAEMON_LOCK(ha); 8043 loop_again = TRUE; 8044 } 8045 8046 /* Idle Check. */ 8047 if (ha->task_daemon_flags & TASK_DAEMON_IDLE_CHK_FLG) { 8048 ha->task_daemon_flags &= ~TASK_DAEMON_IDLE_CHK_FLG; 8049 if (!(ha->task_daemon_flags & QL_SUSPENDED)) { 8050 TASK_DAEMON_UNLOCK(ha); 8051 ql_idle_check(ha); 8052 TASK_DAEMON_LOCK(ha); 8053 loop_again = TRUE; 8054 } 8055 } 8056 8057 /* Crystal+ port#0 bypass transition */ 8058 if (ha->task_daemon_flags & HANDLE_PORT_BYPASS_CHANGE) { 8059 ha->task_daemon_flags &= ~HANDLE_PORT_BYPASS_CHANGE; 8060 TASK_DAEMON_UNLOCK(ha); 8061 (void) ql_initiate_lip(ha); 8062 TASK_DAEMON_LOCK(ha); 8063 loop_again = TRUE; 8064 } 8065 8066 /* Abort queues needed. */ 8067 if (ha->task_daemon_flags & ABORT_QUEUES_NEEDED) { 8068 ha->task_daemon_flags &= ~ABORT_QUEUES_NEEDED; 8069 TASK_DAEMON_UNLOCK(ha); 8070 ql_abort_queues(ha); 8071 TASK_DAEMON_LOCK(ha); 8072 } 8073 8074 /* Not suspended, awaken waiting routines. */ 8075 if (!(ha->task_daemon_flags & QL_SUSPENDED) && 8076 ha->task_daemon_flags & SUSPENDED_WAKEUP_FLG) { 8077 ha->task_daemon_flags &= ~SUSPENDED_WAKEUP_FLG; 8078 cv_broadcast(&ha->cv_dr_suspended); 8079 loop_again = TRUE; 8080 } 8081 8082 /* Handle RSCN changes. */ 8083 for (vha = ha; vha != NULL; vha = vha->vp_next) { 8084 if (vha->task_daemon_flags & RSCN_UPDATE_NEEDED) { 8085 vha->task_daemon_flags &= ~RSCN_UPDATE_NEEDED; 8086 TASK_DAEMON_UNLOCK(ha); 8087 (void) ql_handle_rscn_update(vha); 8088 TASK_DAEMON_LOCK(ha); 8089 loop_again = TRUE; 8090 } 8091 } 8092 8093 /* Handle state changes. */ 8094 for (vha = ha; vha != NULL; vha = vha->vp_next) { 8095 if (vha->task_daemon_flags & FC_STATE_CHANGE && 8096 !(ha->task_daemon_flags & 8097 TASK_DAEMON_POWERING_DOWN)) { 8098 /* Report state change. */ 8099 EL(vha, "state change = %xh\n", vha->state); 8100 vha->task_daemon_flags &= ~FC_STATE_CHANGE; 8101 8102 if (vha->task_daemon_flags & 8103 COMMAND_WAIT_NEEDED) { 8104 vha->task_daemon_flags &= 8105 ~COMMAND_WAIT_NEEDED; 8106 if (!(ha->task_daemon_flags & 8107 COMMAND_WAIT_ACTIVE)) { 8108 ha->task_daemon_flags |= 8109 COMMAND_WAIT_ACTIVE; 8110 TASK_DAEMON_UNLOCK(ha); 8111 ql_cmd_wait(ha); 8112 TASK_DAEMON_LOCK(ha); 8113 ha->task_daemon_flags &= 8114 ~COMMAND_WAIT_ACTIVE; 8115 } 8116 } 8117 8118 msg = NULL; 8119 if (FC_PORT_STATE_MASK(vha->state) == 8120 FC_STATE_OFFLINE) { 8121 if (vha->task_daemon_flags & 8122 STATE_ONLINE) { 8123 if (ha->topology & 8124 QL_LOOP_CONNECTION) { 8125 msg = "Loop OFFLINE"; 8126 } else { 8127 msg = "Link OFFLINE"; 8128 } 8129 } 8130 vha->task_daemon_flags &= 8131 ~STATE_ONLINE; 8132 } else if (FC_PORT_STATE_MASK(vha->state) == 8133 FC_STATE_LOOP) { 8134 if (!(vha->task_daemon_flags & 8135 STATE_ONLINE)) { 8136 msg = "Loop ONLINE"; 8137 } 8138 vha->task_daemon_flags |= STATE_ONLINE; 8139 } else if (FC_PORT_STATE_MASK(vha->state) == 8140 FC_STATE_ONLINE) { 8141 if (!(vha->task_daemon_flags & 8142 STATE_ONLINE)) { 8143 msg = "Link ONLINE"; 8144 } 8145 vha->task_daemon_flags |= STATE_ONLINE; 8146 } else { 8147 msg = "Unknown Link state"; 8148 } 8149 8150 if (msg != NULL) { 8151 cmn_err(CE_NOTE, "!Qlogic %s(%d,%d): " 8152 "%s", QL_NAME, ha->instance, 8153 vha->vp_index, msg); 8154 } 8155 8156 if (vha->flags & FCA_BOUND) { 8157 QL_PRINT_10(CE_CONT, "(%d,%d): statec_" 8158 "cb state=%xh\n", ha->instance, 8159 vha->vp_index, vha->state); 8160 TASK_DAEMON_UNLOCK(ha); 8161 (vha->bind_info.port_statec_cb) 8162 (vha->bind_info.port_handle, 8163 vha->state); 8164 TASK_DAEMON_LOCK(ha); 8165 } 8166 loop_again = TRUE; 8167 } 8168 } 8169 8170 if (ha->task_daemon_flags & LIP_RESET_PENDING && 8171 !(ha->task_daemon_flags & TASK_DAEMON_POWERING_DOWN)) { 8172 EL(ha, "processing LIP reset\n"); 8173 ha->task_daemon_flags &= ~LIP_RESET_PENDING; 8174 TASK_DAEMON_UNLOCK(ha); 8175 for (vha = ha; vha != NULL; vha = vha->vp_next) { 8176 if (vha->flags & FCA_BOUND) { 8177 QL_PRINT_10(CE_CONT, "(%d,%d): statec_" 8178 "cb reset\n", ha->instance, 8179 vha->vp_index); 8180 (vha->bind_info.port_statec_cb) 8181 (vha->bind_info.port_handle, 8182 FC_STATE_TARGET_PORT_RESET); 8183 } 8184 } 8185 TASK_DAEMON_LOCK(ha); 8186 loop_again = TRUE; 8187 } 8188 8189 if (QL_IS_SET(ha->task_daemon_flags, NEED_UNSOLICITED_BUFFERS | 8190 FIRMWARE_UP)) { 8191 /* 8192 * The firmware needs more unsolicited 8193 * buffers. We cannot allocate any new 8194 * buffers unless the ULP module requests 8195 * for new buffers. All we can do here is 8196 * to give received buffers from the pool 8197 * that is already allocated 8198 */ 8199 ha->task_daemon_flags &= ~NEED_UNSOLICITED_BUFFERS; 8200 TASK_DAEMON_UNLOCK(ha); 8201 ql_isp_rcvbuf(ha); 8202 TASK_DAEMON_LOCK(ha); 8203 loop_again = TRUE; 8204 } 8205 8206 if (ha->task_daemon_flags & ISP_ABORT_NEEDED) { 8207 TASK_DAEMON_UNLOCK(ha); 8208 (void) ql_abort_isp(ha); 8209 TASK_DAEMON_LOCK(ha); 8210 loop_again = TRUE; 8211 } 8212 8213 if (!(ha->task_daemon_flags & (LOOP_DOWN | DRIVER_STALL | 8214 COMMAND_WAIT_NEEDED))) { 8215 if (QL_IS_SET(ha->task_daemon_flags, 8216 RESET_MARKER_NEEDED | FIRMWARE_UP)) { 8217 ha->task_daemon_flags &= ~RESET_MARKER_NEEDED; 8218 if (!(ha->task_daemon_flags & RESET_ACTIVE)) { 8219 ha->task_daemon_flags |= RESET_ACTIVE; 8220 TASK_DAEMON_UNLOCK(ha); 8221 for (vha = ha; vha != NULL; 8222 vha = vha->vp_next) { 8223 ql_rst_aen(vha); 8224 } 8225 TASK_DAEMON_LOCK(ha); 8226 ha->task_daemon_flags &= ~RESET_ACTIVE; 8227 loop_again = TRUE; 8228 } 8229 } 8230 8231 if (QL_IS_SET(ha->task_daemon_flags, 8232 LOOP_RESYNC_NEEDED | FIRMWARE_UP)) { 8233 if (!(ha->task_daemon_flags & 8234 LOOP_RESYNC_ACTIVE)) { 8235 ha->task_daemon_flags |= 8236 LOOP_RESYNC_ACTIVE; 8237 TASK_DAEMON_UNLOCK(ha); 8238 (void) ql_loop_resync(ha); 8239 TASK_DAEMON_LOCK(ha); 8240 loop_again = TRUE; 8241 } 8242 } 8243 } 8244 8245 /* Port retry needed. */ 8246 if (ha->task_daemon_flags & PORT_RETRY_NEEDED) { 8247 ha->task_daemon_flags &= ~PORT_RETRY_NEEDED; 8248 ADAPTER_STATE_LOCK(ha); 8249 ha->port_retry_timer = 0; 8250 ADAPTER_STATE_UNLOCK(ha); 8251 8252 TASK_DAEMON_UNLOCK(ha); 8253 ql_restart_queues(ha); 8254 TASK_DAEMON_LOCK(ha); 8255 loop_again = B_TRUE; 8256 } 8257 8258 /* iiDMA setting needed? */ 8259 if (ha->task_daemon_flags & TD_IIDMA_NEEDED) { 8260 ha->task_daemon_flags &= ~TD_IIDMA_NEEDED; 8261 8262 TASK_DAEMON_UNLOCK(ha); 8263 ql_iidma(ha); 8264 TASK_DAEMON_LOCK(ha); 8265 loop_again = B_TRUE; 8266 } 8267 8268 if (ha->task_daemon_flags & SEND_PLOGI) { 8269 ha->task_daemon_flags &= ~SEND_PLOGI; 8270 TASK_DAEMON_UNLOCK(ha); 8271 ql_n_port_plogi(ha); 8272 TASK_DAEMON_LOCK(ha); 8273 } 8274 8275 head = &ha->callback_queue; 8276 if (head->first != NULL) { 8277 sp = head->first->base_address; 8278 link = &sp->cmd; 8279 8280 /* Dequeue command. */ 8281 ql_remove_link(head, link); 8282 8283 /* Release task daemon lock. */ 8284 TASK_DAEMON_UNLOCK(ha); 8285 8286 /* Do callback. */ 8287 if (sp->flags & SRB_UB_CALLBACK) { 8288 ql_unsol_callback(sp); 8289 } else { 8290 (*sp->pkt->pkt_comp)(sp->pkt); 8291 } 8292 8293 /* Acquire task daemon lock. */ 8294 TASK_DAEMON_LOCK(ha); 8295 8296 loop_again = TRUE; 8297 } 8298 8299 } while (loop_again); 8300} 8301 8302/* 8303 * ql_idle_check 8304 * Test for adapter is alive and well. 8305 * 8306 * Input: 8307 * ha: adapter state pointer. 8308 * 8309 * Context: 8310 * Kernel context. 8311 */ 8312static void 8313ql_idle_check(ql_adapter_state_t *ha) 8314{ 8315 ddi_devstate_t state; 8316 int rval; 8317 ql_mbx_data_t mr; 8318 8319 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance); 8320 8321 /* Firmware Ready Test. */ 8322 rval = ql_get_firmware_state(ha, &mr); 8323 if (!(ha->task_daemon_flags & QL_SUSPENDED) && 8324 (rval != QL_SUCCESS || mr.mb[1] != FSTATE_READY)) { 8325 EL(ha, "failed, Firmware Ready Test = %xh\n", rval); 8326 state = ddi_get_devstate(ha->dip); 8327 if (state == DDI_DEVSTATE_UP) { 8328 /*EMPTY*/ 8329 ddi_dev_report_fault(ha->dip, DDI_SERVICE_DEGRADED, 8330 DDI_DEVICE_FAULT, "Firmware Ready Test failed"); 8331 } 8332 TASK_DAEMON_LOCK(ha); 8333 if (!(ha->task_daemon_flags & ABORT_ISP_ACTIVE)) { 8334 EL(ha, "fstate_ready, isp_abort_needed\n"); 8335 ha->task_daemon_flags |= ISP_ABORT_NEEDED; 8336 } 8337 TASK_DAEMON_UNLOCK(ha); 8338 } 8339 8340 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance); 8341} 8342 8343/* 8344 * ql_unsol_callback 8345 * Handle unsolicited buffer callbacks. 8346 * 8347 * Input: 8348 * ha = adapter state pointer. 8349 * sp = srb pointer. 8350 * 8351 * Context: 8352 * Kernel context. 8353 */ 8354static void 8355ql_unsol_callback(ql_srb_t *sp) 8356{ 8357 fc_affected_id_t *af; 8358 fc_unsol_buf_t *ubp; 8359 uchar_t r_ctl; 8360 uchar_t ls_code; 8361 ql_tgt_t *tq; 8362 ql_adapter_state_t *ha = sp->ha, *pha = sp->ha->pha; 8363 8364 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance); 8365 8366 ubp = ha->ub_array[sp->handle]; 8367 r_ctl = ubp->ub_frame.r_ctl; 8368 ls_code = ubp->ub_buffer[0]; 8369 8370 if (sp->lun_queue == NULL) { 8371 tq = NULL; 8372 } else { 8373 tq = sp->lun_queue->target_queue; 8374 } 8375 8376 QL_UB_LOCK(ha); 8377 if (sp->flags & SRB_UB_FREE_REQUESTED || 8378 pha->task_daemon_flags & TASK_DAEMON_POWERING_DOWN) { 8379 sp->flags &= ~(SRB_UB_IN_ISP | SRB_UB_CALLBACK | 8380 SRB_UB_RSCN | SRB_UB_FCP | SRB_UB_ACQUIRED); 8381 sp->flags |= SRB_UB_IN_FCA; 8382 QL_UB_UNLOCK(ha); 8383 return; 8384 } 8385 8386 /* Process RSCN */ 8387 if (sp->flags & SRB_UB_RSCN) { 8388 int sendup = 1; 8389 8390 /* 8391 * Defer RSCN posting until commands return 8392 */ 8393 QL_UB_UNLOCK(ha); 8394 8395 af = (fc_affected_id_t *)((caddr_t)ubp->ub_buffer + 4); 8396 8397 /* Abort outstanding commands */ 8398 sendup = ql_process_rscn(ha, af); 8399 if (sendup == 0) { 8400 8401 TASK_DAEMON_LOCK(ha); 8402 ql_add_link_b(&pha->callback_queue, &sp->cmd); 8403 TASK_DAEMON_UNLOCK(ha); 8404 8405 /* 8406 * Wait for commands to drain in F/W (doesn't take 8407 * more than a few milliseconds) 8408 */ 8409 ql_delay(ha, 10000); 8410 8411 QL_PRINT_2(CE_CONT, "(%d,%d): done rscn_sendup=0, " 8412 "fmt=%xh, d_id=%xh\n", ha->instance, ha->vp_index, 8413 af->aff_format, af->aff_d_id); 8414 return; 8415 } 8416 8417 QL_UB_LOCK(ha); 8418 8419 EL(ha, "sending unsol rscn, fmt=%xh, d_id=%xh to transport\n", 8420 af->aff_format, af->aff_d_id); 8421 } 8422 8423 /* Process UNSOL LOGO */ 8424 if ((r_ctl == R_CTL_ELS_REQ) && (ls_code == LA_ELS_LOGO)) { 8425 QL_UB_UNLOCK(ha); 8426 8427 if (tq && (ql_process_logo_for_device(ha, tq) == 0)) { 8428 TASK_DAEMON_LOCK(ha); 8429 ql_add_link_b(&pha->callback_queue, &sp->cmd); 8430 TASK_DAEMON_UNLOCK(ha); 8431 QL_PRINT_2(CE_CONT, "(%d,%d): logo_sendup=0, d_id=%xh" 8432 "\n", ha->instance, ha->vp_index, tq->d_id.b24); 8433 return; 8434 } 8435 8436 QL_UB_LOCK(ha); 8437 EL(ha, "sending unsol logout for %xh to transport\n", 8438 ubp->ub_frame.s_id); 8439 } 8440 8441 sp->flags &= ~(SRB_UB_IN_FCA | SRB_UB_IN_ISP | SRB_UB_RSCN | 8442 SRB_UB_FCP); 8443 8444 if (sp->ub_type == FC_TYPE_IS8802_SNAP) { 8445 (void) ddi_dma_sync(sp->ub_buffer.dma_handle, 0, 8446 ubp->ub_bufsize, DDI_DMA_SYNC_FORCPU); 8447 } 8448 QL_UB_UNLOCK(ha); 8449 8450 (ha->bind_info.port_unsol_cb)(ha->bind_info.port_handle, 8451 ubp, sp->ub_type); 8452 8453 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance); 8454} 8455 8456/* 8457 * ql_send_logo 8458 * 8459 * Input: 8460 * ha: adapter state pointer. 8461 * tq: target queue pointer. 8462 * done_q: done queue pointer. 8463 * 8464 * Context: 8465 * Interrupt or Kernel context, no mailbox commands allowed. 8466 */ 8467void 8468ql_send_logo(ql_adapter_state_t *vha, ql_tgt_t *tq, ql_head_t *done_q) 8469{ 8470 fc_unsol_buf_t *ubp; 8471 ql_srb_t *sp; 8472 la_els_logo_t *payload; 8473 ql_adapter_state_t *ha = vha->pha; 8474 8475 QL_PRINT_3(CE_CONT, "(%d): started, d_id=%xh\n", ha->instance, 8476 tq->d_id.b24); 8477 8478 if ((tq->d_id.b24 == 0) || (tq->d_id.b24 == 0xffffff)) { 8479 EL(ha, "no device, d_id=%xh\n", tq->d_id.b24); 8480 return; 8481 } 8482 8483 if ((tq->flags & (TQF_RSCN_RCVD | TQF_PLOGI_PROGRS)) == 0 && 8484 tq->logout_sent == 0 && (ha->task_daemon_flags & LOOP_DOWN) == 0) { 8485 8486 /* Locate a buffer to use. */ 8487 ubp = ql_get_unsolicited_buffer(vha, FC_TYPE_EXTENDED_LS); 8488 if (ubp == NULL) { 8489 EL(vha, "Failed, get_unsolicited_buffer\n"); 8490 return; 8491 } 8492 8493 DEVICE_QUEUE_LOCK(tq); 8494 tq->flags |= TQF_NEED_AUTHENTICATION; 8495 tq->logout_sent++; 8496 DEVICE_QUEUE_UNLOCK(tq); 8497 8498 EL(vha, "Received LOGO from = %xh\n", tq->d_id.b24); 8499 8500 sp = ubp->ub_fca_private; 8501 8502 /* Set header. */ 8503 ubp->ub_frame.d_id = vha->d_id.b24; 8504 ubp->ub_frame.r_ctl = R_CTL_ELS_REQ; 8505 ubp->ub_frame.s_id = tq->d_id.b24; 8506 ubp->ub_frame.rsvd = 0; 8507 ubp->ub_frame.f_ctl = F_CTL_FIRST_SEQ | F_CTL_END_SEQ | 8508 F_CTL_SEQ_INITIATIVE; 8509 ubp->ub_frame.type = FC_TYPE_EXTENDED_LS; 8510 ubp->ub_frame.seq_cnt = 0; 8511 ubp->ub_frame.df_ctl = 0; 8512 ubp->ub_frame.seq_id = 0; 8513 ubp->ub_frame.rx_id = 0xffff; 8514 ubp->ub_frame.ox_id = 0xffff; 8515 8516 /* set payload. */ 8517 payload = (la_els_logo_t *)ubp->ub_buffer; 8518 bzero(payload, sizeof (la_els_logo_t)); 8519 /* Make sure ls_code in payload is always big endian */ 8520 ubp->ub_buffer[0] = LA_ELS_LOGO; 8521 ubp->ub_buffer[1] = 0; 8522 ubp->ub_buffer[2] = 0; 8523 ubp->ub_buffer[3] = 0; 8524 bcopy(&vha->loginparams.node_ww_name.raw_wwn[0], 8525 &payload->nport_ww_name.raw_wwn[0], 8); 8526 payload->nport_id.port_id = tq->d_id.b24; 8527 8528 QL_UB_LOCK(ha); 8529 sp->flags |= SRB_UB_CALLBACK; 8530 QL_UB_UNLOCK(ha); 8531 if (tq->lun_queues.first != NULL) { 8532 sp->lun_queue = (tq->lun_queues.first)->base_address; 8533 } else { 8534 sp->lun_queue = ql_lun_queue(vha, tq, 0); 8535 } 8536 if (done_q) { 8537 ql_add_link_b(done_q, &sp->cmd); 8538 } else { 8539 ql_awaken_task_daemon(ha, sp, 0, 0); 8540 } 8541 } 8542 8543 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance); 8544} 8545 8546static int 8547ql_process_logo_for_device(ql_adapter_state_t *ha, ql_tgt_t *tq) 8548{ 8549 port_id_t d_id; 8550 ql_srb_t *sp; 8551 ql_link_t *link; 8552 int sendup = 1; 8553 8554 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance); 8555 8556 DEVICE_QUEUE_LOCK(tq); 8557 if (tq->outcnt) { 8558 DEVICE_QUEUE_UNLOCK(tq); 8559 sendup = 0; 8560 (void) ql_abort_device(ha, tq, 1); 8561 ql_delay(ha, 10000); 8562 } else { 8563 DEVICE_QUEUE_UNLOCK(tq); 8564 TASK_DAEMON_LOCK(ha); 8565 8566 for (link = ha->pha->callback_queue.first; link != NULL; 8567 link = link->next) { 8568 sp = link->base_address; 8569 if (sp->flags & SRB_UB_CALLBACK) { 8570 continue; 8571 } 8572 d_id.b24 = sp->pkt->pkt_cmd_fhdr.d_id; 8573 8574 if (tq->d_id.b24 == d_id.b24) { 8575 sendup = 0; 8576 break; 8577 } 8578 } 8579 8580 TASK_DAEMON_UNLOCK(ha); 8581 } 8582 8583 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance); 8584 8585 return (sendup); 8586} 8587 8588static int 8589ql_send_plogi(ql_adapter_state_t *ha, ql_tgt_t *tq, ql_head_t *done_q) 8590{ 8591 fc_unsol_buf_t *ubp; 8592 ql_srb_t *sp; 8593 la_els_logi_t *payload; 8594 class_svc_param_t *class3_param; 8595 8596 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance); 8597 8598 if ((tq->flags & TQF_RSCN_RCVD) || (ha->task_daemon_flags & 8599 LOOP_DOWN)) { 8600 EL(ha, "Failed, tqf=%xh\n", tq->flags); 8601 return (QL_FUNCTION_FAILED); 8602 } 8603 8604 /* Locate a buffer to use. */ 8605 ubp = ql_get_unsolicited_buffer(ha, FC_TYPE_EXTENDED_LS); 8606 if (ubp == NULL) { 8607 EL(ha, "Failed\n"); 8608 return (QL_FUNCTION_FAILED); 8609 } 8610 8611 QL_PRINT_3(CE_CONT, "(%d): Received LOGO from = %xh\n", 8612 ha->instance, tq->d_id.b24); 8613 8614 EL(ha, "Emulate PLOGI from = %xh tq = %x\n", tq->d_id.b24, tq); 8615 8616 sp = ubp->ub_fca_private; 8617 8618 /* Set header. */ 8619 ubp->ub_frame.d_id = ha->d_id.b24; 8620 ubp->ub_frame.r_ctl = R_CTL_ELS_REQ; 8621 ubp->ub_frame.s_id = tq->d_id.b24; 8622 ubp->ub_frame.rsvd = 0; 8623 ubp->ub_frame.f_ctl = F_CTL_FIRST_SEQ | F_CTL_END_SEQ | 8624 F_CTL_SEQ_INITIATIVE; 8625 ubp->ub_frame.type = FC_TYPE_EXTENDED_LS; 8626 ubp->ub_frame.seq_cnt = 0; 8627 ubp->ub_frame.df_ctl = 0; 8628 ubp->ub_frame.seq_id = 0; 8629 ubp->ub_frame.rx_id = 0xffff; 8630 ubp->ub_frame.ox_id = 0xffff; 8631 8632 /* set payload. */ 8633 payload = (la_els_logi_t *)ubp->ub_buffer; 8634 bzero(payload, sizeof (payload)); 8635 8636 payload->ls_code.ls_code = LA_ELS_PLOGI; 8637 payload->common_service.fcph_version = 0x2006; 8638 payload->common_service.cmn_features = 0x8800; 8639 8640 CFG_IST(ha, CFG_CTRL_242581) ? 8641 (payload->common_service.rx_bufsize = CHAR_TO_SHORT( 8642 ha->init_ctrl_blk.cb24.max_frame_length[0], 8643 ha->init_ctrl_blk.cb24.max_frame_length[1])) : 8644 (payload->common_service.rx_bufsize = CHAR_TO_SHORT( 8645 ha->init_ctrl_blk.cb.max_frame_length[0], 8646 ha->init_ctrl_blk.cb.max_frame_length[1])); 8647 8648 payload->common_service.conc_sequences = 0xff; 8649 payload->common_service.relative_offset = 0x03; 8650 payload->common_service.e_d_tov = 0x7d0; 8651 8652 bcopy((void *)&tq->port_name[0], 8653 (void *)&payload->nport_ww_name.raw_wwn[0], 8); 8654 8655 bcopy((void *)&tq->node_name[0], 8656 (void *)&payload->node_ww_name.raw_wwn[0], 8); 8657 8658 class3_param = (class_svc_param_t *)&payload->class_3; 8659 class3_param->class_valid_svc_opt = 0x8000; 8660 class3_param->recipient_ctl = tq->class3_recipient_ctl; 8661 class3_param->rcv_data_size = tq->class3_rcv_data_size; 8662 class3_param->conc_sequences = tq->class3_conc_sequences; 8663 class3_param->open_sequences_per_exch = 8664 tq->class3_open_sequences_per_exch; 8665 8666 QL_UB_LOCK(ha); 8667 sp->flags |= SRB_UB_CALLBACK; 8668 QL_UB_UNLOCK(ha); 8669 8670 ql_isp_els_handle_endian(ha, (uint8_t *)payload, LA_ELS_PLOGI); 8671 8672 if (done_q) { 8673 ql_add_link_b(done_q, &sp->cmd); 8674 } else { 8675 ql_awaken_task_daemon(ha, sp, 0, 0); 8676 } 8677 8678 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance); 8679 8680 return (QL_SUCCESS); 8681} 8682 8683/* 8684 * Abort outstanding commands in the Firmware, clear internally 8685 * queued commands in the driver, Synchronize the target with 8686 * the Firmware 8687 */ 8688int 8689ql_abort_device(ql_adapter_state_t *ha, ql_tgt_t *tq, int drain) 8690{ 8691 ql_link_t *link, *link2; 8692 ql_lun_t *lq; 8693 int rval = QL_SUCCESS; 8694 ql_srb_t *sp; 8695 ql_head_t done_q = { NULL, NULL }; 8696 8697 QL_PRINT_10(CE_CONT, "(%d,%d): started\n", ha->instance, ha->vp_index); 8698 8699 /* 8700 * First clear, internally queued commands 8701 */ 8702 DEVICE_QUEUE_LOCK(tq); 8703 for (link = tq->lun_queues.first; link != NULL; link = link->next) { 8704 lq = link->base_address; 8705 8706 link2 = lq->cmd.first; 8707 while (link2 != NULL) { 8708 sp = link2->base_address; 8709 link2 = link2->next; 8710 8711 if (sp->flags & SRB_ABORT) { 8712 continue; 8713 } 8714 8715 /* Remove srb from device command queue. */ 8716 ql_remove_link(&lq->cmd, &sp->cmd); 8717 sp->flags &= ~SRB_IN_DEVICE_QUEUE; 8718 8719 /* Set ending status. */ 8720 sp->pkt->pkt_reason = CS_ABORTED; 8721 8722 /* Call done routine to handle completions. */ 8723 ql_add_link_b(&done_q, &sp->cmd); 8724 } 8725 } 8726 DEVICE_QUEUE_UNLOCK(tq); 8727 8728 if (done_q.first != NULL) { 8729 ql_done(done_q.first); 8730 } 8731 8732 if (drain && VALID_TARGET_ID(ha, tq->loop_id) && PD_PORT_LOGIN(tq)) { 8733 rval = ql_abort_target(ha, tq, 0); 8734 } 8735 8736 if (rval != QL_SUCCESS) { 8737 EL(ha, "failed=%xh, d_id=%xh\n", rval, tq->d_id.b24); 8738 } else { 8739 /*EMPTY*/ 8740 QL_PRINT_10(CE_CONT, "(%d,%d): done\n", ha->instance, 8741 ha->vp_index); 8742 } 8743 8744 return (rval); 8745} 8746 8747/* 8748 * ql_rcv_rscn_els 8749 * Processes received RSCN extended link service. 8750 * 8751 * Input: 8752 * ha: adapter state pointer. 8753 * mb: array containing input mailbox registers. 8754 * done_q: done queue pointer. 8755 * 8756 * Context: 8757 * Interrupt or Kernel context, no mailbox commands allowed. 8758 */ 8759void 8760ql_rcv_rscn_els(ql_adapter_state_t *ha, uint16_t *mb, ql_head_t *done_q) 8761{ 8762 fc_unsol_buf_t *ubp; 8763 ql_srb_t *sp; 8764 fc_rscn_t *rn; 8765 fc_affected_id_t *af; 8766 port_id_t d_id; 8767 8768 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance); 8769 8770 /* Locate a buffer to use. */ 8771 ubp = ql_get_unsolicited_buffer(ha, FC_TYPE_EXTENDED_LS); 8772 if (ubp != NULL) { 8773 sp = ubp->ub_fca_private; 8774 8775 /* Set header. */ 8776 ubp->ub_frame.d_id = ha->d_id.b24; 8777 ubp->ub_frame.r_ctl = R_CTL_ELS_REQ; 8778 ubp->ub_frame.s_id = FS_FABRIC_CONTROLLER; 8779 ubp->ub_frame.rsvd = 0; 8780 ubp->ub_frame.f_ctl = F_CTL_FIRST_SEQ | F_CTL_END_SEQ | 8781 F_CTL_SEQ_INITIATIVE; 8782 ubp->ub_frame.type = FC_TYPE_EXTENDED_LS; 8783 ubp->ub_frame.seq_cnt = 0; 8784 ubp->ub_frame.df_ctl = 0; 8785 ubp->ub_frame.seq_id = 0; 8786 ubp->ub_frame.rx_id = 0xffff; 8787 ubp->ub_frame.ox_id = 0xffff; 8788 8789 /* set payload. */ 8790 rn = (fc_rscn_t *)ubp->ub_buffer; 8791 af = (fc_affected_id_t *)((caddr_t)ubp->ub_buffer + 4); 8792 8793 rn->rscn_code = LA_ELS_RSCN; 8794 rn->rscn_len = 4; 8795 rn->rscn_payload_len = 8; 8796 d_id.b.al_pa = LSB(mb[2]); 8797 d_id.b.area = MSB(mb[2]); 8798 d_id.b.domain = LSB(mb[1]); 8799 af->aff_d_id = d_id.b24; 8800 af->aff_format = MSB(mb[1]); 8801 8802 EL(ha, "LA_ELS_RSCN fmt=%xh, d_id=%xh\n", af->aff_format, 8803 af->aff_d_id); 8804 8805 ql_update_rscn(ha, af); 8806 8807 QL_UB_LOCK(ha); 8808 sp->flags |= SRB_UB_CALLBACK | SRB_UB_RSCN; 8809 QL_UB_UNLOCK(ha); 8810 ql_add_link_b(done_q, &sp->cmd); 8811 } 8812 8813 if (ubp == NULL) { 8814 EL(ha, "Failed, get_unsolicited_buffer\n"); 8815 } else { 8816 /*EMPTY*/ 8817 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance); 8818 } 8819} 8820 8821/* 8822 * ql_update_rscn 8823 * Update devices from received RSCN. 8824 * 8825 * Input: 8826 * ha: adapter state pointer. 8827 * af: pointer to RSCN data. 8828 * 8829 * Context: 8830 * Interrupt or Kernel context, no mailbox commands allowed. 8831 */ 8832static void 8833ql_update_rscn(ql_adapter_state_t *ha, fc_affected_id_t *af) 8834{ 8835 ql_link_t *link; 8836 uint16_t index; 8837 ql_tgt_t *tq; 8838 8839 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance); 8840 8841 if (af->aff_format == FC_RSCN_PORT_ADDRESS) { 8842 port_id_t d_id; 8843 8844 d_id.r.rsvd_1 = 0; 8845 d_id.b24 = af->aff_d_id; 8846 8847 tq = ql_d_id_to_queue(ha, d_id); 8848 if (tq) { 8849 EL(ha, "SD_RSCN_RCVD %xh RPA\n", d_id.b24); 8850 DEVICE_QUEUE_LOCK(tq); 8851 tq->flags |= TQF_RSCN_RCVD; 8852 DEVICE_QUEUE_UNLOCK(tq); 8853 } 8854 QL_PRINT_3(CE_CONT, "(%d): FC_RSCN_PORT_ADDRESS done\n", 8855 ha->instance); 8856 8857 return; 8858 } 8859 8860 for (index = 0; index < DEVICE_HEAD_LIST_SIZE; index++) { 8861 for (link = ha->dev[index].first; link != NULL; 8862 link = link->next) { 8863 tq = link->base_address; 8864 8865 switch (af->aff_format) { 8866 case FC_RSCN_FABRIC_ADDRESS: 8867 if (!RESERVED_LOOP_ID(ha, tq->loop_id)) { 8868 EL(ha, "SD_RSCN_RCVD %xh RFA\n", 8869 tq->d_id.b24); 8870 DEVICE_QUEUE_LOCK(tq); 8871 tq->flags |= TQF_RSCN_RCVD; 8872 DEVICE_QUEUE_UNLOCK(tq); 8873 } 8874 break; 8875 8876 case FC_RSCN_AREA_ADDRESS: 8877 if ((tq->d_id.b24 & 0xffff00) == af->aff_d_id) { 8878 EL(ha, "SD_RSCN_RCVD %xh RAA\n", 8879 tq->d_id.b24); 8880 DEVICE_QUEUE_LOCK(tq); 8881 tq->flags |= TQF_RSCN_RCVD; 8882 DEVICE_QUEUE_UNLOCK(tq); 8883 } 8884 break; 8885 8886 case FC_RSCN_DOMAIN_ADDRESS: 8887 if ((tq->d_id.b24 & 0xff0000) == af->aff_d_id) { 8888 EL(ha, "SD_RSCN_RCVD %xh RDA\n", 8889 tq->d_id.b24); 8890 DEVICE_QUEUE_LOCK(tq); 8891 tq->flags |= TQF_RSCN_RCVD; 8892 DEVICE_QUEUE_UNLOCK(tq); 8893 } 8894 break; 8895 8896 default: 8897 break; 8898 } 8899 } 8900 } 8901 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance); 8902} 8903 8904/* 8905 * ql_process_rscn 8906 * 8907 * Input: 8908 * ha: adapter state pointer. 8909 * af: RSCN payload pointer. 8910 * 8911 * Context: 8912 * Kernel context. 8913 */ 8914static int 8915ql_process_rscn(ql_adapter_state_t *ha, fc_affected_id_t *af) 8916{ 8917 int sendit; 8918 int sendup = 1; 8919 ql_link_t *link; 8920 uint16_t index; 8921 ql_tgt_t *tq; 8922 8923 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance); 8924 8925 if (af->aff_format == FC_RSCN_PORT_ADDRESS) { 8926 port_id_t d_id; 8927 8928 d_id.r.rsvd_1 = 0; 8929 d_id.b24 = af->aff_d_id; 8930 8931 tq = ql_d_id_to_queue(ha, d_id); 8932 if (tq) { 8933 sendup = ql_process_rscn_for_device(ha, tq); 8934 } 8935 8936 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance); 8937 8938 return (sendup); 8939 } 8940 8941 for (index = 0; index < DEVICE_HEAD_LIST_SIZE; index++) { 8942 for (link = ha->dev[index].first; link != NULL; 8943 link = link->next) { 8944 8945 tq = link->base_address; 8946 if (tq == NULL) { 8947 continue; 8948 } 8949 8950 switch (af->aff_format) { 8951 case FC_RSCN_FABRIC_ADDRESS: 8952 if (!RESERVED_LOOP_ID(ha, tq->loop_id)) { 8953 sendit = ql_process_rscn_for_device( 8954 ha, tq); 8955 if (sendup) { 8956 sendup = sendit; 8957 } 8958 } 8959 break; 8960 8961 case FC_RSCN_AREA_ADDRESS: 8962 if ((tq->d_id.b24 & 0xffff00) == 8963 af->aff_d_id) { 8964 sendit = ql_process_rscn_for_device( 8965 ha, tq); 8966 8967 if (sendup) { 8968 sendup = sendit; 8969 } 8970 } 8971 break; 8972 8973 case FC_RSCN_DOMAIN_ADDRESS: 8974 if ((tq->d_id.b24 & 0xff0000) == 8975 af->aff_d_id) { 8976 sendit = ql_process_rscn_for_device( 8977 ha, tq); 8978 8979 if (sendup) { 8980 sendup = sendit; 8981 } 8982 } 8983 break; 8984 8985 default: 8986 break; 8987 } 8988 } 8989 } 8990 8991 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance); 8992 8993 return (sendup); 8994} 8995 8996/* 8997 * ql_process_rscn_for_device 8998 * 8999 * Input: 9000 * ha: adapter state pointer. 9001 * tq: target queue pointer. 9002 * 9003 * Context: 9004 * Kernel context. 9005 */ 9006static int 9007ql_process_rscn_for_device(ql_adapter_state_t *ha, ql_tgt_t *tq) 9008{ 9009 int sendup = 1; 9010 9011 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance); 9012 9013 DEVICE_QUEUE_LOCK(tq); 9014 9015 /* 9016 * Let FCP-2 compliant devices continue I/Os 9017 * with their low level recoveries. 9018 */ 9019 if (((tq->flags & TQF_INITIATOR_DEVICE) == 0) && 9020 (tq->prli_svc_param_word_3 & PRLI_W3_RETRY)) { 9021 /* 9022 * Cause ADISC to go out 9023 */ 9024 DEVICE_QUEUE_UNLOCK(tq); 9025 9026 (void) ql_get_port_database(ha, tq, PDF_NONE); 9027 9028 DEVICE_QUEUE_LOCK(tq); 9029 tq->flags &= ~TQF_RSCN_RCVD; 9030 9031 } else if (tq->loop_id != PORT_NO_LOOP_ID) { 9032 if (tq->d_id.b24 != BROADCAST_ADDR) { 9033 tq->flags |= TQF_NEED_AUTHENTICATION; 9034 } 9035 9036 DEVICE_QUEUE_UNLOCK(tq); 9037 9038 (void) ql_abort_device(ha, tq, 1); 9039 9040 DEVICE_QUEUE_LOCK(tq); 9041 9042 if (tq->outcnt) { 9043 sendup = 0; 9044 } else { 9045 tq->flags &= ~TQF_RSCN_RCVD; 9046 } 9047 } else { 9048 tq->flags &= ~TQF_RSCN_RCVD; 9049 } 9050 9051 if (sendup) { 9052 if (tq->d_id.b24 != BROADCAST_ADDR) { 9053 tq->flags |= TQF_NEED_AUTHENTICATION; 9054 } 9055 } 9056 9057 DEVICE_QUEUE_UNLOCK(tq); 9058 9059 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance); 9060 9061 return (sendup); 9062} 9063 9064static int 9065ql_handle_rscn_update(ql_adapter_state_t *ha) 9066{ 9067 int rval; 9068 ql_tgt_t *tq; 9069 uint16_t index, loop_id; 9070 ql_dev_id_list_t *list; 9071 uint32_t list_size; 9072 port_id_t d_id; 9073 ql_mbx_data_t mr; 9074 ql_head_t done_q = { NULL, NULL }; 9075 9076 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance); 9077 9078 list_size = sizeof (ql_dev_id_list_t) * DEVICE_LIST_ENTRIES; 9079 list = kmem_zalloc(list_size, KM_SLEEP); 9080 if (list == NULL) { 9081 rval = QL_MEMORY_ALLOC_FAILED; 9082 EL(ha, "kmem_zalloc failed=%xh\n", rval); 9083 return (rval); 9084 } 9085 9086 /* 9087 * Get data from RISC code d_id list to init each device queue. 9088 */ 9089 rval = ql_get_id_list(ha, (caddr_t)list, list_size, &mr); 9090 if (rval != QL_SUCCESS) { 9091 kmem_free(list, list_size); 9092 EL(ha, "get_id_list failed=%xh\n", rval); 9093 return (rval); 9094 } 9095 9096 /* Acquire adapter state lock. */ 9097 ADAPTER_STATE_LOCK(ha); 9098 9099 /* Check for new devices */ 9100 for (index = 0; index < mr.mb[1]; index++) { 9101 ql_dev_list(ha, list, index, &d_id, &loop_id); 9102 9103 if (VALID_DEVICE_ID(ha, loop_id)) { 9104 d_id.r.rsvd_1 = 0; 9105 9106 tq = ql_d_id_to_queue(ha, d_id); 9107 if (tq != NULL) { 9108 continue; 9109 } 9110 9111 tq = ql_dev_init(ha, d_id, loop_id); 9112 9113 /* Test for fabric device. */ 9114 if (d_id.b.domain != ha->d_id.b.domain || 9115 d_id.b.area != ha->d_id.b.area) { 9116 tq->flags |= TQF_FABRIC_DEVICE; 9117 } 9118 9119 ADAPTER_STATE_UNLOCK(ha); 9120 if (ql_get_port_database(ha, tq, PDF_NONE) != 9121 QL_SUCCESS) { 9122 tq->loop_id = PORT_NO_LOOP_ID; 9123 } 9124 ADAPTER_STATE_LOCK(ha); 9125 9126 /* 9127 * Send up a PLOGI about the new device 9128 */ 9129 if (VALID_DEVICE_ID(ha, tq->loop_id)) { 9130 (void) ql_send_plogi(ha, tq, &done_q); 9131 } 9132 } 9133 } 9134 9135 /* Release adapter state lock. */ 9136 ADAPTER_STATE_UNLOCK(ha); 9137 9138 if (done_q.first != NULL) { 9139 ql_done(done_q.first); 9140 } 9141 9142 kmem_free(list, list_size); 9143 9144 if (rval != QL_SUCCESS) { 9145 EL(ha, "failed=%xh\n", rval); 9146 } else { 9147 /*EMPTY*/ 9148 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance); 9149 } 9150 9151 return (rval); 9152} 9153 9154/* 9155 * ql_free_unsolicited_buffer 9156 * Frees allocated buffer. 9157 * 9158 * Input: 9159 * ha = adapter state pointer. 9160 * index = buffer array index. 9161 * ADAPTER_STATE_LOCK must be already obtained. 9162 * 9163 * Context: 9164 * Kernel context. 9165 */ 9166static void 9167ql_free_unsolicited_buffer(ql_adapter_state_t *ha, fc_unsol_buf_t *ubp) 9168{ 9169 ql_srb_t *sp; 9170 int status; 9171 9172 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance); 9173 9174 sp = ubp->ub_fca_private; 9175 if (sp->ub_type == FC_TYPE_IS8802_SNAP) { 9176 /* Disconnect IP from system buffers. */ 9177 if (ha->flags & IP_INITIALIZED) { 9178 ADAPTER_STATE_UNLOCK(ha); 9179 status = ql_shutdown_ip(ha); 9180 ADAPTER_STATE_LOCK(ha); 9181 if (status != QL_SUCCESS) { 9182 cmn_err(CE_WARN, 9183 "!Qlogic %s(%d): Failed to shutdown IP", 9184 QL_NAME, ha->instance); 9185 return; 9186 } 9187 9188 ha->flags &= ~IP_ENABLED; 9189 } 9190 9191 ql_free_phys(ha, &sp->ub_buffer); 9192 } else { 9193 kmem_free(ubp->ub_buffer, ubp->ub_bufsize); 9194 } 9195 9196 kmem_free(sp, sizeof (ql_srb_t)); 9197 kmem_free(ubp, sizeof (fc_unsol_buf_t)); 9198 9199 if (ha->ub_allocated != 0) { 9200 ha->ub_allocated--; 9201 } 9202 9203 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance); 9204} 9205 9206/* 9207 * ql_get_unsolicited_buffer 9208 * Locates a free unsolicited buffer. 9209 * 9210 * Input: 9211 * ha = adapter state pointer. 9212 * type = buffer type. 9213 * 9214 * Returns: 9215 * Unsolicited buffer pointer. 9216 * 9217 * Context: 9218 * Interrupt or Kernel context, no mailbox commands allowed. 9219 */ 9220fc_unsol_buf_t * 9221ql_get_unsolicited_buffer(ql_adapter_state_t *ha, uint32_t type) 9222{ 9223 fc_unsol_buf_t *ubp; 9224 ql_srb_t *sp; 9225 uint16_t index; 9226 9227 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance); 9228 9229 /* Locate a buffer to use. */ 9230 ubp = NULL; 9231 9232 QL_UB_LOCK(ha); 9233 for (index = 0; index < QL_UB_LIMIT; index++) { 9234 ubp = ha->ub_array[index]; 9235 if (ubp != NULL) { 9236 sp = ubp->ub_fca_private; 9237 if ((sp->ub_type == type) && 9238 (sp->flags & SRB_UB_IN_FCA) && 9239 (!(sp->flags & (SRB_UB_CALLBACK | 9240 SRB_UB_FREE_REQUESTED | SRB_UB_ACQUIRED)))) { 9241 sp->flags |= SRB_UB_ACQUIRED; 9242 ubp->ub_resp_flags = 0; 9243 break; 9244 } 9245 ubp = NULL; 9246 } 9247 } 9248 QL_UB_UNLOCK(ha); 9249 9250 if (ubp) { 9251 ubp->ub_resp_token = NULL; 9252 ubp->ub_class = FC_TRAN_CLASS3; 9253 } 9254 9255 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance); 9256 9257 return (ubp); 9258} 9259 9260/* 9261 * ql_ub_frame_hdr 9262 * Processes received unsolicited buffers from ISP. 9263 * 9264 * Input: 9265 * ha: adapter state pointer. 9266 * tq: target queue pointer. 9267 * index: unsolicited buffer array index. 9268 * done_q: done queue pointer. 9269 * 9270 * Returns: 9271 * ql local function return status code. 9272 * 9273 * Context: 9274 * Interrupt or Kernel context, no mailbox commands allowed. 9275 */ 9276int 9277ql_ub_frame_hdr(ql_adapter_state_t *ha, ql_tgt_t *tq, uint16_t index, 9278 ql_head_t *done_q) 9279{ 9280 fc_unsol_buf_t *ubp; 9281 ql_srb_t *sp; 9282 uint16_t loop_id; 9283 int rval = QL_FUNCTION_FAILED; 9284 9285 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance); 9286 9287 QL_UB_LOCK(ha); 9288 if (index >= QL_UB_LIMIT || (ubp = ha->ub_array[index]) == NULL) { 9289 EL(ha, "Invalid buffer index=%xh\n", index); 9290 QL_UB_UNLOCK(ha); 9291 return (rval); 9292 } 9293 9294 sp = ubp->ub_fca_private; 9295 if (sp->flags & SRB_UB_FREE_REQUESTED) { 9296 EL(ha, "buffer freed index=%xh\n", index); 9297 sp->flags &= ~(SRB_UB_IN_ISP | SRB_UB_CALLBACK | 9298 SRB_UB_RSCN | SRB_UB_FCP | SRB_UB_ACQUIRED); 9299 9300 sp->flags |= SRB_UB_IN_FCA; 9301 9302 QL_UB_UNLOCK(ha); 9303 return (rval); 9304 } 9305 9306 if ((sp->handle == index) && 9307 (sp->flags & SRB_UB_IN_ISP) && 9308 (sp->ub_type == FC_TYPE_IS8802_SNAP) && 9309 (!(sp->flags & SRB_UB_ACQUIRED))) { 9310 /* set broadcast D_ID */ 9311 loop_id = (uint16_t)(CFG_IST(ha, CFG_CTRL_242581) ? 9312 BROADCAST_24XX_HDL : IP_BROADCAST_LOOP_ID); 9313 if (tq->ub_loop_id == loop_id) { 9314 if (ha->topology & QL_FL_PORT) { 9315 ubp->ub_frame.d_id = 0x000000; 9316 } else { 9317 ubp->ub_frame.d_id = 0xffffff; 9318 } 9319 } else { 9320 ubp->ub_frame.d_id = ha->d_id.b24; 9321 } 9322 ubp->ub_frame.r_ctl = R_CTL_UNSOL_DATA; 9323 ubp->ub_frame.rsvd = 0; 9324 ubp->ub_frame.s_id = tq->d_id.b24; 9325 ubp->ub_frame.type = FC_TYPE_IS8802_SNAP; 9326 ubp->ub_frame.seq_cnt = tq->ub_seq_cnt; 9327 ubp->ub_frame.df_ctl = 0; 9328 ubp->ub_frame.seq_id = tq->ub_seq_id; 9329 ubp->ub_frame.rx_id = 0xffff; 9330 ubp->ub_frame.ox_id = 0xffff; 9331 ubp->ub_bufsize = sp->ub_size < tq->ub_sequence_length ? 9332 sp->ub_size : tq->ub_sequence_length; 9333 ubp->ub_frame.ro = tq->ub_frame_ro; 9334 9335 tq->ub_sequence_length = (uint16_t) 9336 (tq->ub_sequence_length - ubp->ub_bufsize); 9337 tq->ub_frame_ro += ubp->ub_bufsize; 9338 tq->ub_seq_cnt++; 9339 9340 if (tq->ub_seq_cnt == tq->ub_total_seg_cnt) { 9341 if (tq->ub_seq_cnt == 1) { 9342 ubp->ub_frame.f_ctl = F_CTL_RO_PRESENT | 9343 F_CTL_FIRST_SEQ | F_CTL_END_SEQ; 9344 } else { 9345 ubp->ub_frame.f_ctl = F_CTL_RO_PRESENT | 9346 F_CTL_END_SEQ; 9347 } 9348 tq->ub_total_seg_cnt = 0; 9349 } else if (tq->ub_seq_cnt == 1) { 9350 ubp->ub_frame.f_ctl = F_CTL_RO_PRESENT | 9351 F_CTL_FIRST_SEQ; 9352 ubp->ub_frame.df_ctl = 0x20; 9353 } 9354 9355 QL_PRINT_3(CE_CONT, "(%d): ub_frame.d_id=%xh\n", 9356 ha->instance, ubp->ub_frame.d_id); 9357 QL_PRINT_3(CE_CONT, "(%d): ub_frame.s_id=%xh\n", 9358 ha->instance, ubp->ub_frame.s_id); 9359 QL_PRINT_3(CE_CONT, "(%d): ub_frame.seq_cnt=%xh\n", 9360 ha->instance, ubp->ub_frame.seq_cnt); 9361 QL_PRINT_3(CE_CONT, "(%d): ub_frame.seq_id=%xh\n", 9362 ha->instance, ubp->ub_frame.seq_id); 9363 QL_PRINT_3(CE_CONT, "(%d): ub_frame.ro=%xh\n", 9364 ha->instance, ubp->ub_frame.ro); 9365 QL_PRINT_3(CE_CONT, "(%d): ub_frame.f_ctl=%xh\n", 9366 ha->instance, ubp->ub_frame.f_ctl); 9367 QL_PRINT_3(CE_CONT, "(%d): ub_bufsize=%xh\n", 9368 ha->instance, ubp->ub_bufsize); 9369 QL_DUMP_3(ubp->ub_buffer, 8, 9370 ubp->ub_bufsize < 64 ? ubp->ub_bufsize : 64); 9371 9372 sp->flags |= SRB_UB_CALLBACK | SRB_UB_ACQUIRED; 9373 ql_add_link_b(done_q, &sp->cmd); 9374 rval = QL_SUCCESS; 9375 } else { 9376 if (sp->handle != index) { 9377 EL(ha, "Bad index=%xh, expect=%xh\n", index, 9378 sp->handle); 9379 } 9380 if ((sp->flags & SRB_UB_IN_ISP) == 0) { 9381 EL(ha, "buffer was already in driver, index=%xh\n", 9382 index); 9383 } 9384 if ((sp->ub_type == FC_TYPE_IS8802_SNAP) == 0) { 9385 EL(ha, "buffer was not an IP buffer, index=%xh\n", 9386 index); 9387 } 9388 if (sp->flags & SRB_UB_ACQUIRED) { 9389 EL(ha, "buffer was being used by driver, index=%xh\n", 9390 index); 9391 } 9392 } 9393 QL_UB_UNLOCK(ha); 9394 9395 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance); 9396 9397 return (rval); 9398} 9399 9400/* 9401 * ql_timer 9402 * One second timer function. 9403 * 9404 * Input: 9405 * ql_hba.first = first link in adapter list. 9406 * 9407 * Context: 9408 * Interrupt context, no mailbox commands allowed. 9409 */ 9410static void 9411ql_timer(void *arg) 9412{ 9413 ql_link_t *link; 9414 uint32_t set_flags; 9415 uint32_t reset_flags; 9416 ql_adapter_state_t *ha = NULL, *vha; 9417 9418 QL_PRINT_6(CE_CONT, "started\n"); 9419 9420 /* Acquire global state lock. */ 9421 GLOBAL_STATE_LOCK(); 9422 if (ql_timer_timeout_id == NULL) { 9423 /* Release global state lock. */ 9424 GLOBAL_STATE_UNLOCK(); 9425 return; 9426 } 9427 9428 for (link = ql_hba.first; link != NULL; link = link->next) { 9429 ha = link->base_address; 9430 9431 /* Skip adapter if suspended of stalled. */ 9432 ADAPTER_STATE_LOCK(ha); 9433 if (ha->flags & ADAPTER_SUSPENDED || 9434 ha->task_daemon_flags & DRIVER_STALL) { 9435 ADAPTER_STATE_UNLOCK(ha); 9436 continue; 9437 } 9438 ha->flags |= ADAPTER_TIMER_BUSY; 9439 ADAPTER_STATE_UNLOCK(ha); 9440 9441 QL_PM_LOCK(ha); 9442 if (ha->power_level != PM_LEVEL_D0) { 9443 QL_PM_UNLOCK(ha); 9444 9445 ADAPTER_STATE_LOCK(ha); 9446 ha->flags &= ~ADAPTER_TIMER_BUSY; 9447 ADAPTER_STATE_UNLOCK(ha); 9448 continue; 9449 } 9450 ha->busy++; 9451 QL_PM_UNLOCK(ha); 9452 9453 set_flags = 0; 9454 reset_flags = 0; 9455 9456 /* Port retry timer handler. */ 9457 if (LOOP_READY(ha)) { 9458 ADAPTER_STATE_LOCK(ha); 9459 if (ha->port_retry_timer != 0) { 9460 ha->port_retry_timer--; 9461 if (ha->port_retry_timer == 0) { 9462 set_flags |= PORT_RETRY_NEEDED; 9463 } 9464 } 9465 ADAPTER_STATE_UNLOCK(ha); 9466 } 9467 9468 /* Loop down timer handler. */ 9469 if (LOOP_RECONFIGURE(ha) == 0) { 9470 if (ha->loop_down_timer > LOOP_DOWN_TIMER_END) { 9471 ha->loop_down_timer--; 9472 /* 9473 * give the firmware loop down dump flag 9474 * a chance to work. 9475 */ 9476 if (ha->loop_down_timer == LOOP_DOWN_RESET) { 9477 if (CFG_IST(ha, 9478 CFG_DUMP_LOOP_OFFLINE_TIMEOUT)) { 9479 (void) ql_binary_fw_dump(ha, 9480 TRUE); 9481 } 9482 EL(ha, "loop_down_reset, " 9483 "isp_abort_needed\n"); 9484 set_flags |= ISP_ABORT_NEEDED; 9485 } 9486 } 9487 if (CFG_IST(ha, CFG_ENABLE_LINK_DOWN_REPORTING)) { 9488 /* Command abort time handler. */ 9489 if (ha->loop_down_timer == 9490 ha->loop_down_abort_time) { 9491 ADAPTER_STATE_LOCK(ha); 9492 ha->flags |= ABORT_CMDS_LOOP_DOWN_TMO; 9493 ADAPTER_STATE_UNLOCK(ha); 9494 set_flags |= ABORT_QUEUES_NEEDED; 9495 EL(ha, "loop_down_abort_time, " 9496 "abort_queues_needed\n"); 9497 } 9498 9499 /* Watchdog timer handler. */ 9500 if (ha->watchdog_timer == 0) { 9501 ha->watchdog_timer = WATCHDOG_TIME; 9502 } else if (LOOP_READY(ha)) { 9503 ha->watchdog_timer--; 9504 if (ha->watchdog_timer == 0) { 9505 for (vha = ha; vha != NULL; 9506 vha = vha->vp_next) { 9507 ql_watchdog(vha, 9508 &set_flags, 9509 &reset_flags); 9510 } 9511 ha->watchdog_timer = 9512 WATCHDOG_TIME; 9513 } 9514 } 9515 } 9516 } 9517 9518 /* Idle timer handler. */ 9519 if (!DRIVER_SUSPENDED(ha)) { 9520 if (++ha->idle_timer >= IDLE_CHECK_TIMER) { 9521#if defined(QL_DEBUG_LEVEL_6) || !defined(QL_DEBUG_LEVEL_3) 9522 set_flags |= TASK_DAEMON_IDLE_CHK_FLG; 9523#endif 9524 ha->idle_timer = 0; 9525 } 9526 if (ha->send_plogi_timer != NULL) { 9527 ha->send_plogi_timer--; 9528 if (ha->send_plogi_timer == NULL) { 9529 set_flags |= SEND_PLOGI; 9530 } 9531 } 9532 } 9533 ADAPTER_STATE_LOCK(ha); 9534 if (ha->restart_mpi_timer != 0) { 9535 ha->restart_mpi_timer--; 9536 if (ha->restart_mpi_timer == 0 && 9537 ha->idc_restart_mpi != 0) { 9538 ha->idc_restart_mpi = 0; 9539 reset_flags |= TASK_DAEMON_STALLED_FLG; 9540 } 9541 } 9542 if (ha->flash_acc_timer != 0) { 9543 ha->flash_acc_timer--; 9544 if (ha->flash_acc_timer == 0 && 9545 ha->idc_flash_acc != 0) { 9546 ha->idc_flash_acc = 1; 9547 ha->idc_mb[1] = 0; 9548 ha->idc_mb[2] = IDC_OPC_DRV_START; 9549 set_flags |= IDC_ACK_NEEDED; 9550 } 9551 } 9552 ADAPTER_STATE_UNLOCK(ha); 9553 9554 if (set_flags != 0 || reset_flags != 0) { 9555 ql_awaken_task_daemon(ha, NULL, set_flags, 9556 reset_flags); 9557 } 9558 9559 if (ha->xioctl->ledstate.BeaconState == BEACON_ON) { 9560 ql_blink_led(ha); 9561 } 9562 9563 /* Update the IO stats */ 9564 if (ha->xioctl->IOInputByteCnt >= 0x100000) { 9565 ha->xioctl->IOInputMByteCnt += 9566 (ha->xioctl->IOInputByteCnt / 0x100000); 9567 ha->xioctl->IOInputByteCnt %= 0x100000; 9568 } 9569 9570 if (ha->xioctl->IOOutputByteCnt >= 0x100000) { 9571 ha->xioctl->IOOutputMByteCnt += 9572 (ha->xioctl->IOOutputByteCnt / 0x100000); 9573 ha->xioctl->IOOutputByteCnt %= 0x100000; 9574 } 9575 9576 ADAPTER_STATE_LOCK(ha); 9577 ha->flags &= ~ADAPTER_TIMER_BUSY; 9578 ADAPTER_STATE_UNLOCK(ha); 9579 9580 QL_PM_LOCK(ha); 9581 ha->busy--; 9582 QL_PM_UNLOCK(ha); 9583 } 9584 9585 /* Restart timer, if not being stopped. */ 9586 if (ql_timer_timeout_id != NULL) { 9587 ql_timer_timeout_id = timeout(ql_timer, arg, ql_timer_ticks); 9588 } 9589 9590 /* Release global state lock. */ 9591 GLOBAL_STATE_UNLOCK(); 9592 9593 QL_PRINT_6(CE_CONT, "done\n"); 9594} 9595 9596/* 9597 * ql_timeout_insert 9598 * Function used to insert a command block onto the 9599 * watchdog timer queue. 9600 * 9601 * Note: Must insure that pkt_time is not zero 9602 * before calling ql_timeout_insert. 9603 * 9604 * Input: 9605 * ha: adapter state pointer. 9606 * tq: target queue pointer. 9607 * sp: SRB pointer. 9608 * DEVICE_QUEUE_LOCK must be already obtained. 9609 * 9610 * Context: 9611 * Kernel context. 9612 */ 9613/* ARGSUSED */ 9614static void 9615ql_timeout_insert(ql_adapter_state_t *ha, ql_tgt_t *tq, ql_srb_t *sp) 9616{ 9617 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance); 9618 9619 if (sp->pkt->pkt_timeout != 0 && sp->pkt->pkt_timeout < 0x10000) { 9620 sp->isp_timeout = (uint16_t)(sp->pkt->pkt_timeout); 9621 /* 9622 * The WATCHDOG_TIME must be rounded up + 1. As an example, 9623 * consider a 1 second timeout. If the WATCHDOG_TIME is 1, it 9624 * will expire in the next watchdog call, which could be in 9625 * 1 microsecond. 9626 * 9627 */ 9628 sp->wdg_q_time = (sp->isp_timeout + WATCHDOG_TIME - 1) / 9629 WATCHDOG_TIME; 9630 /* 9631 * Added an additional 10 to account for the 9632 * firmware timer drift which can occur with 9633 * very long timeout values. 9634 */ 9635 sp->wdg_q_time += 10; 9636 9637 /* 9638 * Add 6 more to insure watchdog does not timeout at the same 9639 * time as ISP RISC code timeout. 9640 */ 9641 sp->wdg_q_time += 6; 9642 9643 /* Save initial time for resetting watchdog time. */ 9644 sp->init_wdg_q_time = sp->wdg_q_time; 9645 9646 /* Insert command onto watchdog queue. */ 9647 ql_add_link_b(&tq->wdg, &sp->wdg); 9648 9649 sp->flags |= SRB_WATCHDOG_ENABLED; 9650 } else { 9651 sp->isp_timeout = 0; 9652 sp->wdg_q_time = 0; 9653 sp->init_wdg_q_time = 0; 9654 } 9655 9656 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance); 9657} 9658 9659/* 9660 * ql_watchdog 9661 * Timeout handler that runs in interrupt context. The 9662 * ql_adapter_state_t * argument is the parameter set up when the 9663 * timeout was initialized (state structure pointer). 9664 * Function used to update timeout values and if timeout 9665 * has occurred command will be aborted. 9666 * 9667 * Input: 9668 * ha: adapter state pointer. 9669 * set_flags: task daemon flags to set. 9670 * reset_flags: task daemon flags to reset. 9671 * 9672 * Context: 9673 * Interrupt context, no mailbox commands allowed. 9674 */ 9675static void 9676ql_watchdog(ql_adapter_state_t *ha, uint32_t *set_flags, uint32_t *reset_flags) 9677{ 9678 ql_srb_t *sp; 9679 ql_link_t *link; 9680 ql_link_t *next_cmd; 9681 ql_link_t *next_device; 9682 ql_tgt_t *tq; 9683 ql_lun_t *lq; 9684 uint16_t index; 9685 int q_sane; 9686 9687 QL_PRINT_6(CE_CONT, "(%d): started\n", ha->instance); 9688 9689 /* Loop through all targets. */ 9690 for (index = 0; index < DEVICE_HEAD_LIST_SIZE; index++) { 9691 for (link = ha->dev[index].first; link != NULL; 9692 link = next_device) { 9693 tq = link->base_address; 9694 9695 /* Try to acquire device queue lock. */ 9696 if (TRY_DEVICE_QUEUE_LOCK(tq) == 0) { 9697 next_device = NULL; 9698 continue; 9699 } 9700 9701 next_device = link->next; 9702 9703 if (!(CFG_IST(ha, CFG_ENABLE_LINK_DOWN_REPORTING)) && 9704 (tq->port_down_retry_count == 0)) { 9705 /* Release device queue lock. */ 9706 DEVICE_QUEUE_UNLOCK(tq); 9707 continue; 9708 } 9709 9710 /* Find out if this device is in a sane state. */ 9711 if (tq->flags & (TQF_RSCN_RCVD | 9712 TQF_NEED_AUTHENTICATION | TQF_QUEUE_SUSPENDED)) { 9713 q_sane = 0; 9714 } else { 9715 q_sane = 1; 9716 } 9717 /* Loop through commands on watchdog queue. */ 9718 for (link = tq->wdg.first; link != NULL; 9719 link = next_cmd) { 9720 next_cmd = link->next; 9721 sp = link->base_address; 9722 lq = sp->lun_queue; 9723 9724 /* 9725 * For SCSI commands, if everything seems to 9726 * be going fine and this packet is stuck 9727 * because of throttling at LUN or target 9728 * level then do not decrement the 9729 * sp->wdg_q_time 9730 */ 9731 if (ha->task_daemon_flags & STATE_ONLINE && 9732 (sp->flags & SRB_ISP_STARTED) == 0 && 9733 q_sane && sp->flags & SRB_FCP_CMD_PKT && 9734 lq->lun_outcnt >= ha->execution_throttle) { 9735 continue; 9736 } 9737 9738 if (sp->wdg_q_time != 0) { 9739 sp->wdg_q_time--; 9740 9741 /* Timeout? */ 9742 if (sp->wdg_q_time != 0) { 9743 continue; 9744 } 9745 9746 ql_remove_link(&tq->wdg, &sp->wdg); 9747 sp->flags &= ~SRB_WATCHDOG_ENABLED; 9748 9749 if (sp->flags & SRB_ISP_STARTED) { 9750 ql_cmd_timeout(ha, tq, sp, 9751 set_flags, reset_flags); 9752 9753 DEVICE_QUEUE_UNLOCK(tq); 9754 tq = NULL; 9755 next_cmd = NULL; 9756 next_device = NULL; 9757 index = DEVICE_HEAD_LIST_SIZE; 9758 } else { 9759 ql_cmd_timeout(ha, tq, sp, 9760 set_flags, reset_flags); 9761 } 9762 } 9763 } 9764 9765 /* Release device queue lock. */ 9766 if (tq != NULL) { 9767 DEVICE_QUEUE_UNLOCK(tq); 9768 } 9769 } 9770 } 9771 9772 QL_PRINT_6(CE_CONT, "(%d): done\n", ha->instance); 9773} 9774 9775/* 9776 * ql_cmd_timeout 9777 * Command timeout handler. 9778 * 9779 * Input: 9780 * ha: adapter state pointer. 9781 * tq: target queue pointer. 9782 * sp: SRB pointer. 9783 * set_flags: task daemon flags to set. 9784 * reset_flags: task daemon flags to reset. 9785 * 9786 * Context: 9787 * Interrupt context, no mailbox commands allowed. 9788 */ 9789/* ARGSUSED */ 9790static void 9791ql_cmd_timeout(ql_adapter_state_t *ha, ql_tgt_t *tq, ql_srb_t *sp, 9792 uint32_t *set_flags, uint32_t *reset_flags) 9793{ 9794 9795 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance); 9796 9797 if (!(sp->flags & SRB_ISP_STARTED)) { 9798 9799 EL(ha, "command timed out in driver = %ph\n", (void *)sp); 9800 9801 REQUEST_RING_LOCK(ha); 9802 9803 /* if it's on a queue */ 9804 if (sp->cmd.head) { 9805 /* 9806 * The pending_cmds que needs to be 9807 * protected by the ring lock 9808 */ 9809 ql_remove_link(sp->cmd.head, &sp->cmd); 9810 } 9811 sp->flags &= ~SRB_IN_DEVICE_QUEUE; 9812 9813 /* Release device queue lock. */ 9814 REQUEST_RING_UNLOCK(ha); 9815 DEVICE_QUEUE_UNLOCK(tq); 9816 9817 /* Set timeout status */ 9818 sp->pkt->pkt_reason = CS_TIMEOUT; 9819 9820 /* Ensure no retry */ 9821 sp->flags &= ~SRB_RETRY; 9822 9823 /* Call done routine to handle completion. */ 9824 ql_done(&sp->cmd); 9825 9826 DEVICE_QUEUE_LOCK(tq); 9827 } else { 9828 EL(ha, "command timed out in isp=%ph, osc=%ph, index=%xh, " 9829 "isp_abort_needed\n", (void *)sp, 9830 (void *)ha->outstanding_cmds[sp->handle & OSC_INDEX_MASK], 9831 sp->handle & OSC_INDEX_MASK); 9832 9833 /* Release device queue lock. */ 9834 DEVICE_QUEUE_UNLOCK(tq); 9835 9836 INTR_LOCK(ha); 9837 ha->pha->xioctl->ControllerErrorCount++; 9838 INTR_UNLOCK(ha); 9839 9840 /* Set ISP needs to be reset */ 9841 sp->flags |= SRB_COMMAND_TIMEOUT; 9842 9843 if (CFG_IST(ha, CFG_DUMP_DRIVER_COMMAND_TIMEOUT)) { 9844 (void) ql_binary_fw_dump(ha, TRUE); 9845 } 9846 9847 *set_flags |= ISP_ABORT_NEEDED; 9848 9849 DEVICE_QUEUE_LOCK(tq); 9850 } 9851 9852 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance); 9853} 9854 9855/* 9856 * ql_rst_aen 9857 * Processes asynchronous reset. 9858 * 9859 * Input: 9860 * ha = adapter state pointer. 9861 * 9862 * Context: 9863 * Kernel context. 9864 */ 9865static void 9866ql_rst_aen(ql_adapter_state_t *ha) 9867{ 9868 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance); 9869 9870 /* Issue marker command. */ 9871 (void) ql_marker(ha, 0, 0, MK_SYNC_ALL); 9872 9873 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance); 9874} 9875 9876/* 9877 * ql_cmd_wait 9878 * Stall driver until all outstanding commands are returned. 9879 * 9880 * Input: 9881 * ha = adapter state pointer. 9882 * 9883 * Context: 9884 * Kernel context. 9885 */ 9886void 9887ql_cmd_wait(ql_adapter_state_t *ha) 9888{ 9889 uint16_t index; 9890 ql_link_t *link; 9891 ql_tgt_t *tq; 9892 ql_adapter_state_t *vha; 9893 9894 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance); 9895 9896 /* Wait for all outstanding commands to be returned. */ 9897 (void) ql_wait_outstanding(ha); 9898 9899 /* 9900 * clear out internally queued commands 9901 */ 9902 for (vha = ha; vha != NULL; vha = vha->vp_next) { 9903 for (index = 0; index < DEVICE_HEAD_LIST_SIZE; index++) { 9904 for (link = vha->dev[index].first; link != NULL; 9905 link = link->next) { 9906 tq = link->base_address; 9907 if (tq && 9908 (!(tq->prli_svc_param_word_3 & 9909 PRLI_W3_RETRY))) { 9910 (void) ql_abort_device(vha, tq, 0); 9911 } 9912 } 9913 } 9914 } 9915 9916 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance); 9917} 9918 9919/* 9920 * ql_wait_outstanding 9921 * Wait for all outstanding commands to complete. 9922 * 9923 * Input: 9924 * ha = adapter state pointer. 9925 * 9926 * Returns: 9927 * index - the index for ql_srb into outstanding_cmds. 9928 * 9929 * Context: 9930 * Kernel context. 9931 */ 9932static uint16_t 9933ql_wait_outstanding(ql_adapter_state_t *ha) 9934{ 9935 ql_srb_t *sp; 9936 uint16_t index, count; 9937 9938 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance); 9939 9940 count = 3000; 9941 for (index = 1; index < MAX_OUTSTANDING_COMMANDS; index++) { 9942 if (ha->pha->pending_cmds.first != NULL) { 9943 ql_start_iocb(ha, NULL); 9944 index = 1; 9945 } 9946 if ((sp = ha->pha->outstanding_cmds[index]) != NULL && 9947 (sp->flags & SRB_COMMAND_TIMEOUT) == 0) { 9948 if (count-- != 0) { 9949 ql_delay(ha, 10000); 9950 index = 0; 9951 } else { 9952 EL(ha, "failed, sp=%ph\n", (void *)sp); 9953 break; 9954 } 9955 } 9956 } 9957 9958 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance); 9959 9960 return (index); 9961} 9962 9963/* 9964 * ql_restart_queues 9965 * Restart device queues. 9966 * 9967 * Input: 9968 * ha = adapter state pointer. 9969 * DEVICE_QUEUE_LOCK must be released. 9970 * 9971 * Context: 9972 * Interrupt or Kernel context, no mailbox commands allowed. 9973 */ 9974static void 9975ql_restart_queues(ql_adapter_state_t *ha) 9976{ 9977 ql_link_t *link, *link2; 9978 ql_tgt_t *tq; 9979 ql_lun_t *lq; 9980 uint16_t index; 9981 ql_adapter_state_t *vha; 9982 9983 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance); 9984 9985 for (vha = ha->pha; vha != NULL; vha = vha->vp_next) { 9986 for (index = 0; index < DEVICE_HEAD_LIST_SIZE; index++) { 9987 for (link = vha->dev[index].first; link != NULL; 9988 link = link->next) { 9989 tq = link->base_address; 9990 9991 /* Acquire device queue lock. */ 9992 DEVICE_QUEUE_LOCK(tq); 9993 9994 tq->flags &= ~TQF_QUEUE_SUSPENDED; 9995 9996 for (link2 = tq->lun_queues.first; 9997 link2 != NULL; link2 = link2->next) { 9998 lq = link2->base_address; 9999 10000 if (lq->cmd.first != NULL) { 10001 ql_next(vha, lq); 10002 DEVICE_QUEUE_LOCK(tq); 10003 } 10004 } 10005 10006 /* Release device queue lock. */ 10007 DEVICE_QUEUE_UNLOCK(tq); 10008 } 10009 } 10010 } 10011 10012 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance); 10013} 10014 10015/* 10016 * ql_iidma 10017 * Setup iiDMA parameters to firmware 10018 * 10019 * Input: 10020 * ha = adapter state pointer. 10021 * DEVICE_QUEUE_LOCK must be released. 10022 * 10023 * Context: 10024 * Interrupt or Kernel context, no mailbox commands allowed. 10025 */ 10026static void 10027ql_iidma(ql_adapter_state_t *ha) 10028{ 10029 ql_link_t *link; 10030 ql_tgt_t *tq; 10031 uint16_t index; 10032 char buf[256]; 10033 uint32_t data; 10034 10035 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance); 10036 10037 if ((CFG_IST(ha, CFG_CTRL_242581)) == 0) { 10038 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance); 10039 return; 10040 } 10041 10042 for (index = 0; index < DEVICE_HEAD_LIST_SIZE; index++) { 10043 for (link = ha->dev[index].first; link != NULL; 10044 link = link->next) { 10045 tq = link->base_address; 10046 10047 /* Acquire device queue lock. */ 10048 DEVICE_QUEUE_LOCK(tq); 10049 10050 if ((tq->flags & TQF_IIDMA_NEEDED) == 0) { 10051 DEVICE_QUEUE_UNLOCK(tq); 10052 continue; 10053 } 10054 10055 tq->flags &= ~TQF_IIDMA_NEEDED; 10056 10057 if ((tq->loop_id > LAST_N_PORT_HDL) || 10058 (tq->iidma_rate == IIDMA_RATE_NDEF)) { 10059 DEVICE_QUEUE_UNLOCK(tq); 10060 continue; 10061 } 10062 10063 /* Get the iiDMA persistent data */ 10064 if (tq->iidma_rate == IIDMA_RATE_INIT) { 10065 (void) sprintf(buf, 10066 "iidma-rate-%02x%02x%02x%02x%02x" 10067 "%02x%02x%02x", tq->port_name[0], 10068 tq->port_name[1], tq->port_name[2], 10069 tq->port_name[3], tq->port_name[4], 10070 tq->port_name[5], tq->port_name[6], 10071 tq->port_name[7]); 10072 10073 if ((data = ql_get_prop(ha, buf)) == 10074 0xffffffff) { 10075 tq->iidma_rate = IIDMA_RATE_NDEF; 10076 } else { 10077 switch (data) { 10078 case IIDMA_RATE_1GB: 10079 case IIDMA_RATE_2GB: 10080 case IIDMA_RATE_4GB: 10081 case IIDMA_RATE_10GB: 10082 tq->iidma_rate = data; 10083 break; 10084 case IIDMA_RATE_8GB: 10085 if (CFG_IST(ha, 10086 CFG_CTRL_25XX)) { 10087 tq->iidma_rate = data; 10088 } else { 10089 tq->iidma_rate = 10090 IIDMA_RATE_4GB; 10091 } 10092 break; 10093 default: 10094 EL(ha, "invalid data for " 10095 "parameter: %s: %xh\n", 10096 buf, data); 10097 tq->iidma_rate = 10098 IIDMA_RATE_NDEF; 10099 break; 10100 } 10101 } 10102 } 10103 10104 /* Set the firmware's iiDMA rate */ 10105 if (tq->iidma_rate <= IIDMA_RATE_MAX && 10106 !(CFG_IST(ha, CFG_CTRL_81XX))) { 10107 data = ql_iidma_rate(ha, tq->loop_id, 10108 &tq->iidma_rate, EXT_IIDMA_MODE_SET); 10109 if (data != QL_SUCCESS) { 10110 EL(ha, "mbx failed: %xh\n", data); 10111 } 10112 } 10113 10114 /* Release device queue lock. */ 10115 DEVICE_QUEUE_UNLOCK(tq); 10116 } 10117 } 10118 10119 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance); 10120} 10121 10122/* 10123 * ql_abort_queues 10124 * Abort all commands on device queues. 10125 * 10126 * Input: 10127 * ha = adapter state pointer. 10128 * 10129 * Context: 10130 * Interrupt or Kernel context, no mailbox commands allowed. 10131 */ 10132static void 10133ql_abort_queues(ql_adapter_state_t *ha) 10134{ 10135 ql_link_t *link; 10136 ql_tgt_t *tq; 10137 ql_srb_t *sp; 10138 uint16_t index; 10139 ql_adapter_state_t *vha; 10140 10141 QL_PRINT_10(CE_CONT, "(%d): started\n", ha->instance); 10142 10143 /* Return all commands in outstanding command list. */ 10144 INTR_LOCK(ha); 10145 10146 /* Place all commands in outstanding cmd list on device queue. */ 10147 for (index = 1; index < MAX_OUTSTANDING_COMMANDS; index++) { 10148 if (ha->pending_cmds.first != NULL) { 10149 INTR_UNLOCK(ha); 10150 ql_start_iocb(ha, NULL); 10151 /* Delay for system */ 10152 ql_delay(ha, 10000); 10153 INTR_LOCK(ha); 10154 index = 1; 10155 } 10156 sp = ha->outstanding_cmds[index]; 10157 10158 /* skip devices capable of FCP2 retrys */ 10159 if ((sp != NULL) && 10160 ((tq = sp->lun_queue->target_queue) != NULL) && 10161 (!(tq->prli_svc_param_word_3 & PRLI_W3_RETRY))) { 10162 ha->outstanding_cmds[index] = NULL; 10163 sp->handle = 0; 10164 sp->flags &= ~SRB_IN_TOKEN_ARRAY; 10165 10166 INTR_UNLOCK(ha); 10167 10168 /* Set ending status. */ 10169 sp->pkt->pkt_reason = CS_PORT_UNAVAILABLE; 10170 sp->flags |= SRB_ISP_COMPLETED; 10171 10172 /* Call done routine to handle completions. */ 10173 sp->cmd.next = NULL; 10174 ql_done(&sp->cmd); 10175 10176 INTR_LOCK(ha); 10177 } 10178 } 10179 INTR_UNLOCK(ha); 10180 10181 for (vha = ha; vha != NULL; vha = vha->vp_next) { 10182 QL_PRINT_10(CE_CONT, "(%d,%d): abort instance\n", 10183 vha->instance, vha->vp_index); 10184 for (index = 0; index < DEVICE_HEAD_LIST_SIZE; index++) { 10185 for (link = vha->dev[index].first; link != NULL; 10186 link = link->next) { 10187 tq = link->base_address; 10188 /* skip devices capable of FCP2 retrys */ 10189 if (!(tq->prli_svc_param_word_3 & 10190 PRLI_W3_RETRY)) { 10191 /* 10192 * Set port unavailable status and 10193 * return all commands on a devices 10194 * queues. 10195 */ 10196 ql_abort_device_queues(ha, tq); 10197 } 10198 } 10199 } 10200 } 10201 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance); 10202} 10203 10204/* 10205 * ql_abort_device_queues 10206 * Abort all commands on device queues. 10207 * 10208 * Input: 10209 * ha = adapter state pointer. 10210 * 10211 * Context: 10212 * Interrupt or Kernel context, no mailbox commands allowed. 10213 */ 10214static void 10215ql_abort_device_queues(ql_adapter_state_t *ha, ql_tgt_t *tq) 10216{ 10217 ql_link_t *lun_link, *cmd_link; 10218 ql_srb_t *sp; 10219 ql_lun_t *lq; 10220 10221 QL_PRINT_10(CE_CONT, "(%d): started\n", ha->instance); 10222 10223 DEVICE_QUEUE_LOCK(tq); 10224 10225 for (lun_link = tq->lun_queues.first; lun_link != NULL; 10226 lun_link = lun_link->next) { 10227 lq = lun_link->base_address; 10228 10229 cmd_link = lq->cmd.first; 10230 while (cmd_link != NULL) { 10231 sp = cmd_link->base_address; 10232 10233 if (sp->flags & SRB_ABORT) { 10234 cmd_link = cmd_link->next; 10235 continue; 10236 } 10237 10238 /* Remove srb from device cmd queue. */ 10239 ql_remove_link(&lq->cmd, &sp->cmd); 10240 10241 sp->flags &= ~SRB_IN_DEVICE_QUEUE; 10242 10243 DEVICE_QUEUE_UNLOCK(tq); 10244 10245 /* Set ending status. */ 10246 sp->pkt->pkt_reason = CS_PORT_UNAVAILABLE; 10247 10248 /* Call done routine to handle completion. */ 10249 ql_done(&sp->cmd); 10250 10251 /* Delay for system */ 10252 ql_delay(ha, 10000); 10253 10254 DEVICE_QUEUE_LOCK(tq); 10255 cmd_link = lq->cmd.first; 10256 } 10257 } 10258 DEVICE_QUEUE_UNLOCK(tq); 10259 10260 QL_PRINT_10(CE_CONT, "(%d): done\n", ha->instance); 10261} 10262 10263/* 10264 * ql_loop_resync 10265 * Resync with fibre channel devices. 10266 * 10267 * Input: 10268 * ha = adapter state pointer. 10269 * DEVICE_QUEUE_LOCK must be released. 10270 * 10271 * Returns: 10272 * ql local function return status code. 10273 * 10274 * Context: 10275 * Kernel context. 10276 */ 10277static int 10278ql_loop_resync(ql_adapter_state_t *ha) 10279{ 10280 int rval; 10281 10282 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance); 10283 10284 if (ha->flags & IP_INITIALIZED) { 10285 (void) ql_shutdown_ip(ha); 10286 } 10287 10288 rval = ql_fw_ready(ha, 10); 10289 10290 TASK_DAEMON_LOCK(ha); 10291 ha->task_daemon_flags &= ~LOOP_RESYNC_ACTIVE; 10292 TASK_DAEMON_UNLOCK(ha); 10293 10294 /* Set loop online, if it really is. */ 10295 if (rval == QL_SUCCESS) { 10296 ql_loop_online(ha); 10297 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance); 10298 } else { 10299 EL(ha, "failed, rval = %xh\n", rval); 10300 } 10301 10302 return (rval); 10303} 10304 10305/* 10306 * ql_loop_online 10307 * Set loop online status if it really is online. 10308 * 10309 * Input: 10310 * ha = adapter state pointer. 10311 * DEVICE_QUEUE_LOCK must be released. 10312 * 10313 * Context: 10314 * Kernel context. 10315 */ 10316void 10317ql_loop_online(ql_adapter_state_t *ha) 10318{ 10319 ql_adapter_state_t *vha; 10320 10321 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance); 10322 10323 /* Inform the FC Transport that the hardware is online. */ 10324 for (vha = ha->pha; vha != NULL; vha = vha->vp_next) { 10325 if (!(vha->task_daemon_flags & 10326 (LOOP_RESYNC_NEEDED | LOOP_DOWN))) { 10327 /* Restart IP if it was shutdown. */ 10328 if (vha->vp_index == 0 && vha->flags & IP_ENABLED && 10329 !(vha->flags & IP_INITIALIZED)) { 10330 (void) ql_initialize_ip(vha); 10331 ql_isp_rcvbuf(vha); 10332 } 10333 10334 if (FC_PORT_STATE_MASK(vha->state) != FC_STATE_LOOP && 10335 FC_PORT_STATE_MASK(vha->state) != 10336 FC_STATE_ONLINE) { 10337 vha->state = FC_PORT_SPEED_MASK(vha->state); 10338 if (vha->topology & QL_LOOP_CONNECTION) { 10339 vha->state |= FC_STATE_LOOP; 10340 } else { 10341 vha->state |= FC_STATE_ONLINE; 10342 } 10343 TASK_DAEMON_LOCK(ha); 10344 vha->task_daemon_flags |= FC_STATE_CHANGE; 10345 TASK_DAEMON_UNLOCK(ha); 10346 } 10347 } 10348 } 10349 10350 ql_awaken_task_daemon(ha, NULL, 0, 0); 10351 10352 /* Restart device queues that may have been stopped. */ 10353 ql_restart_queues(ha); 10354 10355 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance); 10356} 10357 10358/* 10359 * ql_fca_handle_to_state 10360 * Verifies handle to be correct. 10361 * 10362 * Input: 10363 * fca_handle = pointer to state structure. 10364 * 10365 * Returns: 10366 * NULL = failure 10367 * 10368 * Context: 10369 * Kernel context. 10370 */ 10371static ql_adapter_state_t * 10372ql_fca_handle_to_state(opaque_t fca_handle) 10373{ 10374#ifdef QL_DEBUG_ROUTINES 10375 ql_link_t *link; 10376 ql_adapter_state_t *ha = NULL; 10377 ql_adapter_state_t *vha = NULL; 10378 10379 for (link = ql_hba.first; link != NULL; link = link->next) { 10380 ha = link->base_address; 10381 for (vha = ha->vp_next; vha != NULL; vha = vha->vp_next) { 10382 if ((opaque_t)vha == fca_handle) { 10383 ha = vha; 10384 break; 10385 } 10386 } 10387 if ((opaque_t)ha == fca_handle) { 10388 break; 10389 } else { 10390 ha = NULL; 10391 } 10392 } 10393 10394 if (ha == NULL) { 10395 /*EMPTY*/ 10396 QL_PRINT_2(CE_CONT, "failed\n"); 10397 } 10398 10399#endif /* QL_DEBUG_ROUTINES */ 10400 10401 return ((ql_adapter_state_t *)fca_handle); 10402} 10403 10404/* 10405 * ql_d_id_to_queue 10406 * Locate device queue that matches destination ID. 10407 * 10408 * Input: 10409 * ha = adapter state pointer. 10410 * d_id = destination ID 10411 * 10412 * Returns: 10413 * NULL = failure 10414 * 10415 * Context: 10416 * Interrupt or Kernel context, no mailbox commands allowed. 10417 */ 10418ql_tgt_t * 10419ql_d_id_to_queue(ql_adapter_state_t *ha, port_id_t d_id) 10420{ 10421 uint16_t index; 10422 ql_tgt_t *tq; 10423 ql_link_t *link; 10424 10425 /* Get head queue index. */ 10426 index = ql_alpa_to_index[d_id.b.al_pa]; 10427 10428 for (link = ha->dev[index].first; link != NULL; link = link->next) { 10429 tq = link->base_address; 10430 if (tq->d_id.b24 == d_id.b24 && 10431 VALID_DEVICE_ID(ha, tq->loop_id)) { 10432 return (tq); 10433 } 10434 } 10435 10436 return (NULL); 10437} 10438 10439/* 10440 * ql_loop_id_to_queue 10441 * Locate device queue that matches loop ID. 10442 * 10443 * Input: 10444 * ha: adapter state pointer. 10445 * loop_id: destination ID 10446 * 10447 * Returns: 10448 * NULL = failure 10449 * 10450 * Context: 10451 * Interrupt or Kernel context, no mailbox commands allowed. 10452 */ 10453ql_tgt_t * 10454ql_loop_id_to_queue(ql_adapter_state_t *ha, uint16_t loop_id) 10455{ 10456 uint16_t index; 10457 ql_tgt_t *tq; 10458 ql_link_t *link; 10459 10460 for (index = 0; index < DEVICE_HEAD_LIST_SIZE; index++) { 10461 for (link = ha->dev[index].first; link != NULL; 10462 link = link->next) { 10463 tq = link->base_address; 10464 if (tq->loop_id == loop_id) { 10465 return (tq); 10466 } 10467 } 10468 } 10469 10470 return (NULL); 10471} 10472 10473/* 10474 * ql_kstat_update 10475 * Updates kernel statistics. 10476 * 10477 * Input: 10478 * ksp - driver kernel statistics structure pointer. 10479 * rw - function to perform 10480 * 10481 * Returns: 10482 * 0 or EACCES 10483 * 10484 * Context: 10485 * Kernel context. 10486 */ 10487/* ARGSUSED */ 10488static int 10489ql_kstat_update(kstat_t *ksp, int rw) 10490{ 10491 int rval; 10492 10493 QL_PRINT_3(CE_CONT, "started\n"); 10494 10495 if (rw == KSTAT_WRITE) { 10496 rval = EACCES; 10497 } else { 10498 rval = 0; 10499 } 10500 10501 if (rval != 0) { 10502 /*EMPTY*/ 10503 QL_PRINT_2(CE_CONT, "failed, rval = %xh\n", rval); 10504 } else { 10505 /*EMPTY*/ 10506 QL_PRINT_3(CE_CONT, "done\n"); 10507 } 10508 return (rval); 10509} 10510 10511/* 10512 * ql_load_flash 10513 * Loads flash. 10514 * 10515 * Input: 10516 * ha: adapter state pointer. 10517 * dp: data pointer. 10518 * size: data length. 10519 * 10520 * Returns: 10521 * ql local function return status code. 10522 * 10523 * Context: 10524 * Kernel context. 10525 */ 10526int 10527ql_load_flash(ql_adapter_state_t *ha, uint8_t *dp, uint32_t size) 10528{ 10529 uint32_t cnt; 10530 int rval; 10531 uint32_t size_to_offset; 10532 uint32_t size_to_compare; 10533 int erase_all; 10534 10535 if (CFG_IST(ha, CFG_CTRL_242581)) { 10536 return (ql_24xx_load_flash(ha, dp, size, 0)); 10537 } 10538 10539 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance); 10540 10541 size_to_compare = 0x20000; 10542 size_to_offset = 0; 10543 erase_all = 0; 10544 if (CFG_IST(ha, CFG_SBUS_CARD)) { 10545 if (size == 0x80000) { 10546 /* Request to flash the entire chip. */ 10547 size_to_compare = 0x80000; 10548 erase_all = 1; 10549 } else { 10550 size_to_compare = 0x40000; 10551 if (ql_flash_sbus_fpga) { 10552 size_to_offset = 0x40000; 10553 } 10554 } 10555 } 10556 if (size > size_to_compare) { 10557 rval = QL_FUNCTION_PARAMETER_ERROR; 10558 EL(ha, "failed=%xh\n", rval); 10559 return (rval); 10560 } 10561 10562 GLOBAL_HW_LOCK(); 10563 10564 /* Enable Flash Read/Write. */ 10565 ql_flash_enable(ha); 10566 10567 /* Erase flash prior to write. */ 10568 rval = ql_erase_flash(ha, erase_all); 10569 10570 if (rval == QL_SUCCESS) { 10571 /* Write data to flash. */ 10572 for (cnt = 0; cnt < size; cnt++) { 10573 /* Allow other system activity. */ 10574 if (cnt % 0x1000 == 0) { 10575 ql_delay(ha, 10000); 10576 } 10577 rval = ql_program_flash_address(ha, 10578 cnt + size_to_offset, *dp++); 10579 if (rval != QL_SUCCESS) { 10580 break; 10581 } 10582 } 10583 } 10584 10585 ql_flash_disable(ha); 10586 10587 GLOBAL_HW_UNLOCK(); 10588 10589 if (rval != QL_SUCCESS) { 10590 EL(ha, "failed=%xh\n", rval); 10591 } else { 10592 /*EMPTY*/ 10593 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance); 10594 } 10595 return (rval); 10596} 10597 10598/* 10599 * ql_program_flash_address 10600 * Program flash address. 10601 * 10602 * Input: 10603 * ha = adapter state pointer. 10604 * addr = flash byte address. 10605 * data = data to be written to flash. 10606 * 10607 * Returns: 10608 * ql local function return status code. 10609 * 10610 * Context: 10611 * Kernel context. 10612 */ 10613static int 10614ql_program_flash_address(ql_adapter_state_t *ha, uint32_t addr, uint8_t data) 10615{ 10616 int rval; 10617 10618 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance); 10619 10620 if (CFG_IST(ha, CFG_SBUS_CARD)) { 10621 ql_write_flash_byte(ha, 0x5555, 0xa0); 10622 ql_write_flash_byte(ha, addr, data); 10623 } else { 10624 /* Write Program Command Sequence */ 10625 ql_write_flash_byte(ha, 0x5555, 0xaa); 10626 ql_write_flash_byte(ha, 0x2aaa, 0x55); 10627 ql_write_flash_byte(ha, 0x5555, 0xa0); 10628 ql_write_flash_byte(ha, addr, data); 10629 } 10630 10631 /* Wait for write to complete. */ 10632 rval = ql_poll_flash(ha, addr, data); 10633 10634 if (rval != QL_SUCCESS) { 10635 EL(ha, "failed=%xh\n", rval); 10636 } else { 10637 /*EMPTY*/ 10638 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance); 10639 } 10640 return (rval); 10641} 10642 10643/* 10644 * ql_erase_flash 10645 * Erases entire flash. 10646 * 10647 * Input: 10648 * ha = adapter state pointer. 10649 * 10650 * Returns: 10651 * ql local function return status code. 10652 * 10653 * Context: 10654 * Kernel context. 10655 */ 10656int 10657ql_erase_flash(ql_adapter_state_t *ha, int erase_all) 10658{ 10659 int rval; 10660 uint32_t erase_delay = 2000000; 10661 uint32_t sStartAddr; 10662 uint32_t ssize; 10663 uint32_t cnt; 10664 uint8_t *bfp; 10665 uint8_t *tmp; 10666 10667 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance); 10668 10669 if ((CFG_IST(ha, CFG_SBUS_CARD)) && !erase_all) { 10670 10671 if (ql_flash_sbus_fpga == 1) { 10672 ssize = QL_SBUS_FCODE_SIZE; 10673 sStartAddr = QL_FCODE_OFFSET; 10674 } else { 10675 ssize = QL_FPGA_SIZE; 10676 sStartAddr = QL_FPGA_OFFSET; 10677 } 10678 10679 erase_delay = 20000000; 10680 10681 bfp = (uint8_t *)kmem_zalloc(ssize, KM_SLEEP); 10682 10683 /* Save the section of flash we're not updating to buffer */ 10684 tmp = bfp; 10685 for (cnt = sStartAddr; cnt < ssize+sStartAddr; cnt++) { 10686 /* Allow other system activity. */ 10687 if (cnt % 0x1000 == 0) { 10688 ql_delay(ha, 10000); 10689 } 10690 *tmp++ = (uint8_t)ql_read_flash_byte(ha, cnt); 10691 } 10692 } 10693 10694 /* Chip Erase Command Sequence */ 10695 ql_write_flash_byte(ha, 0x5555, 0xaa); 10696 ql_write_flash_byte(ha, 0x2aaa, 0x55); 10697 ql_write_flash_byte(ha, 0x5555, 0x80); 10698 ql_write_flash_byte(ha, 0x5555, 0xaa); 10699 ql_write_flash_byte(ha, 0x2aaa, 0x55); 10700 ql_write_flash_byte(ha, 0x5555, 0x10); 10701 10702 ql_delay(ha, erase_delay); 10703 10704 /* Wait for erase to complete. */ 10705 rval = ql_poll_flash(ha, 0, 0x80); 10706 10707 if (rval != QL_SUCCESS) { 10708 EL(ha, "failed=%xh\n", rval); 10709 if (CFG_IST(ha, CFG_SBUS_CARD)) { 10710 kmem_free(bfp, ssize); 10711 } 10712 return (rval); 10713 } 10714 10715 /* restore the section we saved in the buffer */ 10716 if ((CFG_IST(ha, CFG_SBUS_CARD)) && !erase_all) { 10717 /* Restore the section we saved off */ 10718 tmp = bfp; 10719 for (cnt = sStartAddr; cnt < ssize+sStartAddr; cnt++) { 10720 /* Allow other system activity. */ 10721 if (cnt % 0x1000 == 0) { 10722 ql_delay(ha, 10000); 10723 } 10724 rval = ql_program_flash_address(ha, cnt, *tmp++); 10725 if (rval != QL_SUCCESS) { 10726 break; 10727 } 10728 } 10729 10730 kmem_free(bfp, ssize); 10731 } 10732 10733 if (rval != QL_SUCCESS) { 10734 EL(ha, "failed=%xh\n", rval); 10735 } else { 10736 /*EMPTY*/ 10737 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance); 10738 } 10739 return (rval); 10740} 10741 10742/* 10743 * ql_poll_flash 10744 * Polls flash for completion. 10745 * 10746 * Input: 10747 * ha = adapter state pointer. 10748 * addr = flash byte address. 10749 * data = data to be polled. 10750 * 10751 * Returns: 10752 * ql local function return status code. 10753 * 10754 * Context: 10755 * Kernel context. 10756 */ 10757int 10758ql_poll_flash(ql_adapter_state_t *ha, uint32_t addr, uint8_t poll_data) 10759{ 10760 uint8_t flash_data; 10761 uint32_t cnt; 10762 int rval = QL_FUNCTION_FAILED; 10763 10764 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance); 10765 10766 poll_data = (uint8_t)(poll_data & BIT_7); 10767 10768 /* Wait for 30 seconds for command to finish. */ 10769 for (cnt = 30000000; cnt; cnt--) { 10770 flash_data = (uint8_t)ql_read_flash_byte(ha, addr); 10771 10772 if ((flash_data & BIT_7) == poll_data) { 10773 rval = QL_SUCCESS; 10774 break; 10775 } 10776 if (flash_data & BIT_5 && cnt > 2) { 10777 cnt = 2; 10778 } 10779 drv_usecwait(1); 10780 } 10781 10782 if (rval != QL_SUCCESS) { 10783 EL(ha, "failed=%xh\n", rval); 10784 } else { 10785 /*EMPTY*/ 10786 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance); 10787 } 10788 return (rval); 10789} 10790 10791/* 10792 * ql_flash_enable 10793 * Setup flash for reading/writing. 10794 * 10795 * Input: 10796 * ha = adapter state pointer. 10797 * 10798 * Context: 10799 * Kernel context. 10800 */ 10801void 10802ql_flash_enable(ql_adapter_state_t *ha) 10803{ 10804 uint16_t data; 10805 10806 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance); 10807 10808 /* Enable Flash Read/Write. */ 10809 if (CFG_IST(ha, CFG_SBUS_CARD)) { 10810 data = (uint16_t)ddi_get16(ha->sbus_fpga_dev_handle, 10811 (uint16_t *)(ha->sbus_fpga_iobase + FPGA_CONF)); 10812 data = (uint16_t)(data | SBUS_FLASH_WRITE_ENABLE); 10813 ddi_put16(ha->sbus_fpga_dev_handle, 10814 (uint16_t *)(ha->sbus_fpga_iobase + FPGA_CONF), data); 10815 /* Read reset command sequence */ 10816 ql_write_flash_byte(ha, 0xaaa, 0xaa); 10817 ql_write_flash_byte(ha, 0x555, 0x55); 10818 ql_write_flash_byte(ha, 0xaaa, 0x20); 10819 ql_write_flash_byte(ha, 0x555, 0xf0); 10820 } else { 10821 data = (uint16_t)(RD16_IO_REG(ha, ctrl_status) | 10822 ISP_FLASH_ENABLE); 10823 WRT16_IO_REG(ha, ctrl_status, data); 10824 10825 /* Read/Reset Command Sequence */ 10826 ql_write_flash_byte(ha, 0x5555, 0xaa); 10827 ql_write_flash_byte(ha, 0x2aaa, 0x55); 10828 ql_write_flash_byte(ha, 0x5555, 0xf0); 10829 } 10830 (void) ql_read_flash_byte(ha, 0); 10831 10832 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance); 10833} 10834 10835/* 10836 * ql_flash_disable 10837 * Disable flash and allow RISC to run. 10838 * 10839 * Input: 10840 * ha = adapter state pointer. 10841 * 10842 * Context: 10843 * Kernel context. 10844 */ 10845void 10846ql_flash_disable(ql_adapter_state_t *ha) 10847{ 10848 uint16_t data; 10849 10850 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance); 10851 10852 if (CFG_IST(ha, CFG_SBUS_CARD)) { 10853 /* 10854 * Lock the flash back up. 10855 */ 10856 ql_write_flash_byte(ha, 0x555, 0x90); 10857 ql_write_flash_byte(ha, 0x555, 0x0); 10858 10859 data = (uint16_t)ddi_get16(ha->sbus_fpga_dev_handle, 10860 (uint16_t *)(ha->sbus_fpga_iobase + FPGA_CONF)); 10861 data = (uint16_t)(data & ~SBUS_FLASH_WRITE_ENABLE); 10862 ddi_put16(ha->sbus_fpga_dev_handle, 10863 (uint16_t *)(ha->sbus_fpga_iobase + FPGA_CONF), data); 10864 } else { 10865 data = (uint16_t)(RD16_IO_REG(ha, ctrl_status) & 10866 ~ISP_FLASH_ENABLE); 10867 WRT16_IO_REG(ha, ctrl_status, data); 10868 } 10869 10870 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance); 10871} 10872 10873/* 10874 * ql_write_flash_byte 10875 * Write byte to flash. 10876 * 10877 * Input: 10878 * ha = adapter state pointer. 10879 * addr = flash byte address. 10880 * data = data to be written. 10881 * 10882 * Context: 10883 * Kernel context. 10884 */ 10885void 10886ql_write_flash_byte(ql_adapter_state_t *ha, uint32_t addr, uint8_t data) 10887{ 10888 if (CFG_IST(ha, CFG_SBUS_CARD)) { 10889 ddi_put16(ha->sbus_fpga_dev_handle, 10890 (uint16_t *)(ha->sbus_fpga_iobase + FPGA_EEPROM_LOADDR), 10891 LSW(addr)); 10892 ddi_put16(ha->sbus_fpga_dev_handle, 10893 (uint16_t *)(ha->sbus_fpga_iobase + FPGA_EEPROM_HIADDR), 10894 MSW(addr)); 10895 ddi_put16(ha->sbus_fpga_dev_handle, 10896 (uint16_t *)(ha->sbus_fpga_iobase + FPGA_EEPROM_DATA), 10897 (uint16_t)data); 10898 } else { 10899 uint16_t bank_select; 10900 10901 /* Setup bit 16 of flash address. */ 10902 bank_select = (uint16_t)RD16_IO_REG(ha, ctrl_status); 10903 10904 if (CFG_IST(ha, CFG_CTRL_6322)) { 10905 bank_select = (uint16_t)(bank_select & ~0xf0); 10906 bank_select = (uint16_t)(bank_select | 10907 ((addr >> 12 & 0xf0) | ISP_FLASH_64K_BANK)); 10908 WRT16_IO_REG(ha, ctrl_status, bank_select); 10909 } else { 10910 if (addr & BIT_16 && !(bank_select & 10911 ISP_FLASH_64K_BANK)) { 10912 bank_select = (uint16_t)(bank_select | 10913 ISP_FLASH_64K_BANK); 10914 WRT16_IO_REG(ha, ctrl_status, bank_select); 10915 } else if (!(addr & BIT_16) && bank_select & 10916 ISP_FLASH_64K_BANK) { 10917 bank_select = (uint16_t)(bank_select & 10918 ~ISP_FLASH_64K_BANK); 10919 WRT16_IO_REG(ha, ctrl_status, bank_select); 10920 } 10921 } 10922 10923 if (CFG_IST(ha, CFG_SBUS_CARD)) { 10924 WRT16_IO_REG(ha, flash_address, (uint16_t)addr); 10925 WRT16_IO_REG(ha, flash_data, (uint16_t)data); 10926 } else { 10927 WRT16_IOMAP_REG(ha, flash_address, addr); 10928 WRT16_IOMAP_REG(ha, flash_data, data); 10929 } 10930 } 10931} 10932 10933/* 10934 * ql_read_flash_byte 10935 * Reads byte from flash, but must read a word from chip. 10936 * 10937 * Input: 10938 * ha = adapter state pointer. 10939 * addr = flash byte address. 10940 * 10941 * Returns: 10942 * byte from flash. 10943 * 10944 * Context: 10945 * Kernel context. 10946 */ 10947uint8_t 10948ql_read_flash_byte(ql_adapter_state_t *ha, uint32_t addr) 10949{ 10950 uint8_t data; 10951 10952 if (CFG_IST(ha, CFG_SBUS_CARD)) { 10953 ddi_put16(ha->sbus_fpga_dev_handle, 10954 (uint16_t *)(ha->sbus_fpga_iobase + FPGA_EEPROM_LOADDR), 10955 LSW(addr)); 10956 ddi_put16(ha->sbus_fpga_dev_handle, 10957 (uint16_t *)(ha->sbus_fpga_iobase + FPGA_EEPROM_HIADDR), 10958 MSW(addr)); 10959 data = (uint8_t)ddi_get16(ha->sbus_fpga_dev_handle, 10960 (uint16_t *)(ha->sbus_fpga_iobase + FPGA_EEPROM_DATA)); 10961 } else { 10962 uint16_t bank_select; 10963 10964 /* Setup bit 16 of flash address. */ 10965 bank_select = RD16_IO_REG(ha, ctrl_status); 10966 if (CFG_IST(ha, CFG_CTRL_6322)) { 10967 bank_select = (uint16_t)(bank_select & ~0xf0); 10968 bank_select = (uint16_t)(bank_select | 10969 ((addr >> 12 & 0xf0) | ISP_FLASH_64K_BANK)); 10970 WRT16_IO_REG(ha, ctrl_status, bank_select); 10971 } else { 10972 if (addr & BIT_16 && 10973 !(bank_select & ISP_FLASH_64K_BANK)) { 10974 bank_select = (uint16_t)(bank_select | 10975 ISP_FLASH_64K_BANK); 10976 WRT16_IO_REG(ha, ctrl_status, bank_select); 10977 } else if (!(addr & BIT_16) && 10978 bank_select & ISP_FLASH_64K_BANK) { 10979 bank_select = (uint16_t)(bank_select & 10980 ~ISP_FLASH_64K_BANK); 10981 WRT16_IO_REG(ha, ctrl_status, bank_select); 10982 } 10983 } 10984 10985 if (CFG_IST(ha, CFG_SBUS_CARD)) { 10986 WRT16_IO_REG(ha, flash_address, addr); 10987 data = (uint8_t)RD16_IO_REG(ha, flash_data); 10988 } else { 10989 WRT16_IOMAP_REG(ha, flash_address, addr); 10990 data = (uint8_t)RD16_IOMAP_REG(ha, flash_data); 10991 } 10992 } 10993 10994 return (data); 10995} 10996 10997/* 10998 * ql_24xx_flash_id 10999 * Get flash IDs. 11000 * 11001 * Input: 11002 * ha: adapter state pointer. 11003 * 11004 * Returns: 11005 * ql local function return status code. 11006 * 11007 * Context: 11008 * Kernel context. 11009 */ 11010int 11011ql_24xx_flash_id(ql_adapter_state_t *vha) 11012{ 11013 int rval; 11014 uint32_t fdata = 0; 11015 ql_adapter_state_t *ha = vha->pha; 11016 ql_xioctl_t *xp = ha->xioctl; 11017 11018 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance); 11019 11020 rval = ql_24xx_read_flash(ha, FLASH_CONF_ADDR | 0x3AB, &fdata); 11021 11022 if (rval != QL_SUCCESS || fdata == 0 || CFG_IST(ha, CFG_CTRL_2581)) { 11023 fdata = 0; 11024 rval = ql_24xx_read_flash(ha, FLASH_CONF_ADDR | 11025 (CFG_IST(ha, CFG_CTRL_2422) ? 0x39F : 0x49F), &fdata); 11026 } 11027 11028 if (rval != QL_SUCCESS) { 11029 EL(ha, "24xx read_flash failed=%xh\n", rval); 11030 } else if (fdata != 0) { 11031 xp->fdesc.flash_manuf = LSB(LSW(fdata)); 11032 xp->fdesc.flash_id = MSB(LSW(fdata)); 11033 xp->fdesc.flash_len = LSB(MSW(fdata)); 11034 } else { 11035 xp->fdesc.flash_manuf = ATMEL_FLASH; 11036 xp->fdesc.flash_id = ATMEL_FLASHID_1024K; 11037 xp->fdesc.flash_len = 0; 11038 } 11039 11040 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance); 11041 11042 return (rval); 11043} 11044 11045/* 11046 * ql_24xx_load_flash 11047 * Loads flash. 11048 * 11049 * Input: 11050 * ha = adapter state pointer. 11051 * dp = data pointer. 11052 * size = data length in bytes. 11053 * faddr = 32bit word flash byte address. 11054 * 11055 * Returns: 11056 * ql local function return status code. 11057 * 11058 * Context: 11059 * Kernel context. 11060 */ 11061int 11062ql_24xx_load_flash(ql_adapter_state_t *vha, uint8_t *dp, uint32_t size, 11063 uint32_t faddr) 11064{ 11065 int rval; 11066 uint32_t cnt, rest_addr, fdata, wc; 11067 dma_mem_t dmabuf = {0}; 11068 ql_adapter_state_t *ha = vha->pha; 11069 ql_xioctl_t *xp = ha->xioctl; 11070 11071 QL_PRINT_3(CE_CONT, "(%d): started, faddr=%xh, size=%xh\n", 11072 ha->instance, faddr, size); 11073 11074 /* start address must be 32 bit word aligned */ 11075 if ((faddr & 0x3) != 0) { 11076 EL(ha, "incorrect buffer size alignment\n"); 11077 return (QL_FUNCTION_PARAMETER_ERROR); 11078 } 11079 11080 /* Allocate DMA buffer */ 11081 if (CFG_IST(ha, CFG_CTRL_2581)) { 11082 if ((rval = ql_get_dma_mem(ha, &dmabuf, 0xffff, 11083 LITTLE_ENDIAN_DMA, QL_DMA_DATA_ALIGN)) != 11084 QL_SUCCESS) { 11085 EL(ha, "dma alloc failed, rval=%xh\n", rval); 11086 return (rval); 11087 } 11088 } 11089 11090 GLOBAL_HW_LOCK(); 11091 11092 /* Enable flash write */ 11093 if ((rval = ql_24xx_unprotect_flash(ha)) != QL_SUCCESS) { 11094 GLOBAL_HW_UNLOCK(); 11095 EL(ha, "unprotect_flash failed, rval=%xh\n", rval); 11096 ql_free_phys(ha, &dmabuf); 11097 return (rval); 11098 } 11099 11100 /* setup mask of address range within a sector */ 11101 rest_addr = (xp->fdesc.block_size - 1) >> 2; 11102 11103 faddr = faddr >> 2; /* flash gets 32 bit words */ 11104 11105 /* 11106 * Write data to flash. 11107 */ 11108 cnt = 0; 11109 size = (size + 3) >> 2; /* Round up & convert to dwords */ 11110 11111 while (cnt < size) { 11112 /* Beginning of a sector? */ 11113 if ((faddr & rest_addr) == 0) { 11114 if (CFG_IST(ha, CFG_CTRL_81XX)) { 11115 fdata = ha->flash_data_addr | faddr; 11116 rval = ql_flash_access(ha, 11117 FAC_ERASE_SECTOR, fdata, fdata + 11118 rest_addr, 0); 11119 if (rval != QL_SUCCESS) { 11120 EL(ha, "erase sector status=" 11121 "%xh, start=%xh, end=%xh" 11122 "\n", rval, fdata, 11123 fdata + rest_addr); 11124 break; 11125 } 11126 } else { 11127 fdata = (faddr & ~rest_addr) << 2; 11128 fdata = (fdata & 0xff00) | 11129 (fdata << 16 & 0xff0000) | 11130 (fdata >> 16 & 0xff); 11131 11132 if (rest_addr == 0x1fff) { 11133 /* 32kb sector block erase */ 11134 rval = ql_24xx_write_flash(ha, 11135 FLASH_CONF_ADDR | 0x0352, 11136 fdata); 11137 } else { 11138 /* 64kb sector block erase */ 11139 rval = ql_24xx_write_flash(ha, 11140 FLASH_CONF_ADDR | 0x03d8, 11141 fdata); 11142 } 11143 if (rval != QL_SUCCESS) { 11144 EL(ha, "Unable to flash sector" 11145 ": address=%xh\n", faddr); 11146 break; 11147 } 11148 } 11149 } 11150 11151 /* Write data */ 11152 if (CFG_IST(ha, CFG_CTRL_2581) && 11153 ((faddr & 0x3f) == 0)) { 11154 /* 11155 * Limit write up to sector boundary. 11156 */ 11157 wc = ((~faddr & (rest_addr>>1)) + 1); 11158 11159 if (size - cnt < wc) { 11160 wc = size - cnt; 11161 } 11162 11163 ddi_rep_put8(dmabuf.acc_handle, (uint8_t *)dp, 11164 (uint8_t *)dmabuf.bp, wc<<2, 11165 DDI_DEV_AUTOINCR); 11166 11167 rval = ql_wrt_risc_ram(ha, ha->flash_data_addr | 11168 faddr, dmabuf.cookie.dmac_laddress, wc); 11169 if (rval != QL_SUCCESS) { 11170 EL(ha, "unable to dma to flash " 11171 "address=%xh\n", faddr << 2); 11172 break; 11173 } 11174 11175 cnt += wc; 11176 faddr += wc; 11177 dp += wc << 2; 11178 } else { 11179 fdata = *dp++; 11180 fdata |= *dp++ << 8; 11181 fdata |= *dp++ << 16; 11182 fdata |= *dp++ << 24; 11183 rval = ql_24xx_write_flash(ha, 11184 ha->flash_data_addr | faddr, fdata); 11185 if (rval != QL_SUCCESS) { 11186 EL(ha, "Unable to program flash " 11187 "address=%xh data=%xh\n", faddr, 11188 *dp); 11189 break; 11190 } 11191 cnt++; 11192 faddr++; 11193 11194 /* Allow other system activity. */ 11195 if (cnt % 0x1000 == 0) { 11196 ql_delay(ha, 10000); 11197 } 11198 } 11199 } 11200 11201 ql_24xx_protect_flash(ha); 11202 11203 ql_free_phys(ha, &dmabuf); 11204 11205 GLOBAL_HW_UNLOCK(); 11206 11207 if (rval != QL_SUCCESS) { 11208 EL(ha, "failed=%xh\n", rval); 11209 } else { 11210 /*EMPTY*/ 11211 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance); 11212 } 11213 return (rval); 11214} 11215 11216/* 11217 * ql_24xx_read_flash 11218 * Reads a 32bit word from ISP24xx NVRAM/FLASH. 11219 * 11220 * Input: 11221 * ha: adapter state pointer. 11222 * faddr: NVRAM/FLASH address. 11223 * bp: data pointer. 11224 * 11225 * Returns: 11226 * ql local function return status code. 11227 * 11228 * Context: 11229 * Kernel context. 11230 */ 11231int 11232ql_24xx_read_flash(ql_adapter_state_t *vha, uint32_t faddr, uint32_t *bp) 11233{ 11234 uint32_t timer; 11235 int rval = QL_SUCCESS; 11236 ql_adapter_state_t *ha = vha->pha; 11237 11238 /* Clear access error flag */ 11239 WRT32_IO_REG(ha, ctrl_status, 11240 RD32_IO_REG(ha, ctrl_status) | FLASH_NVRAM_ACCESS_ERROR); 11241 11242 WRT32_IO_REG(ha, flash_address, faddr & ~FLASH_DATA_FLAG); 11243 11244 /* Wait for READ cycle to complete. */ 11245 for (timer = 300000; timer; timer--) { 11246 if (RD32_IO_REG(ha, flash_address) & FLASH_DATA_FLAG) { 11247 break; 11248 } 11249 drv_usecwait(10); 11250 } 11251 11252 if (timer == 0) { 11253 EL(ha, "failed, timeout\n"); 11254 rval = QL_FUNCTION_TIMEOUT; 11255 } else if (RD32_IO_REG(ha, ctrl_status) & FLASH_NVRAM_ACCESS_ERROR) { 11256 EL(ha, "failed, access error\n"); 11257 rval = QL_FUNCTION_FAILED; 11258 } 11259 11260 *bp = RD32_IO_REG(ha, flash_data); 11261 11262 return (rval); 11263} 11264 11265/* 11266 * ql_24xx_write_flash 11267 * Writes a 32bit word to ISP24xx NVRAM/FLASH. 11268 * 11269 * Input: 11270 * ha: adapter state pointer. 11271 * addr: NVRAM/FLASH address. 11272 * value: data. 11273 * 11274 * Returns: 11275 * ql local function return status code. 11276 * 11277 * Context: 11278 * Kernel context. 11279 */ 11280int 11281ql_24xx_write_flash(ql_adapter_state_t *vha, uint32_t addr, uint32_t data) 11282{ 11283 uint32_t timer, fdata; 11284 int rval = QL_SUCCESS; 11285 ql_adapter_state_t *ha = vha->pha; 11286 11287 /* Clear access error flag */ 11288 WRT32_IO_REG(ha, ctrl_status, 11289 RD32_IO_REG(ha, ctrl_status) | FLASH_NVRAM_ACCESS_ERROR); 11290 11291 WRT32_IO_REG(ha, flash_data, data); 11292 RD32_IO_REG(ha, flash_data); /* PCI Posting. */ 11293 WRT32_IO_REG(ha, flash_address, addr | FLASH_DATA_FLAG); 11294 11295 /* Wait for Write cycle to complete. */ 11296 for (timer = 3000000; timer; timer--) { 11297 if ((RD32_IO_REG(ha, flash_address) & FLASH_DATA_FLAG) == 0) { 11298 /* Check flash write in progress. */ 11299 if ((addr & FLASH_ADDR_MASK) == FLASH_CONF_ADDR) { 11300 (void) ql_24xx_read_flash(ha, 11301 FLASH_CONF_ADDR | 0x005, &fdata); 11302 if (!(fdata & BIT_0)) { 11303 break; 11304 } 11305 } else { 11306 break; 11307 } 11308 } 11309 drv_usecwait(10); 11310 } 11311 if (timer == 0) { 11312 EL(ha, "failed, timeout\n"); 11313 rval = QL_FUNCTION_TIMEOUT; 11314 } else if (RD32_IO_REG(ha, ctrl_status) & FLASH_NVRAM_ACCESS_ERROR) { 11315 EL(ha, "access error\n"); 11316 rval = QL_FUNCTION_FAILED; 11317 } 11318 11319 return (rval); 11320} 11321/* 11322 * ql_24xx_unprotect_flash 11323 * Enable writes 11324 * 11325 * Input: 11326 * ha: adapter state pointer. 11327 * 11328 * Returns: 11329 * ql local function return status code. 11330 * 11331 * Context: 11332 * Kernel context. 11333 */ 11334int 11335ql_24xx_unprotect_flash(ql_adapter_state_t *vha) 11336{ 11337 int rval; 11338 uint32_t fdata; 11339 ql_adapter_state_t *ha = vha->pha; 11340 ql_xioctl_t *xp = ha->xioctl; 11341 11342 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance); 11343 11344 if (CFG_IST(ha, CFG_CTRL_81XX)) { 11345 if (ha->task_daemon_flags & FIRMWARE_UP) { 11346 if ((rval = ql_flash_access(ha, FAC_WRT_ENABLE, 0, 0, 11347 0)) != QL_SUCCESS) { 11348 EL(ha, "status=%xh\n", rval); 11349 } 11350 QL_PRINT_3(CE_CONT, "(%d): 8100 done\n", 11351 ha->instance); 11352 return (rval); 11353 } 11354 } else { 11355 /* Enable flash write. */ 11356 WRT32_IO_REG(ha, ctrl_status, 11357 RD32_IO_REG(ha, ctrl_status) | ISP_FLASH_ENABLE); 11358 RD32_IO_REG(ha, ctrl_status); /* PCI Posting. */ 11359 } 11360 11361 /* 11362 * Remove block write protection (SST and ST) and 11363 * Sector/Block Protection Register Lock (SST, ST, ATMEL). 11364 * Unprotect sectors. 11365 */ 11366 (void) ql_24xx_write_flash(ha, FLASH_CONF_ADDR | 0x100 | 11367 xp->fdesc.write_statusreg_cmd, xp->fdesc.write_enable_bits); 11368 11369 if (xp->fdesc.unprotect_sector_cmd != 0) { 11370 for (fdata = 0; fdata < 0x10; fdata++) { 11371 (void) ql_24xx_write_flash(ha, FLASH_CONF_ADDR | 11372 0x300 | xp->fdesc.unprotect_sector_cmd, fdata); 11373 } 11374 11375 (void) ql_24xx_write_flash(ha, FLASH_CONF_ADDR | 0x300 | 11376 xp->fdesc.unprotect_sector_cmd, 0x00400f); 11377 (void) ql_24xx_write_flash(ha, FLASH_CONF_ADDR | 0x300 | 11378 xp->fdesc.unprotect_sector_cmd, 0x00600f); 11379 (void) ql_24xx_write_flash(ha, FLASH_CONF_ADDR | 0x300 | 11380 xp->fdesc.unprotect_sector_cmd, 0x00800f); 11381 } 11382 11383 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance); 11384 11385 return (QL_SUCCESS); 11386} 11387 11388/* 11389 * ql_24xx_protect_flash 11390 * Disable writes 11391 * 11392 * Input: 11393 * ha: adapter state pointer. 11394 * 11395 * Context: 11396 * Kernel context. 11397 */ 11398void 11399ql_24xx_protect_flash(ql_adapter_state_t *vha) 11400{ 11401 int rval; 11402 uint32_t fdata; 11403 ql_adapter_state_t *ha = vha->pha; 11404 ql_xioctl_t *xp = ha->xioctl; 11405 11406 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance); 11407 11408 if (CFG_IST(ha, CFG_CTRL_81XX)) { 11409 if (ha->task_daemon_flags & FIRMWARE_UP) { 11410 if ((rval = ql_flash_access(ha, FAC_WRT_PROTECT, 0, 0, 11411 0)) != QL_SUCCESS) { 11412 EL(ha, "status=%xh\n", rval); 11413 } 11414 QL_PRINT_3(CE_CONT, "(%d): 8100 done\n", 11415 ha->instance); 11416 return; 11417 } 11418 } else { 11419 /* Enable flash write. */ 11420 WRT32_IO_REG(ha, ctrl_status, 11421 RD32_IO_REG(ha, ctrl_status) | ISP_FLASH_ENABLE); 11422 RD32_IO_REG(ha, ctrl_status); /* PCI Posting. */ 11423 } 11424 11425 /* 11426 * Protect sectors. 11427 * Set block write protection (SST and ST) and 11428 * Sector/Block Protection Register Lock (SST, ST, ATMEL). 11429 */ 11430 if (xp->fdesc.protect_sector_cmd != 0) { 11431 for (fdata = 0; fdata < 0x10; fdata++) { 11432 (void) ql_24xx_write_flash(ha, FLASH_CONF_ADDR | 11433 0x330 | xp->fdesc.protect_sector_cmd, fdata); 11434 } 11435 (void) ql_24xx_write_flash(ha, FLASH_CONF_ADDR | 0x330 | 11436 xp->fdesc.protect_sector_cmd, 0x00400f); 11437 (void) ql_24xx_write_flash(ha, FLASH_CONF_ADDR | 0x330 | 11438 xp->fdesc.protect_sector_cmd, 0x00600f); 11439 (void) ql_24xx_write_flash(ha, FLASH_CONF_ADDR | 0x330 | 11440 xp->fdesc.protect_sector_cmd, 0x00800f); 11441 11442 /* TODO: ??? */ 11443 (void) ql_24xx_write_flash(ha, 11444 FLASH_CONF_ADDR | 0x101, 0x80); 11445 } else { 11446 (void) ql_24xx_write_flash(ha, 11447 FLASH_CONF_ADDR | 0x101, 0x9c); 11448 } 11449 11450 /* Disable flash write. */ 11451 if (!(CFG_IST(ha, CFG_CTRL_81XX))) { 11452 WRT32_IO_REG(ha, ctrl_status, 11453 RD32_IO_REG(ha, ctrl_status) & ~ISP_FLASH_ENABLE); 11454 RD32_IO_REG(ha, ctrl_status); /* PCI Posting. */ 11455 } 11456 11457 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance); 11458} 11459 11460/* 11461 * ql_dump_firmware 11462 * Save RISC code state information. 11463 * 11464 * Input: 11465 * ha = adapter state pointer. 11466 * 11467 * Returns: 11468 * QL local function return status code. 11469 * 11470 * Context: 11471 * Kernel context. 11472 */ 11473static int 11474ql_dump_firmware(ql_adapter_state_t *vha) 11475{ 11476 int rval; 11477 clock_t timer; 11478 ql_adapter_state_t *ha = vha->pha; 11479 11480 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance); 11481 11482 QL_DUMP_LOCK(ha); 11483 11484 if (ha->ql_dump_state & QL_DUMPING || 11485 (ha->ql_dump_state & QL_DUMP_VALID && 11486 !(ha->ql_dump_state & QL_DUMP_UPLOADED))) { 11487 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance); 11488 QL_DUMP_UNLOCK(ha); 11489 return (QL_SUCCESS); 11490 } 11491 11492 QL_DUMP_UNLOCK(ha); 11493 11494 ql_awaken_task_daemon(ha, NULL, DRIVER_STALL, 0); 11495 11496 /* 11497 * Wait for all outstanding commands to complete 11498 */ 11499 (void) ql_wait_outstanding(ha); 11500 11501 /* Dump firmware. */ 11502 rval = ql_binary_fw_dump(ha, TRUE); 11503 11504 /* Do abort to force restart. */ 11505 ql_awaken_task_daemon(ha, NULL, ISP_ABORT_NEEDED, DRIVER_STALL); 11506 EL(ha, "restarting, isp_abort_needed\n"); 11507 11508 /* Acquire task daemon lock. */ 11509 TASK_DAEMON_LOCK(ha); 11510 11511 /* Wait for suspension to end. */ 11512 while (ha->task_daemon_flags & QL_SUSPENDED) { 11513 ha->task_daemon_flags |= SUSPENDED_WAKEUP_FLG; 11514 11515 /* 30 seconds from now */ 11516 timer = ddi_get_lbolt(); 11517 timer += drv_usectohz(30000000); 11518 11519 if (cv_timedwait(&ha->cv_dr_suspended, 11520 &ha->task_daemon_mutex, timer) == -1) { 11521 /* 11522 * The timeout time 'timer' was 11523 * reached without the condition 11524 * being signaled. 11525 */ 11526 break; 11527 } 11528 } 11529 11530 /* Release task daemon lock. */ 11531 TASK_DAEMON_UNLOCK(ha); 11532 11533 if (rval == QL_SUCCESS || rval == QL_DATA_EXISTS) { 11534 /*EMPTY*/ 11535 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance); 11536 } else { 11537 EL(ha, "failed, rval = %xh\n", rval); 11538 } 11539 return (rval); 11540} 11541 11542/* 11543 * ql_binary_fw_dump 11544 * Dumps binary data from firmware. 11545 * 11546 * Input: 11547 * ha = adapter state pointer. 11548 * lock_needed = mailbox lock needed. 11549 * 11550 * Returns: 11551 * ql local function return status code. 11552 * 11553 * Context: 11554 * Interrupt or Kernel context, no mailbox commands allowed. 11555 */ 11556int 11557ql_binary_fw_dump(ql_adapter_state_t *vha, int lock_needed) 11558{ 11559 clock_t timer; 11560 mbx_cmd_t mc; 11561 mbx_cmd_t *mcp = &mc; 11562 int rval = QL_SUCCESS; 11563 ql_adapter_state_t *ha = vha->pha; 11564 11565 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance); 11566 11567 QL_DUMP_LOCK(ha); 11568 11569 if (ha->ql_dump_state & QL_DUMPING || 11570 (ha->ql_dump_state & QL_DUMP_VALID && 11571 !(ha->ql_dump_state & QL_DUMP_UPLOADED))) { 11572 EL(ha, "dump already done, qds=%x\n", ha->ql_dump_state); 11573 QL_DUMP_UNLOCK(ha); 11574 return (QL_DATA_EXISTS); 11575 } 11576 11577 ha->ql_dump_state &= ~(QL_DUMP_VALID | QL_DUMP_UPLOADED); 11578 ha->ql_dump_state |= QL_DUMPING; 11579 11580 QL_DUMP_UNLOCK(ha); 11581 11582 if (CFG_IST(ha, CFG_ENABLE_FWEXTTRACE)) { 11583 11584 /* Insert Time Stamp */ 11585 rval = ql_fw_etrace(ha, &ha->fwexttracebuf, 11586 FTO_INSERT_TIME_STAMP); 11587 if (rval != QL_SUCCESS) { 11588 EL(ha, "f/w extended trace insert" 11589 "time stamp failed: %xh\n", rval); 11590 } 11591 } 11592 11593 if (lock_needed == TRUE) { 11594 /* Acquire mailbox register lock. */ 11595 MBX_REGISTER_LOCK(ha); 11596 11597 /* Check for mailbox available, if not wait for signal. */ 11598 while (ha->mailbox_flags & MBX_BUSY_FLG) { 11599 ha->mailbox_flags = (uint8_t) 11600 (ha->mailbox_flags | MBX_WANT_FLG); 11601 11602 /* 30 seconds from now */ 11603 timer = ddi_get_lbolt(); 11604 timer += (ha->mcp->timeout + 2) * 11605 drv_usectohz(1000000); 11606 if (cv_timedwait(&ha->cv_mbx_wait, &ha->mbx_mutex, 11607 timer) == -1) { 11608 /* 11609 * The timeout time 'timer' was 11610 * reached without the condition 11611 * being signaled. 11612 */ 11613 11614 /* Release mailbox register lock. */ 11615 MBX_REGISTER_UNLOCK(ha); 11616 11617 EL(ha, "failed, rval = %xh\n", 11618 QL_FUNCTION_TIMEOUT); 11619 return (QL_FUNCTION_TIMEOUT); 11620 } 11621 } 11622 11623 /* Set busy flag. */ 11624 ha->mailbox_flags = (uint8_t) 11625 (ha->mailbox_flags | MBX_BUSY_FLG); 11626 mcp->timeout = 120; 11627 ha->mcp = mcp; 11628 11629 /* Release mailbox register lock. */ 11630 MBX_REGISTER_UNLOCK(ha); 11631 } 11632 11633 /* Free previous dump buffer. */ 11634 if (ha->ql_dump_ptr != NULL) { 11635 kmem_free(ha->ql_dump_ptr, ha->ql_dump_size); 11636 ha->ql_dump_ptr = NULL; 11637 } 11638 11639 if (CFG_IST(ha, CFG_CTRL_2422)) { 11640 ha->ql_dump_size = (uint32_t)(sizeof (ql_24xx_fw_dump_t) + 11641 ha->fw_ext_memory_size); 11642 } else if (CFG_IST(ha, CFG_CTRL_25XX)) { 11643 ha->ql_dump_size = (uint32_t)(sizeof (ql_25xx_fw_dump_t) + 11644 ha->fw_ext_memory_size); 11645 } else if (CFG_IST(ha, CFG_CTRL_81XX)) { 11646 ha->ql_dump_size = (uint32_t)(sizeof (ql_81xx_fw_dump_t) + 11647 ha->fw_ext_memory_size); 11648 } else { 11649 ha->ql_dump_size = sizeof (ql_fw_dump_t); 11650 } 11651 11652 if ((ha->ql_dump_ptr = kmem_zalloc(ha->ql_dump_size, KM_NOSLEEP)) == 11653 NULL) { 11654 rval = QL_MEMORY_ALLOC_FAILED; 11655 } else { 11656 if (CFG_IST(ha, (CFG_CTRL_2300 | CFG_CTRL_6322))) { 11657 rval = ql_2300_binary_fw_dump(ha, ha->ql_dump_ptr); 11658 } else if (CFG_IST(ha, CFG_CTRL_81XX)) { 11659 rval = ql_81xx_binary_fw_dump(ha, ha->ql_dump_ptr); 11660 } else if (CFG_IST(ha, CFG_CTRL_25XX)) { 11661 rval = ql_25xx_binary_fw_dump(ha, ha->ql_dump_ptr); 11662 } else if (CFG_IST(ha, CFG_CTRL_2422)) { 11663 rval = ql_24xx_binary_fw_dump(ha, ha->ql_dump_ptr); 11664 } else { 11665 rval = ql_2200_binary_fw_dump(ha, ha->ql_dump_ptr); 11666 } 11667 } 11668 11669 /* Reset ISP chip. */ 11670 ql_reset_chip(ha); 11671 11672 QL_DUMP_LOCK(ha); 11673 11674 if (rval != QL_SUCCESS) { 11675 if (ha->ql_dump_ptr != NULL) { 11676 kmem_free(ha->ql_dump_ptr, ha->ql_dump_size); 11677 ha->ql_dump_ptr = NULL; 11678 } 11679 ha->ql_dump_state &= ~(QL_DUMPING | QL_DUMP_VALID | 11680 QL_DUMP_UPLOADED); 11681 EL(ha, "failed, rval = %xh\n", rval); 11682 } else { 11683 ha->ql_dump_state &= ~(QL_DUMPING | QL_DUMP_UPLOADED); 11684 ha->ql_dump_state |= QL_DUMP_VALID; 11685 EL(ha, "done\n"); 11686 } 11687 11688 QL_DUMP_UNLOCK(ha); 11689 11690 return (rval); 11691} 11692 11693/* 11694 * ql_ascii_fw_dump 11695 * Converts firmware binary dump to ascii. 11696 * 11697 * Input: 11698 * ha = adapter state pointer. 11699 * bptr = buffer pointer. 11700 * 11701 * Returns: 11702 * Amount of data buffer used. 11703 * 11704 * Context: 11705 * Kernel context. 11706 */ 11707size_t 11708ql_ascii_fw_dump(ql_adapter_state_t *vha, caddr_t bufp) 11709{ 11710 uint32_t cnt; 11711 caddr_t bp; 11712 int mbox_cnt; 11713 ql_adapter_state_t *ha = vha->pha; 11714 ql_fw_dump_t *fw = ha->ql_dump_ptr; 11715 11716 if (CFG_IST(ha, CFG_CTRL_2422)) { 11717 return (ql_24xx_ascii_fw_dump(ha, bufp)); 11718 } else if (CFG_IST(ha, CFG_CTRL_2581)) { 11719 return (ql_2581_ascii_fw_dump(ha, bufp)); 11720 } 11721 11722 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance); 11723 11724 if (CFG_IST(ha, CFG_CTRL_2300)) { 11725 (void) sprintf(bufp, "\nISP 2300IP "); 11726 } else if (CFG_IST(ha, CFG_CTRL_6322)) { 11727 (void) sprintf(bufp, "\nISP 6322FLX "); 11728 } else { 11729 (void) sprintf(bufp, "\nISP 2200IP "); 11730 } 11731 11732 bp = bufp + strlen(bufp); 11733 (void) sprintf(bp, "Firmware Version %d.%d.%d\n", 11734 ha->fw_major_version, ha->fw_minor_version, 11735 ha->fw_subminor_version); 11736 11737 (void) strcat(bufp, "\nPBIU Registers:"); 11738 bp = bufp + strlen(bufp); 11739 for (cnt = 0; cnt < sizeof (fw->pbiu_reg) / 2; cnt++) { 11740 if (cnt % 8 == 0) { 11741 *bp++ = '\n'; 11742 } 11743 (void) sprintf(bp, "%04x ", fw->pbiu_reg[cnt]); 11744 bp = bp + 6; 11745 } 11746 11747 if (CFG_IST(ha, (CFG_CTRL_2300 | CFG_CTRL_6322))) { 11748 (void) strcat(bufp, "\n\nReqQ-RspQ-Risc2Host Status " 11749 "registers:"); 11750 bp = bufp + strlen(bufp); 11751 for (cnt = 0; cnt < sizeof (fw->risc_host_reg) / 2; cnt++) { 11752 if (cnt % 8 == 0) { 11753 *bp++ = '\n'; 11754 } 11755 (void) sprintf(bp, "%04x ", fw->risc_host_reg[cnt]); 11756 bp = bp + 6; 11757 } 11758 } 11759 11760 (void) strcat(bp, "\n\nMailbox Registers:"); 11761 bp = bufp + strlen(bufp); 11762 mbox_cnt = (CFG_IST(ha, (CFG_CTRL_2300 | CFG_CTRL_6322))) ? 16 : 8; 11763 for (cnt = 0; cnt < mbox_cnt; cnt++) { 11764 if (cnt % 8 == 0) { 11765 *bp++ = '\n'; 11766 } 11767 (void) sprintf(bp, "%04x ", fw->mailbox_reg[cnt]); 11768 bp = bp + 6; 11769 } 11770 11771 if (CFG_IST(ha, (CFG_CTRL_2300 | CFG_CTRL_6322))) { 11772 (void) strcat(bp, "\n\nAuto Request Response DMA Registers:"); 11773 bp = bufp + strlen(bufp); 11774 for (cnt = 0; cnt < sizeof (fw->resp_dma_reg) / 2; cnt++) { 11775 if (cnt % 8 == 0) { 11776 *bp++ = '\n'; 11777 } 11778 (void) sprintf(bp, "%04x ", fw->resp_dma_reg[cnt]); 11779 bp = bp + 6; 11780 } 11781 } 11782 11783 (void) strcat(bp, "\n\nDMA Registers:"); 11784 bp = bufp + strlen(bufp); 11785 for (cnt = 0; cnt < sizeof (fw->dma_reg) / 2; cnt++) { 11786 if (cnt % 8 == 0) { 11787 *bp++ = '\n'; 11788 } 11789 (void) sprintf(bp, "%04x ", fw->dma_reg[cnt]); 11790 bp = bp + 6; 11791 } 11792 11793 (void) strcat(bp, "\n\nRISC Hardware Registers:"); 11794 bp = bufp + strlen(bufp); 11795 for (cnt = 0; cnt < sizeof (fw->risc_hdw_reg) / 2; cnt++) { 11796 if (cnt % 8 == 0) { 11797 *bp++ = '\n'; 11798 } 11799 (void) sprintf(bp, "%04x ", fw->risc_hdw_reg[cnt]); 11800 bp = bp + 6; 11801 } 11802 11803 (void) strcat(bp, "\n\nRISC GP0 Registers:"); 11804 bp = bufp + strlen(bufp); 11805 for (cnt = 0; cnt < sizeof (fw->risc_gp0_reg) / 2; cnt++) { 11806 if (cnt % 8 == 0) { 11807 *bp++ = '\n'; 11808 } 11809 (void) sprintf(bp, "%04x ", fw->risc_gp0_reg[cnt]); 11810 bp = bp + 6; 11811 } 11812 11813 (void) strcat(bp, "\n\nRISC GP1 Registers:"); 11814 bp = bufp + strlen(bufp); 11815 for (cnt = 0; cnt < sizeof (fw->risc_gp1_reg) / 2; cnt++) { 11816 if (cnt % 8 == 0) { 11817 *bp++ = '\n'; 11818 } 11819 (void) sprintf(bp, "%04x ", fw->risc_gp1_reg[cnt]); 11820 bp = bp + 6; 11821 } 11822 11823 (void) strcat(bp, "\n\nRISC GP2 Registers:"); 11824 bp = bufp + strlen(bufp); 11825 for (cnt = 0; cnt < sizeof (fw->risc_gp2_reg) / 2; cnt++) { 11826 if (cnt % 8 == 0) { 11827 *bp++ = '\n'; 11828 } 11829 (void) sprintf(bp, "%04x ", fw->risc_gp2_reg[cnt]); 11830 bp = bp + 6; 11831 } 11832 11833 (void) strcat(bp, "\n\nRISC GP3 Registers:"); 11834 bp = bufp + strlen(bufp); 11835 for (cnt = 0; cnt < sizeof (fw->risc_gp3_reg) / 2; cnt++) { 11836 if (cnt % 8 == 0) { 11837 *bp++ = '\n'; 11838 } 11839 (void) sprintf(bp, "%04x ", fw->risc_gp3_reg[cnt]); 11840 bp = bp + 6; 11841 } 11842 11843 (void) strcat(bp, "\n\nRISC GP4 Registers:"); 11844 bp = bufp + strlen(bufp); 11845 for (cnt = 0; cnt < sizeof (fw->risc_gp4_reg) / 2; cnt++) { 11846 if (cnt % 8 == 0) { 11847 *bp++ = '\n'; 11848 } 11849 (void) sprintf(bp, "%04x ", fw->risc_gp4_reg[cnt]); 11850 bp = bp + 6; 11851 } 11852 11853 (void) strcat(bp, "\n\nRISC GP5 Registers:"); 11854 bp = bufp + strlen(bufp); 11855 for (cnt = 0; cnt < sizeof (fw->risc_gp5_reg) / 2; cnt++) { 11856 if (cnt % 8 == 0) { 11857 *bp++ = '\n'; 11858 } 11859 (void) sprintf(bp, "%04x ", fw->risc_gp5_reg[cnt]); 11860 bp = bp + 6; 11861 } 11862 11863 (void) strcat(bp, "\n\nRISC GP6 Registers:"); 11864 bp = bufp + strlen(bufp); 11865 for (cnt = 0; cnt < sizeof (fw->risc_gp6_reg) / 2; cnt++) { 11866 if (cnt % 8 == 0) { 11867 *bp++ = '\n'; 11868 } 11869 (void) sprintf(bp, "%04x ", fw->risc_gp6_reg[cnt]); 11870 bp = bp + 6; 11871 } 11872 11873 (void) strcat(bp, "\n\nRISC GP7 Registers:"); 11874 bp = bufp + strlen(bufp); 11875 for (cnt = 0; cnt < sizeof (fw->risc_gp7_reg) / 2; cnt++) { 11876 if (cnt % 8 == 0) { 11877 *bp++ = '\n'; 11878 } 11879 (void) sprintf(bp, "%04x ", fw->risc_gp7_reg[cnt]); 11880 bp = bp + 6; 11881 } 11882 11883 (void) strcat(bp, "\n\nFrame Buffer Hardware Registers:"); 11884 bp = bufp + strlen(bufp); 11885 for (cnt = 0; cnt < sizeof (fw->frame_buf_hdw_reg) / 2; cnt++) { 11886 if ((cnt == 16) && ((CFG_IST(ha, (CFG_CTRL_2300 | 11887 CFG_CTRL_6322)) == 0))) { 11888 break; 11889 } 11890 if (cnt % 8 == 0) { 11891 *bp++ = '\n'; 11892 } 11893 (void) sprintf(bp, "%04x ", fw->frame_buf_hdw_reg[cnt]); 11894 bp = bp + 6; 11895 } 11896 11897 (void) strcat(bp, "\n\nFPM B0 Registers:"); 11898 bp = bufp + strlen(bufp); 11899 for (cnt = 0; cnt < sizeof (fw->fpm_b0_reg) / 2; cnt++) { 11900 if (cnt % 8 == 0) { 11901 *bp++ = '\n'; 11902 } 11903 (void) sprintf(bp, "%04x ", fw->fpm_b0_reg[cnt]); 11904 bp = bp + 6; 11905 } 11906 11907 (void) strcat(bp, "\n\nFPM B1 Registers:"); 11908 bp = bufp + strlen(bufp); 11909 for (cnt = 0; cnt < sizeof (fw->fpm_b1_reg) / 2; cnt++) { 11910 if (cnt % 8 == 0) { 11911 *bp++ = '\n'; 11912 } 11913 (void) sprintf(bp, "%04x ", fw->fpm_b1_reg[cnt]); 11914 bp = bp + 6; 11915 } 11916 11917 if (CFG_IST(ha, (CFG_CTRL_2300 | CFG_CTRL_6322))) { 11918 (void) strcat(bp, "\n\nCode RAM Dump:"); 11919 bp = bufp + strlen(bufp); 11920 for (cnt = 0; cnt < sizeof (fw->risc_ram) / 2; cnt++) { 11921 if (cnt % 8 == 0) { 11922 (void) sprintf(bp, "\n%05x: ", cnt + 0x0800); 11923 bp = bp + 8; 11924 } 11925 (void) sprintf(bp, "%04x ", fw->risc_ram[cnt]); 11926 bp = bp + 6; 11927 } 11928 11929 (void) strcat(bp, "\n\nStack RAM Dump:"); 11930 bp = bufp + strlen(bufp); 11931 for (cnt = 0; cnt < sizeof (fw->stack_ram) / 2; cnt++) { 11932 if (cnt % 8 == 0) { 11933 (void) sprintf(bp, "\n%05x: ", cnt + 0x010000); 11934 bp = bp + 8; 11935 } 11936 (void) sprintf(bp, "%04x ", fw->stack_ram[cnt]); 11937 bp = bp + 6; 11938 } 11939 11940 (void) strcat(bp, "\n\nData RAM Dump:"); 11941 bp = bufp + strlen(bufp); 11942 for (cnt = 0; cnt < sizeof (fw->data_ram) / 2; cnt++) { 11943 if (cnt % 8 == 0) { 11944 (void) sprintf(bp, "\n%05x: ", cnt + 0x010800); 11945 bp = bp + 8; 11946 } 11947 (void) sprintf(bp, "%04x ", fw->data_ram[cnt]); 11948 bp = bp + 6; 11949 } 11950 } else { 11951 (void) strcat(bp, "\n\nRISC SRAM:"); 11952 bp = bufp + strlen(bufp); 11953 for (cnt = 0; cnt < 0xf000; cnt++) { 11954 if (cnt % 8 == 0) { 11955 (void) sprintf(bp, "\n%04x: ", cnt + 0x1000); 11956 bp = bp + 7; 11957 } 11958 (void) sprintf(bp, "%04x ", fw->risc_ram[cnt]); 11959 bp = bp + 6; 11960 } 11961 } 11962 11963 (void) strcat(bp, "\n\n[<==END] ISP Debug Dump."); 11964 bp += strlen(bp); 11965 11966 (void) sprintf(bp, "\n\nRequest Queue"); 11967 bp += strlen(bp); 11968 for (cnt = 0; cnt < REQUEST_QUEUE_SIZE / 4; cnt++) { 11969 if (cnt % 8 == 0) { 11970 (void) sprintf(bp, "\n%08x: ", cnt); 11971 bp += strlen(bp); 11972 } 11973 (void) sprintf(bp, "%08x ", fw->req_q[cnt]); 11974 bp += strlen(bp); 11975 } 11976 11977 (void) sprintf(bp, "\n\nResponse Queue"); 11978 bp += strlen(bp); 11979 for (cnt = 0; cnt < RESPONSE_QUEUE_SIZE / 4; cnt++) { 11980 if (cnt % 8 == 0) { 11981 (void) sprintf(bp, "\n%08x: ", cnt); 11982 bp += strlen(bp); 11983 } 11984 (void) sprintf(bp, "%08x ", fw->rsp_q[cnt]); 11985 bp += strlen(bp); 11986 } 11987 11988 (void) sprintf(bp, "\n"); 11989 11990 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance); 11991 11992 return (strlen(bufp)); 11993} 11994 11995/* 11996 * ql_24xx_ascii_fw_dump 11997 * Converts ISP24xx firmware binary dump to ascii. 11998 * 11999 * Input: 12000 * ha = adapter state pointer. 12001 * bptr = buffer pointer. 12002 * 12003 * Returns: 12004 * Amount of data buffer used. 12005 * 12006 * Context: 12007 * Kernel context. 12008 */ 12009static size_t 12010ql_24xx_ascii_fw_dump(ql_adapter_state_t *ha, caddr_t bufp) 12011{ 12012 uint32_t cnt; 12013 caddr_t bp = bufp; 12014 ql_24xx_fw_dump_t *fw = ha->ql_dump_ptr; 12015 12016 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance); 12017 12018 (void) sprintf(bp, "ISP FW Version %d.%02d.%02d Attributes %X\n", 12019 ha->fw_major_version, ha->fw_minor_version, 12020 ha->fw_subminor_version, ha->fw_attributes); 12021 bp += strlen(bp); 12022 12023 (void) sprintf(bp, "\nHCCR Register\n%08x\n", fw->hccr); 12024 12025 (void) strcat(bp, "\nHost Interface Registers"); 12026 bp += strlen(bp); 12027 for (cnt = 0; cnt < sizeof (fw->host_reg) / 4; cnt++) { 12028 if (cnt % 8 == 0) { 12029 (void) sprintf(bp++, "\n"); 12030 } 12031 12032 (void) sprintf(bp, "%08x ", fw->host_reg[cnt]); 12033 bp += 9; 12034 } 12035 12036 (void) sprintf(bp, "\n\nMailbox Registers"); 12037 bp += strlen(bp); 12038 for (cnt = 0; cnt < sizeof (fw->mailbox_reg) / 2; cnt++) { 12039 if (cnt % 16 == 0) { 12040 (void) sprintf(bp++, "\n"); 12041 } 12042 12043 (void) sprintf(bp, "%04x ", fw->mailbox_reg[cnt]); 12044 bp += 5; 12045 } 12046 12047 (void) sprintf(bp, "\n\nXSEQ GP Registers"); 12048 bp += strlen(bp); 12049 for (cnt = 0; cnt < sizeof (fw->xseq_gp_reg) / 4; cnt++) { 12050 if (cnt % 8 == 0) { 12051 (void) sprintf(bp++, "\n"); 12052 } 12053 12054 (void) sprintf(bp, "%08x ", fw->xseq_gp_reg[cnt]); 12055 bp += 9; 12056 } 12057 12058 (void) sprintf(bp, "\n\nXSEQ-0 Registers"); 12059 bp += strlen(bp); 12060 for (cnt = 0; cnt < sizeof (fw->xseq_0_reg) / 4; cnt++) { 12061 if (cnt % 8 == 0) { 12062 (void) sprintf(bp++, "\n"); 12063 } 12064 12065 (void) sprintf(bp, "%08x ", fw->xseq_0_reg[cnt]); 12066 bp += 9; 12067 } 12068 12069 (void) sprintf(bp, "\n\nXSEQ-1 Registers"); 12070 bp += strlen(bp); 12071 for (cnt = 0; cnt < sizeof (fw->xseq_1_reg) / 4; cnt++) { 12072 if (cnt % 8 == 0) { 12073 (void) sprintf(bp++, "\n"); 12074 } 12075 12076 (void) sprintf(bp, "%08x ", fw->xseq_1_reg[cnt]); 12077 bp += 9; 12078 } 12079 12080 (void) sprintf(bp, "\n\nRSEQ GP Registers"); 12081 bp += strlen(bp); 12082 for (cnt = 0; cnt < sizeof (fw->rseq_gp_reg) / 4; cnt++) { 12083 if (cnt % 8 == 0) { 12084 (void) sprintf(bp++, "\n"); 12085 } 12086 12087 (void) sprintf(bp, "%08x ", fw->rseq_gp_reg[cnt]); 12088 bp += 9; 12089 } 12090 12091 (void) sprintf(bp, "\n\nRSEQ-0 Registers"); 12092 bp += strlen(bp); 12093 for (cnt = 0; cnt < sizeof (fw->rseq_0_reg) / 4; cnt++) { 12094 if (cnt % 8 == 0) { 12095 (void) sprintf(bp++, "\n"); 12096 } 12097 12098 (void) sprintf(bp, "%08x ", fw->rseq_0_reg[cnt]); 12099 bp += 9; 12100 } 12101 12102 (void) sprintf(bp, "\n\nRSEQ-1 Registers"); 12103 bp += strlen(bp); 12104 for (cnt = 0; cnt < sizeof (fw->rseq_1_reg) / 4; cnt++) { 12105 if (cnt % 8 == 0) { 12106 (void) sprintf(bp++, "\n"); 12107 } 12108 12109 (void) sprintf(bp, "%08x ", fw->rseq_1_reg[cnt]); 12110 bp += 9; 12111 } 12112 12113 (void) sprintf(bp, "\n\nRSEQ-2 Registers"); 12114 bp += strlen(bp); 12115 for (cnt = 0; cnt < sizeof (fw->rseq_2_reg) / 4; cnt++) { 12116 if (cnt % 8 == 0) { 12117 (void) sprintf(bp++, "\n"); 12118 } 12119 12120 (void) sprintf(bp, "%08x ", fw->rseq_2_reg[cnt]); 12121 bp += 9; 12122 } 12123 12124 (void) sprintf(bp, "\n\nCommand DMA Registers"); 12125 bp += strlen(bp); 12126 for (cnt = 0; cnt < sizeof (fw->cmd_dma_reg) / 4; cnt++) { 12127 if (cnt % 8 == 0) { 12128 (void) sprintf(bp++, "\n"); 12129 } 12130 12131 (void) sprintf(bp, "%08x ", fw->cmd_dma_reg[cnt]); 12132 bp += 9; 12133 } 12134 12135 (void) sprintf(bp, "\n\nRequest0 Queue DMA Channel Registers"); 12136 bp += strlen(bp); 12137 for (cnt = 0; cnt < sizeof (fw->req0_dma_reg) / 4; cnt++) { 12138 if (cnt % 8 == 0) { 12139 (void) sprintf(bp++, "\n"); 12140 } 12141 12142 (void) sprintf(bp, "%08x ", fw->req0_dma_reg[cnt]); 12143 bp += 9; 12144 } 12145 12146 (void) sprintf(bp, "\n\nResponse0 Queue DMA Channel Registers"); 12147 bp += strlen(bp); 12148 for (cnt = 0; cnt < sizeof (fw->resp0_dma_reg) / 4; cnt++) { 12149 if (cnt % 8 == 0) { 12150 (void) sprintf(bp++, "\n"); 12151 } 12152 12153 (void) sprintf(bp, "%08x ", fw->resp0_dma_reg[cnt]); 12154 bp += 9; 12155 } 12156 12157 (void) sprintf(bp, "\n\nRequest1 Queue DMA Channel Registers"); 12158 bp += strlen(bp); 12159 for (cnt = 0; cnt < sizeof (fw->req1_dma_reg) / 4; cnt++) { 12160 if (cnt % 8 == 0) { 12161 (void) sprintf(bp++, "\n"); 12162 } 12163 12164 (void) sprintf(bp, "%08x ", fw->req1_dma_reg[cnt]); 12165 bp += 9; 12166 } 12167 12168 (void) sprintf(bp, "\n\nXMT0 Data DMA Registers"); 12169 bp += strlen(bp); 12170 for (cnt = 0; cnt < sizeof (fw->xmt0_dma_reg) / 4; cnt++) { 12171 if (cnt % 8 == 0) { 12172 (void) sprintf(bp++, "\n"); 12173 } 12174 12175 (void) sprintf(bp, "%08x ", fw->xmt0_dma_reg[cnt]); 12176 bp += 9; 12177 } 12178 12179 (void) sprintf(bp, "\n\nXMT1 Data DMA Registers"); 12180 bp += strlen(bp); 12181 for (cnt = 0; cnt < sizeof (fw->xmt1_dma_reg) / 4; cnt++) { 12182 if (cnt % 8 == 0) { 12183 (void) sprintf(bp++, "\n"); 12184 } 12185 12186 (void) sprintf(bp, "%08x ", fw->xmt1_dma_reg[cnt]); 12187 bp += 9; 12188 } 12189 12190 (void) sprintf(bp, "\n\nXMT2 Data DMA Registers"); 12191 bp += strlen(bp); 12192 for (cnt = 0; cnt < sizeof (fw->xmt2_dma_reg) / 4; cnt++) { 12193 if (cnt % 8 == 0) { 12194 (void) sprintf(bp++, "\n"); 12195 } 12196 12197 (void) sprintf(bp, "%08x ", fw->xmt2_dma_reg[cnt]); 12198 bp += 9; 12199 } 12200 12201 (void) sprintf(bp, "\n\nXMT3 Data DMA Registers"); 12202 bp += strlen(bp); 12203 for (cnt = 0; cnt < sizeof (fw->xmt3_dma_reg) / 4; cnt++) { 12204 if (cnt % 8 == 0) { 12205 (void) sprintf(bp++, "\n"); 12206 } 12207 12208 (void) sprintf(bp, "%08x ", fw->xmt3_dma_reg[cnt]); 12209 bp += 9; 12210 } 12211 12212 (void) sprintf(bp, "\n\nXMT4 Data DMA Registers"); 12213 bp += strlen(bp); 12214 for (cnt = 0; cnt < sizeof (fw->xmt4_dma_reg) / 4; cnt++) { 12215 if (cnt % 8 == 0) { 12216 (void) sprintf(bp++, "\n"); 12217 } 12218 12219 (void) sprintf(bp, "%08x ", fw->xmt4_dma_reg[cnt]); 12220 bp += 9; 12221 } 12222 12223 (void) sprintf(bp, "\n\nXMT Data DMA Common Registers"); 12224 bp += strlen(bp); 12225 for (cnt = 0; cnt < sizeof (fw->xmt_data_dma_reg) / 4; cnt++) { 12226 if (cnt % 8 == 0) { 12227 (void) sprintf(bp++, "\n"); 12228 } 12229 12230 (void) sprintf(bp, "%08x ", fw->xmt_data_dma_reg[cnt]); 12231 bp += 9; 12232 } 12233 12234 (void) sprintf(bp, "\n\nRCV Thread 0 Data DMA Registers"); 12235 bp += strlen(bp); 12236 for (cnt = 0; cnt < sizeof (fw->rcvt0_data_dma_reg) / 4; cnt++) { 12237 if (cnt % 8 == 0) { 12238 (void) sprintf(bp++, "\n"); 12239 } 12240 12241 (void) sprintf(bp, "%08x ", fw->rcvt0_data_dma_reg[cnt]); 12242 bp += 9; 12243 } 12244 12245 (void) sprintf(bp, "\n\nRCV Thread 1 Data DMA Registers"); 12246 bp += strlen(bp); 12247 for (cnt = 0; cnt < sizeof (fw->rcvt1_data_dma_reg) / 4; cnt++) { 12248 if (cnt % 8 == 0) { 12249 (void) sprintf(bp++, "\n"); 12250 } 12251 12252 (void) sprintf(bp, "%08x ", fw->rcvt1_data_dma_reg[cnt]); 12253 bp += 9; 12254 } 12255 12256 (void) sprintf(bp, "\n\nRISC GP Registers"); 12257 bp += strlen(bp); 12258 for (cnt = 0; cnt < sizeof (fw->risc_gp_reg) / 4; cnt++) { 12259 if (cnt % 8 == 0) { 12260 (void) sprintf(bp++, "\n"); 12261 } 12262 12263 (void) sprintf(bp, "%08x ", fw->risc_gp_reg[cnt]); 12264 bp += 9; 12265 } 12266 12267 (void) sprintf(bufp + strlen(bufp), "\n\nShadow Registers"); 12268 bp += strlen(bp); 12269 for (cnt = 0; cnt < sizeof (fw->shadow_reg) / 4; cnt++) { 12270 if (cnt % 8 == 0) { 12271 (void) sprintf(bp++, "\n"); 12272 } 12273 12274 (void) sprintf(bp, "%08x ", fw->shadow_reg[cnt]); 12275 bp += 9; 12276 } 12277 12278 (void) sprintf(bp, "\n\nLMC Registers"); 12279 bp += strlen(bp); 12280 for (cnt = 0; cnt < sizeof (fw->lmc_reg) / 4; cnt++) { 12281 if (cnt % 8 == 0) { 12282 (void) sprintf(bp++, "\n"); 12283 } 12284 12285 (void) sprintf(bp, "%08x ", fw->lmc_reg[cnt]); 12286 bp += 9; 12287 } 12288 12289 (void) sprintf(bp, "\n\nFPM Hardware Registers"); 12290 bp += strlen(bp); 12291 for (cnt = 0; cnt < sizeof (fw->fpm_hdw_reg) / 4; cnt++) { 12292 if (cnt % 8 == 0) { 12293 (void) sprintf(bp++, "\n"); 12294 } 12295 12296 (void) sprintf(bp, "%08x ", fw->fpm_hdw_reg[cnt]); 12297 bp += 9; 12298 } 12299 12300 (void) sprintf(bp, "\n\nFB Hardware Registers"); 12301 bp += strlen(bp); 12302 for (cnt = 0; cnt < sizeof (fw->fb_hdw_reg) / 4; cnt++) { 12303 if (cnt % 8 == 0) { 12304 (void) sprintf(bp++, "\n"); 12305 } 12306 12307 (void) sprintf(bp, "%08x ", fw->fb_hdw_reg[cnt]); 12308 bp += 9; 12309 } 12310 12311 (void) sprintf(bp, "\n\nCode RAM"); 12312 bp += strlen(bp); 12313 for (cnt = 0; cnt < sizeof (fw->code_ram) / 4; cnt++) { 12314 if (cnt % 8 == 0) { 12315 (void) sprintf(bp, "\n%08x: ", cnt + 0x20000); 12316 bp += 11; 12317 } 12318 12319 (void) sprintf(bp, "%08x ", fw->code_ram[cnt]); 12320 bp += 9; 12321 } 12322 12323 (void) sprintf(bp, "\n\nExternal Memory"); 12324 bp += strlen(bp); 12325 for (cnt = 0; cnt < ha->fw_ext_memory_size / 4; cnt++) { 12326 if (cnt % 8 == 0) { 12327 (void) sprintf(bp, "\n%08x: ", cnt + 0x100000); 12328 bp += 11; 12329 } 12330 (void) sprintf(bp, "%08x ", fw->ext_mem[cnt]); 12331 bp += 9; 12332 } 12333 12334 (void) sprintf(bp, "\n[<==END] ISP Debug Dump"); 12335 bp += strlen(bp); 12336 12337 (void) sprintf(bp, "\n\nRequest Queue"); 12338 bp += strlen(bp); 12339 for (cnt = 0; cnt < REQUEST_QUEUE_SIZE / 4; cnt++) { 12340 if (cnt % 8 == 0) { 12341 (void) sprintf(bp, "\n%08x: ", cnt); 12342 bp += strlen(bp); 12343 } 12344 (void) sprintf(bp, "%08x ", fw->req_q[cnt]); 12345 bp += strlen(bp); 12346 } 12347 12348 (void) sprintf(bp, "\n\nResponse Queue"); 12349 bp += strlen(bp); 12350 for (cnt = 0; cnt < RESPONSE_QUEUE_SIZE / 4; cnt++) { 12351 if (cnt % 8 == 0) { 12352 (void) sprintf(bp, "\n%08x: ", cnt); 12353 bp += strlen(bp); 12354 } 12355 (void) sprintf(bp, "%08x ", fw->rsp_q[cnt]); 12356 bp += strlen(bp); 12357 } 12358 12359 if (CFG_IST(ha, CFG_ENABLE_FWEXTTRACE) && 12360 (ha->fwexttracebuf.bp != NULL)) { 12361 uint32_t cnt_b = 0; 12362 uint64_t w64 = (uintptr_t)ha->fwexttracebuf.bp; 12363 12364 (void) sprintf(bp, "\n\nExtended Trace Buffer Memory"); 12365 bp += strlen(bp); 12366 /* show data address as a byte address, data as long words */ 12367 for (cnt = 0; cnt < FWEXTSIZE / 4; cnt++) { 12368 cnt_b = cnt * 4; 12369 if (cnt_b % 32 == 0) { 12370 (void) sprintf(bp, "\n%08x: ", 12371 (int)(w64 + cnt_b)); 12372 bp += 11; 12373 } 12374 (void) sprintf(bp, "%08x ", fw->ext_trace_buf[cnt]); 12375 bp += 9; 12376 } 12377 } 12378 12379 if (CFG_IST(ha, CFG_ENABLE_FWFCETRACE) && 12380 (ha->fwfcetracebuf.bp != NULL)) { 12381 uint32_t cnt_b = 0; 12382 uint64_t w64 = (uintptr_t)ha->fwfcetracebuf.bp; 12383 12384 (void) sprintf(bp, "\n\nFC Event Trace Buffer Memory"); 12385 bp += strlen(bp); 12386 /* show data address as a byte address, data as long words */ 12387 for (cnt = 0; cnt < FWFCESIZE / 4; cnt++) { 12388 cnt_b = cnt * 4; 12389 if (cnt_b % 32 == 0) { 12390 (void) sprintf(bp, "\n%08x: ", 12391 (int)(w64 + cnt_b)); 12392 bp += 11; 12393 } 12394 (void) sprintf(bp, "%08x ", fw->fce_trace_buf[cnt]); 12395 bp += 9; 12396 } 12397 } 12398 12399 (void) sprintf(bp, "\n\n"); 12400 bp += strlen(bp); 12401 12402 cnt = (uint32_t)((uintptr_t)bp - (uintptr_t)bufp); 12403 12404 QL_PRINT_3(CE_CONT, "(%d): done=%xh\n", ha->instance, cnt); 12405 12406 return (cnt); 12407} 12408 12409/* 12410 * ql_2581_ascii_fw_dump 12411 * Converts ISP25xx or ISP81xx firmware binary dump to ascii. 12412 * 12413 * Input: 12414 * ha = adapter state pointer. 12415 * bptr = buffer pointer. 12416 * 12417 * Returns: 12418 * Amount of data buffer used. 12419 * 12420 * Context: 12421 * Kernel context. 12422 */ 12423static size_t 12424ql_2581_ascii_fw_dump(ql_adapter_state_t *ha, caddr_t bufp) 12425{ 12426 uint32_t cnt; 12427 uint32_t cnt1; 12428 caddr_t bp = bufp; 12429 ql_25xx_fw_dump_t *fw = ha->ql_dump_ptr; 12430 12431 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance); 12432 12433 (void) sprintf(bp, "\nISP FW Version %d.%02d.%02d Attributes %X\n", 12434 ha->fw_major_version, ha->fw_minor_version, 12435 ha->fw_subminor_version, ha->fw_attributes); 12436 bp += strlen(bp); 12437 12438 (void) sprintf(bp, "\nR2H Status Register\n%08x\n", fw->r2h_status); 12439 bp += strlen(bp); 12440 12441 (void) sprintf(bp, "\nHostRisc Registers"); 12442 bp += strlen(bp); 12443 for (cnt = 0; cnt < sizeof (fw->hostrisc_reg) / 4; cnt++) { 12444 if (cnt % 8 == 0) { 12445 (void) sprintf(bp++, "\n"); 12446 } 12447 (void) sprintf(bp, "%08x ", fw->hostrisc_reg[cnt]); 12448 bp += 9; 12449 } 12450 12451 (void) sprintf(bp, "\n\nPCIe Registers"); 12452 bp += strlen(bp); 12453 for (cnt = 0; cnt < sizeof (fw->pcie_reg) / 4; cnt++) { 12454 if (cnt % 8 == 0) { 12455 (void) sprintf(bp++, "\n"); 12456 } 12457 (void) sprintf(bp, "%08x ", fw->pcie_reg[cnt]); 12458 bp += 9; 12459 } 12460 12461 (void) strcat(bp, "\n\nHost Interface Registers"); 12462 bp += strlen(bp); 12463 for (cnt = 0; cnt < sizeof (fw->host_reg) / 4; cnt++) { 12464 if (cnt % 8 == 0) { 12465 (void) sprintf(bp++, "\n"); 12466 } 12467 (void) sprintf(bp, "%08x ", fw->host_reg[cnt]); 12468 bp += 9; 12469 } 12470 12471 (void) sprintf(bufp + strlen(bufp), "\n\nShadow Registers"); 12472 bp += strlen(bp); 12473 for (cnt = 0; cnt < sizeof (fw->shadow_reg) / 4; cnt++) { 12474 if (cnt % 8 == 0) { 12475 (void) sprintf(bp++, "\n"); 12476 } 12477 (void) sprintf(bp, "%08x ", fw->shadow_reg[cnt]); 12478 bp += 9; 12479 } 12480 12481 (void) sprintf(bufp + strlen(bufp), "\n\nRISC IO Register\n%08x", 12482 fw->risc_io); 12483 bp += strlen(bp); 12484 12485 (void) sprintf(bp, "\n\nMailbox Registers"); 12486 bp += strlen(bp); 12487 for (cnt = 0; cnt < sizeof (fw->mailbox_reg) / 2; cnt++) { 12488 if (cnt % 16 == 0) { 12489 (void) sprintf(bp++, "\n"); 12490 } 12491 (void) sprintf(bp, "%04x ", fw->mailbox_reg[cnt]); 12492 bp += 5; 12493 } 12494 12495 (void) sprintf(bp, "\n\nXSEQ GP Registers"); 12496 bp += strlen(bp); 12497 for (cnt = 0; cnt < sizeof (fw->xseq_gp_reg) / 4; cnt++) { 12498 if (cnt % 8 == 0) { 12499 (void) sprintf(bp++, "\n"); 12500 } 12501 (void) sprintf(bp, "%08x ", fw->xseq_gp_reg[cnt]); 12502 bp += 9; 12503 } 12504 12505 (void) sprintf(bp, "\n\nXSEQ-0 Registers"); 12506 bp += strlen(bp); 12507 for (cnt = 0; cnt < sizeof (fw->xseq_0_reg) / 4; cnt++) { 12508 if (cnt % 8 == 0) { 12509 (void) sprintf(bp++, "\n"); 12510 } 12511 (void) sprintf(bp, "%08x ", fw->xseq_0_reg[cnt]); 12512 bp += 9; 12513 } 12514 12515 (void) sprintf(bp, "\n\nXSEQ-1 Registers"); 12516 bp += strlen(bp); 12517 for (cnt = 0; cnt < sizeof (fw->xseq_1_reg) / 4; cnt++) { 12518 if (cnt % 8 == 0) { 12519 (void) sprintf(bp++, "\n"); 12520 } 12521 (void) sprintf(bp, "%08x ", fw->xseq_1_reg[cnt]); 12522 bp += 9; 12523 } 12524 12525 (void) sprintf(bp, "\n\nRSEQ GP Registers"); 12526 bp += strlen(bp); 12527 for (cnt = 0; cnt < sizeof (fw->rseq_gp_reg) / 4; cnt++) { 12528 if (cnt % 8 == 0) { 12529 (void) sprintf(bp++, "\n"); 12530 } 12531 (void) sprintf(bp, "%08x ", fw->rseq_gp_reg[cnt]); 12532 bp += 9; 12533 } 12534 12535 (void) sprintf(bp, "\n\nRSEQ-0 Registers"); 12536 bp += strlen(bp); 12537 for (cnt = 0; cnt < sizeof (fw->rseq_0_reg) / 4; cnt++) { 12538 if (cnt % 8 == 0) { 12539 (void) sprintf(bp++, "\n"); 12540 } 12541 (void) sprintf(bp, "%08x ", fw->rseq_0_reg[cnt]); 12542 bp += 9; 12543 } 12544 12545 (void) sprintf(bp, "\n\nRSEQ-1 Registers"); 12546 bp += strlen(bp); 12547 for (cnt = 0; cnt < sizeof (fw->rseq_1_reg) / 4; cnt++) { 12548 if (cnt % 8 == 0) { 12549 (void) sprintf(bp++, "\n"); 12550 } 12551 (void) sprintf(bp, "%08x ", fw->rseq_1_reg[cnt]); 12552 bp += 9; 12553 } 12554 12555 (void) sprintf(bp, "\n\nRSEQ-2 Registers"); 12556 bp += strlen(bp); 12557 for (cnt = 0; cnt < sizeof (fw->rseq_2_reg) / 4; cnt++) { 12558 if (cnt % 8 == 0) { 12559 (void) sprintf(bp++, "\n"); 12560 } 12561 (void) sprintf(bp, "%08x ", fw->rseq_2_reg[cnt]); 12562 bp += 9; 12563 } 12564 12565 (void) sprintf(bp, "\n\nASEQ GP Registers"); 12566 bp += strlen(bp); 12567 for (cnt = 0; cnt < sizeof (fw->aseq_gp_reg) / 4; cnt++) { 12568 if (cnt % 8 == 0) { 12569 (void) sprintf(bp++, "\n"); 12570 } 12571 (void) sprintf(bp, "%08x ", fw->aseq_gp_reg[cnt]); 12572 bp += 9; 12573 } 12574 12575 (void) sprintf(bp, "\n\nASEQ-0 Registers"); 12576 bp += strlen(bp); 12577 for (cnt = 0; cnt < sizeof (fw->aseq_0_reg) / 4; cnt++) { 12578 if (cnt % 8 == 0) { 12579 (void) sprintf(bp++, "\n"); 12580 } 12581 (void) sprintf(bp, "%08x ", fw->aseq_0_reg[cnt]); 12582 bp += 9; 12583 } 12584 12585 (void) sprintf(bp, "\n\nASEQ-1 Registers"); 12586 bp += strlen(bp); 12587 for (cnt = 0; cnt < sizeof (fw->aseq_1_reg) / 4; cnt++) { 12588 if (cnt % 8 == 0) { 12589 (void) sprintf(bp++, "\n"); 12590 } 12591 (void) sprintf(bp, "%08x ", fw->aseq_1_reg[cnt]); 12592 bp += 9; 12593 } 12594 12595 (void) sprintf(bp, "\n\nASEQ-2 Registers"); 12596 bp += strlen(bp); 12597 for (cnt = 0; cnt < sizeof (fw->aseq_2_reg) / 4; cnt++) { 12598 if (cnt % 8 == 0) { 12599 (void) sprintf(bp++, "\n"); 12600 } 12601 (void) sprintf(bp, "%08x ", fw->aseq_2_reg[cnt]); 12602 bp += 9; 12603 } 12604 12605 (void) sprintf(bp, "\n\nCommand DMA Registers"); 12606 bp += strlen(bp); 12607 for (cnt = 0; cnt < sizeof (fw->cmd_dma_reg) / 4; cnt++) { 12608 if (cnt % 8 == 0) { 12609 (void) sprintf(bp++, "\n"); 12610 } 12611 (void) sprintf(bp, "%08x ", fw->cmd_dma_reg[cnt]); 12612 bp += 9; 12613 } 12614 12615 (void) sprintf(bp, "\n\nRequest0 Queue DMA Channel Registers"); 12616 bp += strlen(bp); 12617 for (cnt = 0; cnt < sizeof (fw->req0_dma_reg) / 4; cnt++) { 12618 if (cnt % 8 == 0) { 12619 (void) sprintf(bp++, "\n"); 12620 } 12621 (void) sprintf(bp, "%08x ", fw->req0_dma_reg[cnt]); 12622 bp += 9; 12623 } 12624 12625 (void) sprintf(bp, "\n\nResponse0 Queue DMA Channel Registers"); 12626 bp += strlen(bp); 12627 for (cnt = 0; cnt < sizeof (fw->resp0_dma_reg) / 4; cnt++) { 12628 if (cnt % 8 == 0) { 12629 (void) sprintf(bp++, "\n"); 12630 } 12631 (void) sprintf(bp, "%08x ", fw->resp0_dma_reg[cnt]); 12632 bp += 9; 12633 } 12634 12635 (void) sprintf(bp, "\n\nRequest1 Queue DMA Channel Registers"); 12636 bp += strlen(bp); 12637 for (cnt = 0; cnt < sizeof (fw->req1_dma_reg) / 4; cnt++) { 12638 if (cnt % 8 == 0) { 12639 (void) sprintf(bp++, "\n"); 12640 } 12641 (void) sprintf(bp, "%08x ", fw->req1_dma_reg[cnt]); 12642 bp += 9; 12643 } 12644 12645 (void) sprintf(bp, "\n\nXMT0 Data DMA Registers"); 12646 bp += strlen(bp); 12647 for (cnt = 0; cnt < sizeof (fw->xmt0_dma_reg) / 4; cnt++) { 12648 if (cnt % 8 == 0) { 12649 (void) sprintf(bp++, "\n"); 12650 } 12651 (void) sprintf(bp, "%08x ", fw->xmt0_dma_reg[cnt]); 12652 bp += 9; 12653 } 12654 12655 (void) sprintf(bp, "\n\nXMT1 Data DMA Registers"); 12656 bp += strlen(bp); 12657 for (cnt = 0; cnt < sizeof (fw->xmt1_dma_reg) / 4; cnt++) { 12658 if (cnt % 8 == 0) { 12659 (void) sprintf(bp++, "\n"); 12660 } 12661 (void) sprintf(bp, "%08x ", fw->xmt1_dma_reg[cnt]); 12662 bp += 9; 12663 } 12664 12665 (void) sprintf(bp, "\n\nXMT2 Data DMA Registers"); 12666 bp += strlen(bp); 12667 for (cnt = 0; cnt < sizeof (fw->xmt2_dma_reg) / 4; cnt++) { 12668 if (cnt % 8 == 0) { 12669 (void) sprintf(bp++, "\n"); 12670 } 12671 (void) sprintf(bp, "%08x ", fw->xmt2_dma_reg[cnt]); 12672 bp += 9; 12673 } 12674 12675 (void) sprintf(bp, "\n\nXMT3 Data DMA Registers"); 12676 bp += strlen(bp); 12677 for (cnt = 0; cnt < sizeof (fw->xmt3_dma_reg) / 4; cnt++) { 12678 if (cnt % 8 == 0) { 12679 (void) sprintf(bp++, "\n"); 12680 } 12681 (void) sprintf(bp, "%08x ", fw->xmt3_dma_reg[cnt]); 12682 bp += 9; 12683 } 12684 12685 (void) sprintf(bp, "\n\nXMT4 Data DMA Registers"); 12686 bp += strlen(bp); 12687 for (cnt = 0; cnt < sizeof (fw->xmt4_dma_reg) / 4; cnt++) { 12688 if (cnt % 8 == 0) { 12689 (void) sprintf(bp++, "\n"); 12690 } 12691 (void) sprintf(bp, "%08x ", fw->xmt4_dma_reg[cnt]); 12692 bp += 9; 12693 } 12694 12695 (void) sprintf(bp, "\n\nXMT Data DMA Common Registers"); 12696 bp += strlen(bp); 12697 for (cnt = 0; cnt < sizeof (fw->xmt_data_dma_reg) / 4; cnt++) { 12698 if (cnt % 8 == 0) { 12699 (void) sprintf(bp++, "\n"); 12700 } 12701 (void) sprintf(bp, "%08x ", fw->xmt_data_dma_reg[cnt]); 12702 bp += 9; 12703 } 12704 12705 (void) sprintf(bp, "\n\nRCV Thread 0 Data DMA Registers"); 12706 bp += strlen(bp); 12707 for (cnt = 0; cnt < sizeof (fw->rcvt0_data_dma_reg) / 4; cnt++) { 12708 if (cnt % 8 == 0) { 12709 (void) sprintf(bp++, "\n"); 12710 } 12711 (void) sprintf(bp, "%08x ", fw->rcvt0_data_dma_reg[cnt]); 12712 bp += 9; 12713 } 12714 12715 (void) sprintf(bp, "\n\nRCV Thread 1 Data DMA Registers"); 12716 bp += strlen(bp); 12717 for (cnt = 0; cnt < sizeof (fw->rcvt1_data_dma_reg) / 4; cnt++) { 12718 if (cnt % 8 == 0) { 12719 (void) sprintf(bp++, "\n"); 12720 } 12721 (void) sprintf(bp, "%08x ", fw->rcvt1_data_dma_reg[cnt]); 12722 bp += 9; 12723 } 12724 12725 (void) sprintf(bp, "\n\nRISC GP Registers"); 12726 bp += strlen(bp); 12727 for (cnt = 0; cnt < sizeof (fw->risc_gp_reg) / 4; cnt++) { 12728 if (cnt % 8 == 0) { 12729 (void) sprintf(bp++, "\n"); 12730 } 12731 (void) sprintf(bp, "%08x ", fw->risc_gp_reg[cnt]); 12732 bp += 9; 12733 } 12734 12735 (void) sprintf(bp, "\n\nLMC Registers"); 12736 bp += strlen(bp); 12737 for (cnt = 0; cnt < sizeof (fw->lmc_reg) / 4; cnt++) { 12738 if (cnt % 8 == 0) { 12739 (void) sprintf(bp++, "\n"); 12740 } 12741 (void) sprintf(bp, "%08x ", fw->lmc_reg[cnt]); 12742 bp += 9; 12743 } 12744 12745 (void) sprintf(bp, "\n\nFPM Hardware Registers"); 12746 bp += strlen(bp); 12747 cnt1 = CFG_IST(ha, CFG_CTRL_81XX) ? 12748 (uint32_t)(sizeof (((ql_81xx_fw_dump_t *)(fw))->fpm_hdw_reg)) : 12749 (uint32_t)(sizeof (fw->fpm_hdw_reg)); 12750 for (cnt = 0; cnt < cnt1 / 4; cnt++) { 12751 if (cnt % 8 == 0) { 12752 (void) sprintf(bp++, "\n"); 12753 } 12754 (void) sprintf(bp, "%08x ", fw->fpm_hdw_reg[cnt]); 12755 bp += 9; 12756 } 12757 12758 (void) sprintf(bp, "\n\nFB Hardware Registers"); 12759 bp += strlen(bp); 12760 cnt1 = CFG_IST(ha, CFG_CTRL_81XX) ? 12761 (uint32_t)(sizeof (((ql_81xx_fw_dump_t *)(fw))->fb_hdw_reg)) : 12762 (uint32_t)(sizeof (fw->fb_hdw_reg)); 12763 for (cnt = 0; cnt < cnt1 / 4; cnt++) { 12764 if (cnt % 8 == 0) { 12765 (void) sprintf(bp++, "\n"); 12766 } 12767 (void) sprintf(bp, "%08x ", fw->fb_hdw_reg[cnt]); 12768 bp += 9; 12769 } 12770 12771 (void) sprintf(bp, "\n\nCode RAM"); 12772 bp += strlen(bp); 12773 for (cnt = 0; cnt < sizeof (fw->code_ram) / 4; cnt++) { 12774 if (cnt % 8 == 0) { 12775 (void) sprintf(bp, "\n%08x: ", cnt + 0x20000); 12776 bp += 11; 12777 } 12778 (void) sprintf(bp, "%08x ", fw->code_ram[cnt]); 12779 bp += 9; 12780 } 12781 12782 (void) sprintf(bp, "\n\nExternal Memory"); 12783 bp += strlen(bp); 12784 for (cnt = 0; cnt < ha->fw_ext_memory_size / 4; cnt++) { 12785 if (cnt % 8 == 0) { 12786 (void) sprintf(bp, "\n%08x: ", cnt + 0x100000); 12787 bp += 11; 12788 } 12789 (void) sprintf(bp, "%08x ", fw->ext_mem[cnt]); 12790 bp += 9; 12791 } 12792 12793 (void) sprintf(bp, "\n[<==END] ISP Debug Dump"); 12794 bp += strlen(bp); 12795 12796 (void) sprintf(bp, "\n\nRequest Queue"); 12797 bp += strlen(bp); 12798 for (cnt = 0; cnt < REQUEST_QUEUE_SIZE / 4; cnt++) { 12799 if (cnt % 8 == 0) { 12800 (void) sprintf(bp, "\n%08x: ", cnt); 12801 bp += strlen(bp); 12802 } 12803 (void) sprintf(bp, "%08x ", fw->req_q[cnt]); 12804 bp += strlen(bp); 12805 } 12806 12807 (void) sprintf(bp, "\n\nResponse Queue"); 12808 bp += strlen(bp); 12809 for (cnt = 0; cnt < RESPONSE_QUEUE_SIZE / 4; cnt++) { 12810 if (cnt % 8 == 0) { 12811 (void) sprintf(bp, "\n%08x: ", cnt); 12812 bp += strlen(bp); 12813 } 12814 (void) sprintf(bp, "%08x ", fw->rsp_q[cnt]); 12815 bp += strlen(bp); 12816 } 12817 12818 if (CFG_IST(ha, CFG_ENABLE_FWEXTTRACE) && 12819 (ha->fwexttracebuf.bp != NULL)) { 12820 uint32_t cnt_b = 0; 12821 uint64_t w64 = (uintptr_t)ha->fwexttracebuf.bp; 12822 12823 (void) sprintf(bp, "\n\nExtended Trace Buffer Memory"); 12824 bp += strlen(bp); 12825 /* show data address as a byte address, data as long words */ 12826 for (cnt = 0; cnt < FWEXTSIZE / 4; cnt++) { 12827 cnt_b = cnt * 4; 12828 if (cnt_b % 32 == 0) { 12829 (void) sprintf(bp, "\n%08x: ", 12830 (int)(w64 + cnt_b)); 12831 bp += 11; 12832 } 12833 (void) sprintf(bp, "%08x ", fw->ext_trace_buf[cnt]); 12834 bp += 9; 12835 } 12836 } 12837 12838 if (CFG_IST(ha, CFG_ENABLE_FWFCETRACE) && 12839 (ha->fwfcetracebuf.bp != NULL)) { 12840 uint32_t cnt_b = 0; 12841 uint64_t w64 = (uintptr_t)ha->fwfcetracebuf.bp; 12842 12843 (void) sprintf(bp, "\n\nFC Event Trace Buffer Memory"); 12844 bp += strlen(bp); 12845 /* show data address as a byte address, data as long words */ 12846 for (cnt = 0; cnt < FWFCESIZE / 4; cnt++) { 12847 cnt_b = cnt * 4; 12848 if (cnt_b % 32 == 0) { 12849 (void) sprintf(bp, "\n%08x: ", 12850 (int)(w64 + cnt_b)); 12851 bp += 11; 12852 } 12853 (void) sprintf(bp, "%08x ", fw->fce_trace_buf[cnt]); 12854 bp += 9; 12855 } 12856 } 12857 12858 (void) sprintf(bp, "\n\n"); 12859 bp += strlen(bp); 12860 12861 cnt = (uint32_t)((uintptr_t)bp - (uintptr_t)bufp); 12862 12863 QL_PRINT_3(CE_CONT, "(%d): done=%xh\n", ha->instance, cnt); 12864 12865 return (cnt); 12866} 12867 12868/* 12869 * ql_2200_binary_fw_dump 12870 * 12871 * Input: 12872 * ha: adapter state pointer. 12873 * fw: firmware dump context pointer. 12874 * 12875 * Returns: 12876 * ql local function return status code. 12877 * 12878 * Context: 12879 * Interrupt or Kernel context, no mailbox commands allowed. 12880 */ 12881static int 12882ql_2200_binary_fw_dump(ql_adapter_state_t *ha, ql_fw_dump_t *fw) 12883{ 12884 uint32_t cnt; 12885 uint16_t risc_address; 12886 clock_t timer; 12887 mbx_cmd_t mc; 12888 mbx_cmd_t *mcp = &mc; 12889 int rval = QL_SUCCESS; 12890 12891 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance); 12892 12893 /* Disable ISP interrupts. */ 12894 WRT16_IO_REG(ha, ictrl, 0); 12895 ADAPTER_STATE_LOCK(ha); 12896 ha->flags &= ~INTERRUPTS_ENABLED; 12897 ADAPTER_STATE_UNLOCK(ha); 12898 12899 /* Release mailbox registers. */ 12900 WRT16_IO_REG(ha, semaphore, 0); 12901 12902 /* Pause RISC. */ 12903 WRT16_IO_REG(ha, hccr, HC_PAUSE_RISC); 12904 timer = 30000; 12905 while ((RD16_IO_REG(ha, hccr) & HC_RISC_PAUSE) == 0) { 12906 if (timer-- != 0) { 12907 drv_usecwait(MILLISEC); 12908 } else { 12909 rval = QL_FUNCTION_TIMEOUT; 12910 break; 12911 } 12912 } 12913 12914 if (rval == QL_SUCCESS) { 12915 (void) ql_read_regs(ha, fw->pbiu_reg, ha->iobase, 12916 sizeof (fw->pbiu_reg) / 2, 16); 12917 12918 /* In 2200 we only read 8 mailboxes */ 12919 (void) ql_read_regs(ha, fw->mailbox_reg, ha->iobase + 0x10, 12920 8, 16); 12921 12922 (void) ql_read_regs(ha, fw->dma_reg, ha->iobase + 0x20, 12923 sizeof (fw->dma_reg) / 2, 16); 12924 12925 WRT16_IO_REG(ha, ctrl_status, 0); 12926 (void) ql_read_regs(ha, fw->risc_hdw_reg, ha->iobase + 0xA0, 12927 sizeof (fw->risc_hdw_reg) / 2, 16); 12928 12929 WRT16_IO_REG(ha, pcr, 0x2000); 12930 (void) ql_read_regs(ha, fw->risc_gp0_reg, ha->iobase + 0x80, 12931 sizeof (fw->risc_gp0_reg) / 2, 16); 12932 12933 WRT16_IO_REG(ha, pcr, 0x2100); 12934 (void) ql_read_regs(ha, fw->risc_gp1_reg, ha->iobase + 0x80, 12935 sizeof (fw->risc_gp1_reg) / 2, 16); 12936 12937 WRT16_IO_REG(ha, pcr, 0x2200); 12938 (void) ql_read_regs(ha, fw->risc_gp2_reg, ha->iobase + 0x80, 12939 sizeof (fw->risc_gp2_reg) / 2, 16); 12940 12941 WRT16_IO_REG(ha, pcr, 0x2300); 12942 (void) ql_read_regs(ha, fw->risc_gp3_reg, ha->iobase + 0x80, 12943 sizeof (fw->risc_gp3_reg) / 2, 16); 12944 12945 WRT16_IO_REG(ha, pcr, 0x2400); 12946 (void) ql_read_regs(ha, fw->risc_gp4_reg, ha->iobase + 0x80, 12947 sizeof (fw->risc_gp4_reg) / 2, 16); 12948 12949 WRT16_IO_REG(ha, pcr, 0x2500); 12950 (void) ql_read_regs(ha, fw->risc_gp5_reg, ha->iobase + 0x80, 12951 sizeof (fw->risc_gp5_reg) / 2, 16); 12952 12953 WRT16_IO_REG(ha, pcr, 0x2600); 12954 (void) ql_read_regs(ha, fw->risc_gp6_reg, ha->iobase + 0x80, 12955 sizeof (fw->risc_gp6_reg) / 2, 16); 12956 12957 WRT16_IO_REG(ha, pcr, 0x2700); 12958 (void) ql_read_regs(ha, fw->risc_gp7_reg, ha->iobase + 0x80, 12959 sizeof (fw->risc_gp7_reg) / 2, 16); 12960 12961 WRT16_IO_REG(ha, ctrl_status, 0x10); 12962 /* 2200 has only 16 registers */ 12963 (void) ql_read_regs(ha, fw->frame_buf_hdw_reg, 12964 ha->iobase + 0x80, 16, 16); 12965 12966 WRT16_IO_REG(ha, ctrl_status, 0x20); 12967 (void) ql_read_regs(ha, fw->fpm_b0_reg, ha->iobase + 0x80, 12968 sizeof (fw->fpm_b0_reg) / 2, 16); 12969 12970 WRT16_IO_REG(ha, ctrl_status, 0x30); 12971 (void) ql_read_regs(ha, fw->fpm_b1_reg, ha->iobase + 0x80, 12972 sizeof (fw->fpm_b1_reg) / 2, 16); 12973 12974 /* Select FPM registers. */ 12975 WRT16_IO_REG(ha, ctrl_status, 0x20); 12976 12977 /* FPM Soft Reset. */ 12978 WRT16_IO_REG(ha, fpm_diag_config, 0x100); 12979 12980 /* Select frame buffer registers. */ 12981 WRT16_IO_REG(ha, ctrl_status, 0x10); 12982 12983 /* Reset frame buffer FIFOs. */ 12984 WRT16_IO_REG(ha, fb_cmd, 0xa000); 12985 12986 /* Select RISC module registers. */ 12987 WRT16_IO_REG(ha, ctrl_status, 0); 12988 12989 /* Reset RISC module. */ 12990 WRT16_IO_REG(ha, hccr, HC_RESET_RISC); 12991 12992 /* Reset ISP semaphore. */ 12993 WRT16_IO_REG(ha, semaphore, 0); 12994 12995 /* Release RISC module. */ 12996 WRT16_IO_REG(ha, hccr, HC_RELEASE_RISC); 12997 12998 /* Wait for RISC to recover from reset. */ 12999 timer = 30000; 13000 while (RD16_IO_REG(ha, mailbox[0]) == MBS_BUSY) { 13001 if (timer-- != 0) { 13002 drv_usecwait(MILLISEC); 13003 } else { 13004 rval = QL_FUNCTION_TIMEOUT; 13005 break; 13006 } 13007 } 13008 13009 /* Disable RISC pause on FPM parity error. */ 13010 WRT16_IO_REG(ha, hccr, HC_DISABLE_PARITY_PAUSE); 13011 } 13012 13013 if (rval == QL_SUCCESS) { 13014 /* Pause RISC. */ 13015 WRT16_IO_REG(ha, hccr, HC_PAUSE_RISC); 13016 timer = 30000; 13017 while ((RD16_IO_REG(ha, hccr) & HC_RISC_PAUSE) == 0) { 13018 if (timer-- != 0) { 13019 drv_usecwait(MILLISEC); 13020 } else { 13021 rval = QL_FUNCTION_TIMEOUT; 13022 break; 13023 } 13024 } 13025 } 13026 13027 if (rval == QL_SUCCESS) { 13028 /* Set memory configuration and timing. */ 13029 WRT16_IO_REG(ha, mctr, 0xf2); 13030 13031 /* Release RISC. */ 13032 WRT16_IO_REG(ha, hccr, HC_RELEASE_RISC); 13033 13034 /* Get RISC SRAM. */ 13035 risc_address = 0x1000; 13036 WRT16_IO_REG(ha, mailbox[0], MBC_READ_RAM_WORD); 13037 for (cnt = 0; cnt < 0xf000; cnt++) { 13038 WRT16_IO_REG(ha, mailbox[1], risc_address++); 13039 WRT16_IO_REG(ha, hccr, HC_SET_HOST_INT); 13040 for (timer = 6000000; timer != 0; timer--) { 13041 /* Check for pending interrupts. */ 13042 if (RD16_IO_REG(ha, istatus) & RISC_INT) { 13043 if (RD16_IO_REG(ha, semaphore) & 13044 BIT_0) { 13045 WRT16_IO_REG(ha, hccr, 13046 HC_CLR_RISC_INT); 13047 mcp->mb[0] = RD16_IO_REG(ha, 13048 mailbox[0]); 13049 fw->risc_ram[cnt] = 13050 RD16_IO_REG(ha, 13051 mailbox[2]); 13052 WRT16_IO_REG(ha, 13053 semaphore, 0); 13054 break; 13055 } 13056 WRT16_IO_REG(ha, hccr, 13057 HC_CLR_RISC_INT); 13058 } 13059 drv_usecwait(5); 13060 } 13061 13062 if (timer == 0) { 13063 rval = QL_FUNCTION_TIMEOUT; 13064 } else { 13065 rval = mcp->mb[0]; 13066 } 13067 13068 if (rval != QL_SUCCESS) { 13069 break; 13070 } 13071 } 13072 } 13073 13074 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance); 13075 13076 return (rval); 13077} 13078 13079/* 13080 * ql_2300_binary_fw_dump 13081 * 13082 * Input: 13083 * ha: adapter state pointer. 13084 * fw: firmware dump context pointer. 13085 * 13086 * Returns: 13087 * ql local function return status code. 13088 * 13089 * Context: 13090 * Interrupt or Kernel context, no mailbox commands allowed. 13091 */ 13092static int 13093ql_2300_binary_fw_dump(ql_adapter_state_t *ha, ql_fw_dump_t *fw) 13094{ 13095 clock_t timer; 13096 int rval = QL_SUCCESS; 13097 13098 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance); 13099 13100 /* Disable ISP interrupts. */ 13101 WRT16_IO_REG(ha, ictrl, 0); 13102 ADAPTER_STATE_LOCK(ha); 13103 ha->flags &= ~INTERRUPTS_ENABLED; 13104 ADAPTER_STATE_UNLOCK(ha); 13105 13106 /* Release mailbox registers. */ 13107 WRT16_IO_REG(ha, semaphore, 0); 13108 13109 /* Pause RISC. */ 13110 WRT16_IO_REG(ha, hccr, HC_PAUSE_RISC); 13111 timer = 30000; 13112 while ((RD16_IO_REG(ha, hccr) & HC_RISC_PAUSE) == 0) { 13113 if (timer-- != 0) { 13114 drv_usecwait(MILLISEC); 13115 } else { 13116 rval = QL_FUNCTION_TIMEOUT; 13117 break; 13118 } 13119 } 13120 13121 if (rval == QL_SUCCESS) { 13122 (void) ql_read_regs(ha, fw->pbiu_reg, ha->iobase, 13123 sizeof (fw->pbiu_reg) / 2, 16); 13124 13125 (void) ql_read_regs(ha, fw->risc_host_reg, ha->iobase + 0x10, 13126 sizeof (fw->risc_host_reg) / 2, 16); 13127 13128 (void) ql_read_regs(ha, fw->mailbox_reg, ha->iobase + 0x40, 13129 sizeof (fw->mailbox_reg) / 2, 16); 13130 13131 WRT16_IO_REG(ha, ctrl_status, 0x40); 13132 (void) ql_read_regs(ha, fw->resp_dma_reg, ha->iobase + 0x80, 13133 sizeof (fw->resp_dma_reg) / 2, 16); 13134 13135 WRT16_IO_REG(ha, ctrl_status, 0x50); 13136 (void) ql_read_regs(ha, fw->dma_reg, ha->iobase + 0x80, 13137 sizeof (fw->dma_reg) / 2, 16); 13138 13139 WRT16_IO_REG(ha, ctrl_status, 0); 13140 (void) ql_read_regs(ha, fw->risc_hdw_reg, ha->iobase + 0xA0, 13141 sizeof (fw->risc_hdw_reg) / 2, 16); 13142 13143 WRT16_IO_REG(ha, pcr, 0x2000); 13144 (void) ql_read_regs(ha, fw->risc_gp0_reg, ha->iobase + 0x80, 13145 sizeof (fw->risc_gp0_reg) / 2, 16); 13146 13147 WRT16_IO_REG(ha, pcr, 0x2200); 13148 (void) ql_read_regs(ha, fw->risc_gp1_reg, ha->iobase + 0x80, 13149 sizeof (fw->risc_gp1_reg) / 2, 16); 13150 13151 WRT16_IO_REG(ha, pcr, 0x2400); 13152 (void) ql_read_regs(ha, fw->risc_gp2_reg, ha->iobase + 0x80, 13153 sizeof (fw->risc_gp2_reg) / 2, 16); 13154 13155 WRT16_IO_REG(ha, pcr, 0x2600); 13156 (void) ql_read_regs(ha, fw->risc_gp3_reg, ha->iobase + 0x80, 13157 sizeof (fw->risc_gp3_reg) / 2, 16); 13158 13159 WRT16_IO_REG(ha, pcr, 0x2800); 13160 (void) ql_read_regs(ha, fw->risc_gp4_reg, ha->iobase + 0x80, 13161 sizeof (fw->risc_gp4_reg) / 2, 16); 13162 13163 WRT16_IO_REG(ha, pcr, 0x2A00); 13164 (void) ql_read_regs(ha, fw->risc_gp5_reg, ha->iobase + 0x80, 13165 sizeof (fw->risc_gp5_reg) / 2, 16); 13166 13167 WRT16_IO_REG(ha, pcr, 0x2C00); 13168 (void) ql_read_regs(ha, fw->risc_gp6_reg, ha->iobase + 0x80, 13169 sizeof (fw->risc_gp6_reg) / 2, 16); 13170 13171 WRT16_IO_REG(ha, pcr, 0x2E00); 13172 (void) ql_read_regs(ha, fw->risc_gp7_reg, ha->iobase + 0x80, 13173 sizeof (fw->risc_gp7_reg) / 2, 16); 13174 13175 WRT16_IO_REG(ha, ctrl_status, 0x10); 13176 (void) ql_read_regs(ha, fw->frame_buf_hdw_reg, 13177 ha->iobase + 0x80, sizeof (fw->frame_buf_hdw_reg) / 2, 16); 13178 13179 WRT16_IO_REG(ha, ctrl_status, 0x20); 13180 (void) ql_read_regs(ha, fw->fpm_b0_reg, ha->iobase + 0x80, 13181 sizeof (fw->fpm_b0_reg) / 2, 16); 13182 13183 WRT16_IO_REG(ha, ctrl_status, 0x30); 13184 (void) ql_read_regs(ha, fw->fpm_b1_reg, ha->iobase + 0x80, 13185 sizeof (fw->fpm_b1_reg) / 2, 16); 13186 13187 /* Select FPM registers. */ 13188 WRT16_IO_REG(ha, ctrl_status, 0x20); 13189 13190 /* FPM Soft Reset. */ 13191 WRT16_IO_REG(ha, fpm_diag_config, 0x100); 13192 13193 /* Select frame buffer registers. */ 13194 WRT16_IO_REG(ha, ctrl_status, 0x10); 13195 13196 /* Reset frame buffer FIFOs. */ 13197 WRT16_IO_REG(ha, fb_cmd, 0xa000); 13198 13199 /* Select RISC module registers. */ 13200 WRT16_IO_REG(ha, ctrl_status, 0); 13201 13202 /* Reset RISC module. */ 13203 WRT16_IO_REG(ha, hccr, HC_RESET_RISC); 13204 13205 /* Reset ISP semaphore. */ 13206 WRT16_IO_REG(ha, semaphore, 0); 13207 13208 /* Release RISC module. */ 13209 WRT16_IO_REG(ha, hccr, HC_RELEASE_RISC); 13210 13211 /* Wait for RISC to recover from reset. */ 13212 timer = 30000; 13213 while (RD16_IO_REG(ha, mailbox[0]) == MBS_BUSY) { 13214 if (timer-- != 0) { 13215 drv_usecwait(MILLISEC); 13216 } else { 13217 rval = QL_FUNCTION_TIMEOUT; 13218 break; 13219 } 13220 } 13221 13222 /* Disable RISC pause on FPM parity error. */ 13223 WRT16_IO_REG(ha, hccr, HC_DISABLE_PARITY_PAUSE); 13224 } 13225 13226 /* Get RISC SRAM. */ 13227 if (rval == QL_SUCCESS) { 13228 rval = ql_read_risc_ram(ha, 0x800, 0xf800, fw->risc_ram); 13229 } 13230 /* Get STACK SRAM. */ 13231 if (rval == QL_SUCCESS) { 13232 rval = ql_read_risc_ram(ha, 0x10000, 0x800, fw->stack_ram); 13233 } 13234 /* Get DATA SRAM. */ 13235 if (rval == QL_SUCCESS) { 13236 rval = ql_read_risc_ram(ha, 0x10800, 0xf800, fw->data_ram); 13237 } 13238 13239 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance); 13240 13241 return (rval); 13242} 13243 13244/* 13245 * ql_24xx_binary_fw_dump 13246 * 13247 * Input: 13248 * ha: adapter state pointer. 13249 * fw: firmware dump context pointer. 13250 * 13251 * Returns: 13252 * ql local function return status code. 13253 * 13254 * Context: 13255 * Interrupt or Kernel context, no mailbox commands allowed. 13256 */ 13257static int 13258ql_24xx_binary_fw_dump(ql_adapter_state_t *ha, ql_24xx_fw_dump_t *fw) 13259{ 13260 uint32_t *reg32; 13261 void *bp; 13262 clock_t timer; 13263 int rval = QL_SUCCESS; 13264 13265 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance); 13266 13267 fw->hccr = RD32_IO_REG(ha, hccr); 13268 13269 /* Pause RISC. */ 13270 if ((RD32_IO_REG(ha, intr_info_lo) & RH_RISC_PAUSED) == 0) { 13271 /* Disable ISP interrupts. */ 13272 WRT16_IO_REG(ha, ictrl, 0); 13273 13274 WRT32_IO_REG(ha, hccr, HC24_PAUSE_RISC); 13275 for (timer = 30000; 13276 (RD32_IO_REG(ha, intr_info_lo) & RH_RISC_PAUSED) == 0 && 13277 rval == QL_SUCCESS; timer--) { 13278 if (timer) { 13279 drv_usecwait(100); 13280 } else { 13281 rval = QL_FUNCTION_TIMEOUT; 13282 } 13283 } 13284 } 13285 13286 if (rval == QL_SUCCESS) { 13287 /* Host interface registers. */ 13288 (void) ql_read_regs(ha, fw->host_reg, ha->iobase, 13289 sizeof (fw->host_reg) / 4, 32); 13290 13291 /* Disable ISP interrupts. */ 13292 WRT32_IO_REG(ha, ictrl, 0); 13293 RD32_IO_REG(ha, ictrl); 13294 ADAPTER_STATE_LOCK(ha); 13295 ha->flags &= ~INTERRUPTS_ENABLED; 13296 ADAPTER_STATE_UNLOCK(ha); 13297 13298 /* Shadow registers. */ 13299 13300 WRT32_IO_REG(ha, io_base_addr, 0x0F70); 13301 RD32_IO_REG(ha, io_base_addr); 13302 13303 reg32 = (uint32_t *)((caddr_t)ha->iobase + 0xF0); 13304 WRT_REG_DWORD(ha, reg32, 0xB0000000); 13305 reg32 = (uint32_t *)((caddr_t)ha->iobase + 0xFC); 13306 fw->shadow_reg[0] = RD_REG_DWORD(ha, reg32); 13307 13308 reg32 = (uint32_t *)((caddr_t)ha->iobase + 0xF0); 13309 WRT_REG_DWORD(ha, reg32, 0xB0100000); 13310 reg32 = (uint32_t *)((caddr_t)ha->iobase + 0xFC); 13311 fw->shadow_reg[1] = RD_REG_DWORD(ha, reg32); 13312 13313 reg32 = (uint32_t *)((caddr_t)ha->iobase + 0xF0); 13314 WRT_REG_DWORD(ha, reg32, 0xB0200000); 13315 reg32 = (uint32_t *)((caddr_t)ha->iobase + 0xFC); 13316 fw->shadow_reg[2] = RD_REG_DWORD(ha, reg32); 13317 13318 reg32 = (uint32_t *)((caddr_t)ha->iobase + 0xF0); 13319 WRT_REG_DWORD(ha, reg32, 0xB0300000); 13320 reg32 = (uint32_t *)((caddr_t)ha->iobase + 0xFC); 13321 fw->shadow_reg[3] = RD_REG_DWORD(ha, reg32); 13322 13323 reg32 = (uint32_t *)((caddr_t)ha->iobase + 0xF0); 13324 WRT_REG_DWORD(ha, reg32, 0xB0400000); 13325 reg32 = (uint32_t *)((caddr_t)ha->iobase + 0xFC); 13326 fw->shadow_reg[4] = RD_REG_DWORD(ha, reg32); 13327 13328 reg32 = (uint32_t *)((caddr_t)ha->iobase + 0xF0); 13329 WRT_REG_DWORD(ha, reg32, 0xB0500000); 13330 reg32 = (uint32_t *)((caddr_t)ha->iobase + 0xFC); 13331 fw->shadow_reg[5] = RD_REG_DWORD(ha, reg32); 13332 13333 reg32 = (uint32_t *)((caddr_t)ha->iobase + 0xF0); 13334 WRT_REG_DWORD(ha, reg32, 0xB0600000); 13335 reg32 = (uint32_t *)((caddr_t)ha->iobase + 0xFC); 13336 fw->shadow_reg[6] = RD_REG_DWORD(ha, reg32); 13337 13338 /* Mailbox registers. */ 13339 (void) ql_read_regs(ha, fw->mailbox_reg, ha->iobase + 0x80, 13340 sizeof (fw->mailbox_reg) / 2, 16); 13341 13342 /* Transfer sequence registers. */ 13343 13344 /* XSEQ GP */ 13345 WRT32_IO_REG(ha, io_base_addr, 0xBF00); 13346 bp = ql_read_regs(ha, fw->xseq_gp_reg, ha->iobase + 0xC0, 13347 16, 32); 13348 WRT32_IO_REG(ha, io_base_addr, 0xBF10); 13349 bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32); 13350 WRT32_IO_REG(ha, io_base_addr, 0xBF20); 13351 bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32); 13352 WRT32_IO_REG(ha, io_base_addr, 0xBF30); 13353 bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32); 13354 WRT32_IO_REG(ha, io_base_addr, 0xBF40); 13355 bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32); 13356 WRT32_IO_REG(ha, io_base_addr, 0xBF50); 13357 bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32); 13358 WRT32_IO_REG(ha, io_base_addr, 0xBF60); 13359 bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32); 13360 WRT32_IO_REG(ha, io_base_addr, 0xBF70); 13361 (void) ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32); 13362 13363 /* XSEQ-0 */ 13364 WRT32_IO_REG(ha, io_base_addr, 0xBFE0); 13365 (void) ql_read_regs(ha, fw->xseq_0_reg, ha->iobase + 0xC0, 13366 sizeof (fw->xseq_0_reg) / 4, 32); 13367 13368 /* XSEQ-1 */ 13369 WRT32_IO_REG(ha, io_base_addr, 0xBFF0); 13370 (void) ql_read_regs(ha, fw->xseq_1_reg, ha->iobase + 0xC0, 13371 sizeof (fw->xseq_1_reg) / 4, 32); 13372 13373 /* Receive sequence registers. */ 13374 13375 /* RSEQ GP */ 13376 WRT32_IO_REG(ha, io_base_addr, 0xFF00); 13377 bp = ql_read_regs(ha, fw->rseq_gp_reg, ha->iobase + 0xC0, 13378 16, 32); 13379 WRT32_IO_REG(ha, io_base_addr, 0xFF10); 13380 bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32); 13381 WRT32_IO_REG(ha, io_base_addr, 0xFF20); 13382 bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32); 13383 WRT32_IO_REG(ha, io_base_addr, 0xFF30); 13384 bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32); 13385 WRT32_IO_REG(ha, io_base_addr, 0xFF40); 13386 bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32); 13387 WRT32_IO_REG(ha, io_base_addr, 0xFF50); 13388 bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32); 13389 WRT32_IO_REG(ha, io_base_addr, 0xFF60); 13390 bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32); 13391 WRT32_IO_REG(ha, io_base_addr, 0xFF70); 13392 (void) ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32); 13393 13394 /* RSEQ-0 */ 13395 WRT32_IO_REG(ha, io_base_addr, 0xFFD0); 13396 (void) ql_read_regs(ha, fw->rseq_0_reg, ha->iobase + 0xC0, 13397 sizeof (fw->rseq_0_reg) / 4, 32); 13398 13399 /* RSEQ-1 */ 13400 WRT32_IO_REG(ha, io_base_addr, 0xFFE0); 13401 (void) ql_read_regs(ha, fw->rseq_1_reg, ha->iobase + 0xC0, 13402 sizeof (fw->rseq_1_reg) / 4, 32); 13403 13404 /* RSEQ-2 */ 13405 WRT32_IO_REG(ha, io_base_addr, 0xFFF0); 13406 (void) ql_read_regs(ha, fw->rseq_2_reg, ha->iobase + 0xC0, 13407 sizeof (fw->rseq_2_reg) / 4, 32); 13408 13409 /* Command DMA registers. */ 13410 13411 WRT32_IO_REG(ha, io_base_addr, 0x7100); 13412 (void) ql_read_regs(ha, fw->cmd_dma_reg, ha->iobase + 0xC0, 13413 sizeof (fw->cmd_dma_reg) / 4, 32); 13414 13415 /* Queues. */ 13416 13417 /* RequestQ0 */ 13418 WRT32_IO_REG(ha, io_base_addr, 0x7200); 13419 bp = ql_read_regs(ha, fw->req0_dma_reg, ha->iobase + 0xC0, 13420 8, 32); 13421 (void) ql_read_regs(ha, bp, ha->iobase + 0xE4, 7, 32); 13422 13423 /* ResponseQ0 */ 13424 WRT32_IO_REG(ha, io_base_addr, 0x7300); 13425 bp = ql_read_regs(ha, fw->resp0_dma_reg, ha->iobase + 0xC0, 13426 8, 32); 13427 (void) ql_read_regs(ha, bp, ha->iobase + 0xE4, 7, 32); 13428 13429 /* RequestQ1 */ 13430 WRT32_IO_REG(ha, io_base_addr, 0x7400); 13431 bp = ql_read_regs(ha, fw->req1_dma_reg, ha->iobase + 0xC0, 13432 8, 32); 13433 (void) ql_read_regs(ha, bp, ha->iobase + 0xE4, 7, 32); 13434 13435 /* Transmit DMA registers. */ 13436 13437 /* XMT0 */ 13438 WRT32_IO_REG(ha, io_base_addr, 0x7600); 13439 bp = ql_read_regs(ha, fw->xmt0_dma_reg, ha->iobase + 0xC0, 13440 16, 32); 13441 WRT32_IO_REG(ha, io_base_addr, 0x7610); 13442 (void) ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32); 13443 13444 /* XMT1 */ 13445 WRT32_IO_REG(ha, io_base_addr, 0x7620); 13446 bp = ql_read_regs(ha, fw->xmt1_dma_reg, ha->iobase + 0xC0, 13447 16, 32); 13448 WRT32_IO_REG(ha, io_base_addr, 0x7630); 13449 (void) ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32); 13450 13451 /* XMT2 */ 13452 WRT32_IO_REG(ha, io_base_addr, 0x7640); 13453 bp = ql_read_regs(ha, fw->xmt2_dma_reg, ha->iobase + 0xC0, 13454 16, 32); 13455 WRT32_IO_REG(ha, io_base_addr, 0x7650); 13456 (void) ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32); 13457 13458 /* XMT3 */ 13459 WRT32_IO_REG(ha, io_base_addr, 0x7660); 13460 bp = ql_read_regs(ha, fw->xmt3_dma_reg, ha->iobase + 0xC0, 13461 16, 32); 13462 WRT32_IO_REG(ha, io_base_addr, 0x7670); 13463 (void) ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32); 13464 13465 /* XMT4 */ 13466 WRT32_IO_REG(ha, io_base_addr, 0x7680); 13467 bp = ql_read_regs(ha, fw->xmt4_dma_reg, ha->iobase + 0xC0, 13468 16, 32); 13469 WRT32_IO_REG(ha, io_base_addr, 0x7690); 13470 (void) ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32); 13471 13472 /* XMT Common */ 13473 WRT32_IO_REG(ha, io_base_addr, 0x76A0); 13474 (void) ql_read_regs(ha, fw->xmt_data_dma_reg, 13475 ha->iobase + 0xC0, sizeof (fw->xmt_data_dma_reg) / 4, 32); 13476 13477 /* Receive DMA registers. */ 13478 13479 /* RCVThread0 */ 13480 WRT32_IO_REG(ha, io_base_addr, 0x7700); 13481 bp = ql_read_regs(ha, fw->rcvt0_data_dma_reg, 13482 ha->iobase + 0xC0, 16, 32); 13483 WRT32_IO_REG(ha, io_base_addr, 0x7710); 13484 (void) ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32); 13485 13486 /* RCVThread1 */ 13487 WRT32_IO_REG(ha, io_base_addr, 0x7720); 13488 bp = ql_read_regs(ha, fw->rcvt1_data_dma_reg, 13489 ha->iobase + 0xC0, 16, 32); 13490 WRT32_IO_REG(ha, io_base_addr, 0x7730); 13491 (void) ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32); 13492 13493 /* RISC registers. */ 13494 13495 /* RISC GP */ 13496 WRT32_IO_REG(ha, io_base_addr, 0x0F00); 13497 bp = ql_read_regs(ha, fw->risc_gp_reg, ha->iobase + 0xC0, 13498 16, 32); 13499 WRT32_IO_REG(ha, io_base_addr, 0x0F10); 13500 bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32); 13501 WRT32_IO_REG(ha, io_base_addr, 0x0F20); 13502 bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32); 13503 WRT32_IO_REG(ha, io_base_addr, 0x0F30); 13504 bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32); 13505 WRT32_IO_REG(ha, io_base_addr, 0x0F40); 13506 bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32); 13507 WRT32_IO_REG(ha, io_base_addr, 0x0F50); 13508 bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32); 13509 WRT32_IO_REG(ha, io_base_addr, 0x0F60); 13510 bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32); 13511 WRT32_IO_REG(ha, io_base_addr, 0x0F70); 13512 (void) ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32); 13513 13514 /* Local memory controller registers. */ 13515 13516 /* LMC */ 13517 WRT32_IO_REG(ha, io_base_addr, 0x3000); 13518 bp = ql_read_regs(ha, fw->lmc_reg, ha->iobase + 0xC0, 13519 16, 32); 13520 WRT32_IO_REG(ha, io_base_addr, 0x3010); 13521 bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32); 13522 WRT32_IO_REG(ha, io_base_addr, 0x3020); 13523 bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32); 13524 WRT32_IO_REG(ha, io_base_addr, 0x3030); 13525 bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32); 13526 WRT32_IO_REG(ha, io_base_addr, 0x3040); 13527 bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32); 13528 WRT32_IO_REG(ha, io_base_addr, 0x3050); 13529 bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32); 13530 WRT32_IO_REG(ha, io_base_addr, 0x3060); 13531 (void) ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32); 13532 13533 /* Fibre Protocol Module registers. */ 13534 13535 /* FPM hardware */ 13536 WRT32_IO_REG(ha, io_base_addr, 0x4000); 13537 bp = ql_read_regs(ha, fw->fpm_hdw_reg, ha->iobase + 0xC0, 13538 16, 32); 13539 WRT32_IO_REG(ha, io_base_addr, 0x4010); 13540 bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32); 13541 WRT32_IO_REG(ha, io_base_addr, 0x4020); 13542 bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32); 13543 WRT32_IO_REG(ha, io_base_addr, 0x4030); 13544 bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32); 13545 WRT32_IO_REG(ha, io_base_addr, 0x4040); 13546 bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32); 13547 WRT32_IO_REG(ha, io_base_addr, 0x4050); 13548 bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32); 13549 WRT32_IO_REG(ha, io_base_addr, 0x4060); 13550 bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32); 13551 WRT32_IO_REG(ha, io_base_addr, 0x4070); 13552 bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32); 13553 WRT32_IO_REG(ha, io_base_addr, 0x4080); 13554 bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32); 13555 WRT32_IO_REG(ha, io_base_addr, 0x4090); 13556 bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32); 13557 WRT32_IO_REG(ha, io_base_addr, 0x40A0); 13558 bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32); 13559 WRT32_IO_REG(ha, io_base_addr, 0x40B0); 13560 (void) ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32); 13561 13562 /* Frame Buffer registers. */ 13563 13564 /* FB hardware */ 13565 WRT32_IO_REG(ha, io_base_addr, 0x6000); 13566 bp = ql_read_regs(ha, fw->fb_hdw_reg, ha->iobase + 0xC0, 13567 16, 32); 13568 WRT32_IO_REG(ha, io_base_addr, 0x6010); 13569 bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32); 13570 WRT32_IO_REG(ha, io_base_addr, 0x6020); 13571 bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32); 13572 WRT32_IO_REG(ha, io_base_addr, 0x6030); 13573 bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32); 13574 WRT32_IO_REG(ha, io_base_addr, 0x6040); 13575 bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32); 13576 WRT32_IO_REG(ha, io_base_addr, 0x6100); 13577 bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32); 13578 WRT32_IO_REG(ha, io_base_addr, 0x6130); 13579 bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32); 13580 WRT32_IO_REG(ha, io_base_addr, 0x6150); 13581 bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32); 13582 WRT32_IO_REG(ha, io_base_addr, 0x6170); 13583 bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32); 13584 WRT32_IO_REG(ha, io_base_addr, 0x6190); 13585 bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32); 13586 WRT32_IO_REG(ha, io_base_addr, 0x61B0); 13587 (void) ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32); 13588 } 13589 13590 /* Get the request queue */ 13591 if (rval == QL_SUCCESS) { 13592 uint32_t cnt; 13593 uint32_t *w32 = (uint32_t *)ha->request_ring_bp; 13594 13595 /* Sync DMA buffer. */ 13596 (void) ddi_dma_sync(ha->hba_buf.dma_handle, 13597 REQUEST_Q_BUFFER_OFFSET, sizeof (fw->req_q), 13598 DDI_DMA_SYNC_FORKERNEL); 13599 13600 for (cnt = 0; cnt < sizeof (fw->req_q) / 4; cnt++) { 13601 fw->req_q[cnt] = *w32++; 13602 LITTLE_ENDIAN_32(&fw->req_q[cnt]); 13603 } 13604 } 13605 13606 /* Get the response queue */ 13607 if (rval == QL_SUCCESS) { 13608 uint32_t cnt; 13609 uint32_t *w32 = (uint32_t *)ha->response_ring_bp; 13610 13611 /* Sync DMA buffer. */ 13612 (void) ddi_dma_sync(ha->hba_buf.dma_handle, 13613 RESPONSE_Q_BUFFER_OFFSET, sizeof (fw->rsp_q), 13614 DDI_DMA_SYNC_FORKERNEL); 13615 13616 for (cnt = 0; cnt < sizeof (fw->rsp_q) / 4; cnt++) { 13617 fw->rsp_q[cnt] = *w32++; 13618 LITTLE_ENDIAN_32(&fw->rsp_q[cnt]); 13619 } 13620 } 13621 13622 /* Reset RISC. */ 13623 ql_reset_chip(ha); 13624 13625 /* Memory. */ 13626 if (rval == QL_SUCCESS) { 13627 /* Code RAM. */ 13628 rval = ql_read_risc_ram(ha, 0x20000, 13629 sizeof (fw->code_ram) / 4, fw->code_ram); 13630 } 13631 if (rval == QL_SUCCESS) { 13632 /* External Memory. */ 13633 rval = ql_read_risc_ram(ha, 0x100000, 13634 ha->fw_ext_memory_size / 4, fw->ext_mem); 13635 } 13636 13637 /* Get the extended trace buffer */ 13638 if (rval == QL_SUCCESS) { 13639 if (CFG_IST(ha, CFG_ENABLE_FWEXTTRACE) && 13640 (ha->fwexttracebuf.bp != NULL)) { 13641 uint32_t cnt; 13642 uint32_t *w32 = ha->fwexttracebuf.bp; 13643 13644 /* Sync DMA buffer. */ 13645 (void) ddi_dma_sync(ha->fwexttracebuf.dma_handle, 0, 13646 FWEXTSIZE, DDI_DMA_SYNC_FORKERNEL); 13647 13648 for (cnt = 0; cnt < FWEXTSIZE / 4; cnt++) { 13649 fw->ext_trace_buf[cnt] = *w32++; 13650 } 13651 } 13652 } 13653 13654 /* Get the FC event trace buffer */ 13655 if (rval == QL_SUCCESS) { 13656 if (CFG_IST(ha, CFG_ENABLE_FWFCETRACE) && 13657 (ha->fwfcetracebuf.bp != NULL)) { 13658 uint32_t cnt; 13659 uint32_t *w32 = ha->fwfcetracebuf.bp; 13660 13661 /* Sync DMA buffer. */ 13662 (void) ddi_dma_sync(ha->fwfcetracebuf.dma_handle, 0, 13663 FWFCESIZE, DDI_DMA_SYNC_FORKERNEL); 13664 13665 for (cnt = 0; cnt < FWFCESIZE / 4; cnt++) { 13666 fw->fce_trace_buf[cnt] = *w32++; 13667 } 13668 } 13669 } 13670 13671 if (rval != QL_SUCCESS) { 13672 EL(ha, "failed=%xh\n", rval); 13673 } else { 13674 /*EMPTY*/ 13675 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance); 13676 } 13677 13678 return (rval); 13679} 13680 13681/* 13682 * ql_25xx_binary_fw_dump 13683 * 13684 * Input: 13685 * ha: adapter state pointer. 13686 * fw: firmware dump context pointer. 13687 * 13688 * Returns: 13689 * ql local function return status code. 13690 * 13691 * Context: 13692 * Interrupt or Kernel context, no mailbox commands allowed. 13693 */ 13694static int 13695ql_25xx_binary_fw_dump(ql_adapter_state_t *ha, ql_25xx_fw_dump_t *fw) 13696{ 13697 uint32_t *reg32; 13698 void *bp; 13699 clock_t timer; 13700 int rval = QL_SUCCESS; 13701 13702 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance); 13703 13704 fw->r2h_status = RD32_IO_REG(ha, intr_info_lo); 13705 13706 /* Pause RISC. */ 13707 if ((RD32_IO_REG(ha, intr_info_lo) & RH_RISC_PAUSED) == 0) { 13708 /* Disable ISP interrupts. */ 13709 WRT16_IO_REG(ha, ictrl, 0); 13710 13711 WRT32_IO_REG(ha, hccr, HC24_PAUSE_RISC); 13712 for (timer = 30000; 13713 (RD32_IO_REG(ha, intr_info_lo) & RH_RISC_PAUSED) == 0 && 13714 rval == QL_SUCCESS; timer--) { 13715 if (timer) { 13716 drv_usecwait(100); 13717 if (timer % 10000 == 0) { 13718 EL(ha, "risc pause %d\n", timer); 13719 } 13720 } else { 13721 EL(ha, "risc pause timeout\n"); 13722 rval = QL_FUNCTION_TIMEOUT; 13723 } 13724 } 13725 } 13726 13727 if (rval == QL_SUCCESS) { 13728 13729 /* Host Interface registers */ 13730 13731 /* HostRisc registers. */ 13732 WRT32_IO_REG(ha, io_base_addr, 0x7000); 13733 bp = ql_read_regs(ha, fw->hostrisc_reg, ha->iobase + 0xC0, 13734 16, 32); 13735 WRT32_IO_REG(ha, io_base_addr, 0x7010); 13736 bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32); 13737 13738 /* PCIe registers. */ 13739 WRT32_IO_REG(ha, io_base_addr, 0x7c00); 13740 WRT_REG_DWORD(ha, ha->iobase + 0xc0, 0x1); 13741 bp = ql_read_regs(ha, fw->pcie_reg, ha->iobase + 0xC4, 13742 3, 32); 13743 (void) ql_read_regs(ha, bp, ha->iobase + 0xC0, 1, 32); 13744 WRT_REG_DWORD(ha, ha->iobase + 0xc0, 0x0); 13745 13746 /* Host interface registers. */ 13747 (void) ql_read_regs(ha, fw->host_reg, ha->iobase, 13748 sizeof (fw->host_reg) / 4, 32); 13749 13750 /* Disable ISP interrupts. */ 13751 13752 WRT32_IO_REG(ha, ictrl, 0); 13753 RD32_IO_REG(ha, ictrl); 13754 ADAPTER_STATE_LOCK(ha); 13755 ha->flags &= ~INTERRUPTS_ENABLED; 13756 ADAPTER_STATE_UNLOCK(ha); 13757 13758 /* Shadow registers. */ 13759 13760 WRT32_IO_REG(ha, io_base_addr, 0x0F70); 13761 RD32_IO_REG(ha, io_base_addr); 13762 13763 reg32 = (uint32_t *)((caddr_t)ha->iobase + 0xF0); 13764 WRT_REG_DWORD(ha, reg32, 0xB0000000); 13765 reg32 = (uint32_t *)((caddr_t)ha->iobase + 0xFC); 13766 fw->shadow_reg[0] = RD_REG_DWORD(ha, reg32); 13767 13768 reg32 = (uint32_t *)((caddr_t)ha->iobase + 0xF0); 13769 WRT_REG_DWORD(ha, reg32, 0xB0100000); 13770 reg32 = (uint32_t *)((caddr_t)ha->iobase + 0xFC); 13771 fw->shadow_reg[1] = RD_REG_DWORD(ha, reg32); 13772 13773 reg32 = (uint32_t *)((caddr_t)ha->iobase + 0xF0); 13774 WRT_REG_DWORD(ha, reg32, 0xB0200000); 13775 reg32 = (uint32_t *)((caddr_t)ha->iobase + 0xFC); 13776 fw->shadow_reg[2] = RD_REG_DWORD(ha, reg32); 13777 13778 reg32 = (uint32_t *)((caddr_t)ha->iobase + 0xF0); 13779 WRT_REG_DWORD(ha, reg32, 0xB0300000); 13780 reg32 = (uint32_t *)((caddr_t)ha->iobase + 0xFC); 13781 fw->shadow_reg[3] = RD_REG_DWORD(ha, reg32); 13782 13783 reg32 = (uint32_t *)((caddr_t)ha->iobase + 0xF0); 13784 WRT_REG_DWORD(ha, reg32, 0xB0400000); 13785 reg32 = (uint32_t *)((caddr_t)ha->iobase + 0xFC); 13786 fw->shadow_reg[4] = RD_REG_DWORD(ha, reg32); 13787 13788 reg32 = (uint32_t *)((caddr_t)ha->iobase + 0xF0); 13789 WRT_REG_DWORD(ha, reg32, 0xB0500000); 13790 reg32 = (uint32_t *)((caddr_t)ha->iobase + 0xFC); 13791 fw->shadow_reg[5] = RD_REG_DWORD(ha, reg32); 13792 13793 reg32 = (uint32_t *)((caddr_t)ha->iobase + 0xF0); 13794 WRT_REG_DWORD(ha, reg32, 0xB0600000); 13795 reg32 = (uint32_t *)((caddr_t)ha->iobase + 0xFC); 13796 fw->shadow_reg[6] = RD_REG_DWORD(ha, reg32); 13797 13798 reg32 = (uint32_t *)((caddr_t)ha->iobase + 0xF0); 13799 WRT_REG_DWORD(ha, reg32, 0xB0700000); 13800 reg32 = (uint32_t *)((caddr_t)ha->iobase + 0xFC); 13801 fw->shadow_reg[7] = RD_REG_DWORD(ha, reg32); 13802 13803 reg32 = (uint32_t *)((caddr_t)ha->iobase + 0xF0); 13804 WRT_REG_DWORD(ha, reg32, 0xB0800000); 13805 reg32 = (uint32_t *)((caddr_t)ha->iobase + 0xFC); 13806 fw->shadow_reg[8] = RD_REG_DWORD(ha, reg32); 13807 13808 reg32 = (uint32_t *)((caddr_t)ha->iobase + 0xF0); 13809 WRT_REG_DWORD(ha, reg32, 0xB0900000); 13810 reg32 = (uint32_t *)((caddr_t)ha->iobase + 0xFC); 13811 fw->shadow_reg[9] = RD_REG_DWORD(ha, reg32); 13812 13813 reg32 = (uint32_t *)((caddr_t)ha->iobase + 0xF0); 13814 WRT_REG_DWORD(ha, reg32, 0xB0A00000); 13815 reg32 = (uint32_t *)((caddr_t)ha->iobase + 0xFC); 13816 fw->shadow_reg[0xa] = RD_REG_DWORD(ha, reg32); 13817 13818 /* RISC I/O register. */ 13819 13820 WRT32_IO_REG(ha, io_base_addr, 0x0010); 13821 (void) ql_read_regs(ha, &fw->risc_io, ha->iobase + 0xC0, 13822 1, 32); 13823 13824 /* Mailbox registers. */ 13825 13826 (void) ql_read_regs(ha, fw->mailbox_reg, ha->iobase + 0x80, 13827 sizeof (fw->mailbox_reg) / 2, 16); 13828 13829 /* Transfer sequence registers. */ 13830 13831 /* XSEQ GP */ 13832 WRT32_IO_REG(ha, io_base_addr, 0xBF00); 13833 bp = ql_read_regs(ha, fw->xseq_gp_reg, ha->iobase + 0xC0, 13834 16, 32); 13835 WRT32_IO_REG(ha, io_base_addr, 0xBF10); 13836 bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32); 13837 WRT32_IO_REG(ha, io_base_addr, 0xBF20); 13838 bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32); 13839 WRT32_IO_REG(ha, io_base_addr, 0xBF30); 13840 bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32); 13841 WRT32_IO_REG(ha, io_base_addr, 0xBF40); 13842 bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32); 13843 WRT32_IO_REG(ha, io_base_addr, 0xBF50); 13844 bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32); 13845 WRT32_IO_REG(ha, io_base_addr, 0xBF60); 13846 bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32); 13847 WRT32_IO_REG(ha, io_base_addr, 0xBF70); 13848 (void) ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32); 13849 13850 /* XSEQ-0 */ 13851 WRT32_IO_REG(ha, io_base_addr, 0xBFC0); 13852 bp = ql_read_regs(ha, fw->xseq_0_reg, ha->iobase + 0xC0, 13853 16, 32); 13854 WRT32_IO_REG(ha, io_base_addr, 0xBFD0); 13855 bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32); 13856 WRT32_IO_REG(ha, io_base_addr, 0xBFE0); 13857 (void) ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32); 13858 13859 /* XSEQ-1 */ 13860 WRT32_IO_REG(ha, io_base_addr, 0xBFF0); 13861 (void) ql_read_regs(ha, fw->xseq_1_reg, ha->iobase + 0xC0, 13862 16, 32); 13863 13864 /* Receive sequence registers. */ 13865 13866 /* RSEQ GP */ 13867 WRT32_IO_REG(ha, io_base_addr, 0xFF00); 13868 bp = ql_read_regs(ha, fw->rseq_gp_reg, ha->iobase + 0xC0, 13869 16, 32); 13870 WRT32_IO_REG(ha, io_base_addr, 0xFF10); 13871 bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32); 13872 WRT32_IO_REG(ha, io_base_addr, 0xFF20); 13873 bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32); 13874 WRT32_IO_REG(ha, io_base_addr, 0xFF30); 13875 bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32); 13876 WRT32_IO_REG(ha, io_base_addr, 0xFF40); 13877 bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32); 13878 WRT32_IO_REG(ha, io_base_addr, 0xFF50); 13879 bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32); 13880 WRT32_IO_REG(ha, io_base_addr, 0xFF60); 13881 bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32); 13882 WRT32_IO_REG(ha, io_base_addr, 0xFF70); 13883 (void) ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32); 13884 13885 /* RSEQ-0 */ 13886 WRT32_IO_REG(ha, io_base_addr, 0xFFC0); 13887 bp = ql_read_regs(ha, fw->rseq_0_reg, ha->iobase + 0xC0, 13888 16, 32); 13889 WRT32_IO_REG(ha, io_base_addr, 0xFFD0); 13890 (void) ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32); 13891 13892 /* RSEQ-1 */ 13893 WRT32_IO_REG(ha, io_base_addr, 0xFFE0); 13894 (void) ql_read_regs(ha, fw->rseq_1_reg, ha->iobase + 0xC0, 13895 sizeof (fw->rseq_1_reg) / 4, 32); 13896 13897 /* RSEQ-2 */ 13898 WRT32_IO_REG(ha, io_base_addr, 0xFFF0); 13899 (void) ql_read_regs(ha, fw->rseq_2_reg, ha->iobase + 0xC0, 13900 sizeof (fw->rseq_2_reg) / 4, 32); 13901 13902 /* Auxiliary sequencer registers. */ 13903 13904 /* ASEQ GP */ 13905 WRT32_IO_REG(ha, io_base_addr, 0xB000); 13906 bp = ql_read_regs(ha, fw->aseq_gp_reg, ha->iobase + 0xC0, 13907 16, 32); 13908 WRT32_IO_REG(ha, io_base_addr, 0xB010); 13909 bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32); 13910 WRT32_IO_REG(ha, io_base_addr, 0xB020); 13911 bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32); 13912 WRT32_IO_REG(ha, io_base_addr, 0xB030); 13913 bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32); 13914 WRT32_IO_REG(ha, io_base_addr, 0xB040); 13915 bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32); 13916 WRT32_IO_REG(ha, io_base_addr, 0xB050); 13917 bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32); 13918 WRT32_IO_REG(ha, io_base_addr, 0xB060); 13919 bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32); 13920 WRT32_IO_REG(ha, io_base_addr, 0xB070); 13921 (void) ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32); 13922 13923 /* ASEQ-0 */ 13924 WRT32_IO_REG(ha, io_base_addr, 0xB0C0); 13925 bp = ql_read_regs(ha, fw->aseq_0_reg, ha->iobase + 0xC0, 13926 16, 32); 13927 WRT32_IO_REG(ha, io_base_addr, 0xB0D0); 13928 (void) ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32); 13929 13930 /* ASEQ-1 */ 13931 WRT32_IO_REG(ha, io_base_addr, 0xB0E0); 13932 (void) ql_read_regs(ha, fw->aseq_1_reg, ha->iobase + 0xC0, 13933 16, 32); 13934 13935 /* ASEQ-2 */ 13936 WRT32_IO_REG(ha, io_base_addr, 0xB0F0); 13937 (void) ql_read_regs(ha, fw->aseq_2_reg, ha->iobase + 0xC0, 13938 16, 32); 13939 13940 /* Command DMA registers. */ 13941 13942 WRT32_IO_REG(ha, io_base_addr, 0x7100); 13943 (void) ql_read_regs(ha, fw->cmd_dma_reg, ha->iobase + 0xC0, 13944 sizeof (fw->cmd_dma_reg) / 4, 32); 13945 13946 /* Queues. */ 13947 13948 /* RequestQ0 */ 13949 WRT32_IO_REG(ha, io_base_addr, 0x7200); 13950 bp = ql_read_regs(ha, fw->req0_dma_reg, ha->iobase + 0xC0, 13951 8, 32); 13952 (void) ql_read_regs(ha, bp, ha->iobase + 0xE4, 7, 32); 13953 13954 /* ResponseQ0 */ 13955 WRT32_IO_REG(ha, io_base_addr, 0x7300); 13956 bp = ql_read_regs(ha, fw->resp0_dma_reg, ha->iobase + 0xC0, 13957 8, 32); 13958 (void) ql_read_regs(ha, bp, ha->iobase + 0xE4, 7, 32); 13959 13960 /* RequestQ1 */ 13961 WRT32_IO_REG(ha, io_base_addr, 0x7400); 13962 bp = ql_read_regs(ha, fw->req1_dma_reg, ha->iobase + 0xC0, 13963 8, 32); 13964 (void) ql_read_regs(ha, bp, ha->iobase + 0xE4, 7, 32); 13965 13966 /* Transmit DMA registers. */ 13967 13968 /* XMT0 */ 13969 WRT32_IO_REG(ha, io_base_addr, 0x7600); 13970 bp = ql_read_regs(ha, fw->xmt0_dma_reg, ha->iobase + 0xC0, 13971 16, 32); 13972 WRT32_IO_REG(ha, io_base_addr, 0x7610); 13973 (void) ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32); 13974 13975 /* XMT1 */ 13976 WRT32_IO_REG(ha, io_base_addr, 0x7620); 13977 bp = ql_read_regs(ha, fw->xmt1_dma_reg, ha->iobase + 0xC0, 13978 16, 32); 13979 WRT32_IO_REG(ha, io_base_addr, 0x7630); 13980 (void) ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32); 13981 13982 /* XMT2 */ 13983 WRT32_IO_REG(ha, io_base_addr, 0x7640); 13984 bp = ql_read_regs(ha, fw->xmt2_dma_reg, ha->iobase + 0xC0, 13985 16, 32); 13986 WRT32_IO_REG(ha, io_base_addr, 0x7650); 13987 (void) ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32); 13988 13989 /* XMT3 */ 13990 WRT32_IO_REG(ha, io_base_addr, 0x7660); 13991 bp = ql_read_regs(ha, fw->xmt3_dma_reg, ha->iobase + 0xC0, 13992 16, 32); 13993 WRT32_IO_REG(ha, io_base_addr, 0x7670); 13994 (void) ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32); 13995 13996 /* XMT4 */ 13997 WRT32_IO_REG(ha, io_base_addr, 0x7680); 13998 bp = ql_read_regs(ha, fw->xmt4_dma_reg, ha->iobase + 0xC0, 13999 16, 32); 14000 WRT32_IO_REG(ha, io_base_addr, 0x7690); 14001 (void) ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32); 14002 14003 /* XMT Common */ 14004 WRT32_IO_REG(ha, io_base_addr, 0x76A0); 14005 (void) ql_read_regs(ha, fw->xmt_data_dma_reg, 14006 ha->iobase + 0xC0, sizeof (fw->xmt_data_dma_reg) / 4, 32); 14007 14008 /* Receive DMA registers. */ 14009 14010 /* RCVThread0 */ 14011 WRT32_IO_REG(ha, io_base_addr, 0x7700); 14012 bp = ql_read_regs(ha, fw->rcvt0_data_dma_reg, 14013 ha->iobase + 0xC0, 16, 32); 14014 WRT32_IO_REG(ha, io_base_addr, 0x7710); 14015 (void) ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32); 14016 14017 /* RCVThread1 */ 14018 WRT32_IO_REG(ha, io_base_addr, 0x7720); 14019 bp = ql_read_regs(ha, fw->rcvt1_data_dma_reg, 14020 ha->iobase + 0xC0, 16, 32); 14021 WRT32_IO_REG(ha, io_base_addr, 0x7730); 14022 (void) ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32); 14023 14024 /* RISC registers. */ 14025 14026 /* RISC GP */ 14027 WRT32_IO_REG(ha, io_base_addr, 0x0F00); 14028 bp = ql_read_regs(ha, fw->risc_gp_reg, ha->iobase + 0xC0, 14029 16, 32); 14030 WRT32_IO_REG(ha, io_base_addr, 0x0F10); 14031 bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32); 14032 WRT32_IO_REG(ha, io_base_addr, 0x0F20); 14033 bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32); 14034 WRT32_IO_REG(ha, io_base_addr, 0x0F30); 14035 bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32); 14036 WRT32_IO_REG(ha, io_base_addr, 0x0F40); 14037 bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32); 14038 WRT32_IO_REG(ha, io_base_addr, 0x0F50); 14039 bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32); 14040 WRT32_IO_REG(ha, io_base_addr, 0x0F60); 14041 bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32); 14042 WRT32_IO_REG(ha, io_base_addr, 0x0F70); 14043 (void) ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32); 14044 14045 /* Local memory controller (LMC) registers. */ 14046 14047 /* LMC */ 14048 WRT32_IO_REG(ha, io_base_addr, 0x3000); 14049 bp = ql_read_regs(ha, fw->lmc_reg, ha->iobase + 0xC0, 14050 16, 32); 14051 WRT32_IO_REG(ha, io_base_addr, 0x3010); 14052 bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32); 14053 WRT32_IO_REG(ha, io_base_addr, 0x3020); 14054 bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32); 14055 WRT32_IO_REG(ha, io_base_addr, 0x3030); 14056 bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32); 14057 WRT32_IO_REG(ha, io_base_addr, 0x3040); 14058 bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32); 14059 WRT32_IO_REG(ha, io_base_addr, 0x3050); 14060 bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32); 14061 WRT32_IO_REG(ha, io_base_addr, 0x3060); 14062 bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32); 14063 WRT32_IO_REG(ha, io_base_addr, 0x3070); 14064 (void) ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32); 14065 14066 /* Fibre Protocol Module registers. */ 14067 14068 /* FPM hardware */ 14069 WRT32_IO_REG(ha, io_base_addr, 0x4000); 14070 bp = ql_read_regs(ha, fw->fpm_hdw_reg, ha->iobase + 0xC0, 14071 16, 32); 14072 WRT32_IO_REG(ha, io_base_addr, 0x4010); 14073 bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32); 14074 WRT32_IO_REG(ha, io_base_addr, 0x4020); 14075 bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32); 14076 WRT32_IO_REG(ha, io_base_addr, 0x4030); 14077 bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32); 14078 WRT32_IO_REG(ha, io_base_addr, 0x4040); 14079 bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32); 14080 WRT32_IO_REG(ha, io_base_addr, 0x4050); 14081 bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32); 14082 WRT32_IO_REG(ha, io_base_addr, 0x4060); 14083 bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32); 14084 WRT32_IO_REG(ha, io_base_addr, 0x4070); 14085 bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32); 14086 WRT32_IO_REG(ha, io_base_addr, 0x4080); 14087 bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32); 14088 WRT32_IO_REG(ha, io_base_addr, 0x4090); 14089 bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32); 14090 WRT32_IO_REG(ha, io_base_addr, 0x40A0); 14091 bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32); 14092 WRT32_IO_REG(ha, io_base_addr, 0x40B0); 14093 (void) ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32); 14094 14095 /* Frame Buffer registers. */ 14096 14097 /* FB hardware */ 14098 WRT32_IO_REG(ha, io_base_addr, 0x6000); 14099 bp = ql_read_regs(ha, fw->fb_hdw_reg, ha->iobase + 0xC0, 14100 16, 32); 14101 WRT32_IO_REG(ha, io_base_addr, 0x6010); 14102 bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32); 14103 WRT32_IO_REG(ha, io_base_addr, 0x6020); 14104 bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32); 14105 WRT32_IO_REG(ha, io_base_addr, 0x6030); 14106 bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32); 14107 WRT32_IO_REG(ha, io_base_addr, 0x6040); 14108 bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32); 14109 WRT32_IO_REG(ha, io_base_addr, 0x6100); 14110 bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32); 14111 WRT32_IO_REG(ha, io_base_addr, 0x6130); 14112 bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32); 14113 WRT32_IO_REG(ha, io_base_addr, 0x6150); 14114 bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32); 14115 WRT32_IO_REG(ha, io_base_addr, 0x6170); 14116 bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32); 14117 WRT32_IO_REG(ha, io_base_addr, 0x6190); 14118 bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32); 14119 WRT32_IO_REG(ha, io_base_addr, 0x61B0); 14120 bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32); 14121 WRT32_IO_REG(ha, io_base_addr, 0x6F00); 14122 (void) ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32); 14123 } 14124 14125 /* Get the request queue */ 14126 if (rval == QL_SUCCESS) { 14127 uint32_t cnt; 14128 uint32_t *w32 = (uint32_t *)ha->request_ring_bp; 14129 14130 /* Sync DMA buffer. */ 14131 (void) ddi_dma_sync(ha->hba_buf.dma_handle, 14132 REQUEST_Q_BUFFER_OFFSET, sizeof (fw->req_q), 14133 DDI_DMA_SYNC_FORKERNEL); 14134 14135 for (cnt = 0; cnt < sizeof (fw->req_q) / 4; cnt++) { 14136 fw->req_q[cnt] = *w32++; 14137 LITTLE_ENDIAN_32(&fw->req_q[cnt]); 14138 } 14139 } 14140 14141 /* Get the respons queue */ 14142 if (rval == QL_SUCCESS) { 14143 uint32_t cnt; 14144 uint32_t *w32 = (uint32_t *)ha->response_ring_bp; 14145 14146 /* Sync DMA buffer. */ 14147 (void) ddi_dma_sync(ha->hba_buf.dma_handle, 14148 RESPONSE_Q_BUFFER_OFFSET, sizeof (fw->rsp_q), 14149 DDI_DMA_SYNC_FORKERNEL); 14150 14151 for (cnt = 0; cnt < sizeof (fw->rsp_q) / 4; cnt++) { 14152 fw->rsp_q[cnt] = *w32++; 14153 LITTLE_ENDIAN_32(&fw->rsp_q[cnt]); 14154 } 14155 } 14156 14157 /* Reset RISC. */ 14158 14159 ql_reset_chip(ha); 14160 14161 /* Memory. */ 14162 14163 if (rval == QL_SUCCESS) { 14164 /* Code RAM. */ 14165 rval = ql_read_risc_ram(ha, 0x20000, 14166 sizeof (fw->code_ram) / 4, fw->code_ram); 14167 } 14168 if (rval == QL_SUCCESS) { 14169 /* External Memory. */ 14170 rval = ql_read_risc_ram(ha, 0x100000, 14171 ha->fw_ext_memory_size / 4, fw->ext_mem); 14172 } 14173 14174 /* Get the FC event trace buffer */ 14175 if (rval == QL_SUCCESS) { 14176 if (CFG_IST(ha, CFG_ENABLE_FWFCETRACE) && 14177 (ha->fwfcetracebuf.bp != NULL)) { 14178 uint32_t cnt; 14179 uint32_t *w32 = ha->fwfcetracebuf.bp; 14180 14181 /* Sync DMA buffer. */ 14182 (void) ddi_dma_sync(ha->fwfcetracebuf.dma_handle, 0, 14183 FWFCESIZE, DDI_DMA_SYNC_FORKERNEL); 14184 14185 for (cnt = 0; cnt < FWFCESIZE / 4; cnt++) { 14186 fw->fce_trace_buf[cnt] = *w32++; 14187 } 14188 } 14189 } 14190 14191 /* Get the extended trace buffer */ 14192 if (rval == QL_SUCCESS) { 14193 if (CFG_IST(ha, CFG_ENABLE_FWEXTTRACE) && 14194 (ha->fwexttracebuf.bp != NULL)) { 14195 uint32_t cnt; 14196 uint32_t *w32 = ha->fwexttracebuf.bp; 14197 14198 /* Sync DMA buffer. */ 14199 (void) ddi_dma_sync(ha->fwexttracebuf.dma_handle, 0, 14200 FWEXTSIZE, DDI_DMA_SYNC_FORKERNEL); 14201 14202 for (cnt = 0; cnt < FWEXTSIZE / 4; cnt++) { 14203 fw->ext_trace_buf[cnt] = *w32++; 14204 } 14205 } 14206 } 14207 14208 if (rval != QL_SUCCESS) { 14209 EL(ha, "failed=%xh\n", rval); 14210 } else { 14211 /*EMPTY*/ 14212 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance); 14213 } 14214 14215 return (rval); 14216} 14217 14218/* 14219 * ql_81xx_binary_fw_dump 14220 * 14221 * Input: 14222 * ha: adapter state pointer. 14223 * fw: firmware dump context pointer. 14224 * 14225 * Returns: 14226 * ql local function return status code. 14227 * 14228 * Context: 14229 * Interrupt or Kernel context, no mailbox commands allowed. 14230 */ 14231static int 14232ql_81xx_binary_fw_dump(ql_adapter_state_t *ha, ql_81xx_fw_dump_t *fw) 14233{ 14234 uint32_t *reg32; 14235 void *bp; 14236 clock_t timer; 14237 int rval = QL_SUCCESS; 14238 14239 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance); 14240 14241 fw->r2h_status = RD32_IO_REG(ha, intr_info_lo); 14242 14243 /* Pause RISC. */ 14244 if ((RD32_IO_REG(ha, intr_info_lo) & RH_RISC_PAUSED) == 0) { 14245 /* Disable ISP interrupts. */ 14246 WRT16_IO_REG(ha, ictrl, 0); 14247 14248 WRT32_IO_REG(ha, hccr, HC24_PAUSE_RISC); 14249 for (timer = 30000; 14250 (RD32_IO_REG(ha, intr_info_lo) & RH_RISC_PAUSED) == 0 && 14251 rval == QL_SUCCESS; timer--) { 14252 if (timer) { 14253 drv_usecwait(100); 14254 if (timer % 10000 == 0) { 14255 EL(ha, "risc pause %d\n", timer); 14256 } 14257 } else { 14258 EL(ha, "risc pause timeout\n"); 14259 rval = QL_FUNCTION_TIMEOUT; 14260 } 14261 } 14262 } 14263 14264 if (rval == QL_SUCCESS) { 14265 14266 /* Host Interface registers */ 14267 14268 /* HostRisc registers. */ 14269 WRT32_IO_REG(ha, io_base_addr, 0x7000); 14270 bp = ql_read_regs(ha, fw->hostrisc_reg, ha->iobase + 0xC0, 14271 16, 32); 14272 WRT32_IO_REG(ha, io_base_addr, 0x7010); 14273 bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32); 14274 14275 /* PCIe registers. */ 14276 WRT32_IO_REG(ha, io_base_addr, 0x7c00); 14277 WRT_REG_DWORD(ha, ha->iobase + 0xc0, 0x1); 14278 bp = ql_read_regs(ha, fw->pcie_reg, ha->iobase + 0xC4, 14279 3, 32); 14280 (void) ql_read_regs(ha, bp, ha->iobase + 0xC0, 1, 32); 14281 WRT_REG_DWORD(ha, ha->iobase + 0xc0, 0x0); 14282 14283 /* Host interface registers. */ 14284 (void) ql_read_regs(ha, fw->host_reg, ha->iobase, 14285 sizeof (fw->host_reg) / 4, 32); 14286 14287 /* Disable ISP interrupts. */ 14288 14289 WRT32_IO_REG(ha, ictrl, 0); 14290 RD32_IO_REG(ha, ictrl); 14291 ADAPTER_STATE_LOCK(ha); 14292 ha->flags &= ~INTERRUPTS_ENABLED; 14293 ADAPTER_STATE_UNLOCK(ha); 14294 14295 /* Shadow registers. */ 14296 14297 WRT32_IO_REG(ha, io_base_addr, 0x0F70); 14298 RD32_IO_REG(ha, io_base_addr); 14299 14300 reg32 = (uint32_t *)((caddr_t)ha->iobase + 0xF0); 14301 WRT_REG_DWORD(ha, reg32, 0xB0000000); 14302 reg32 = (uint32_t *)((caddr_t)ha->iobase + 0xFC); 14303 fw->shadow_reg[0] = RD_REG_DWORD(ha, reg32); 14304 14305 reg32 = (uint32_t *)((caddr_t)ha->iobase + 0xF0); 14306 WRT_REG_DWORD(ha, reg32, 0xB0100000); 14307 reg32 = (uint32_t *)((caddr_t)ha->iobase + 0xFC); 14308 fw->shadow_reg[1] = RD_REG_DWORD(ha, reg32); 14309 14310 reg32 = (uint32_t *)((caddr_t)ha->iobase + 0xF0); 14311 WRT_REG_DWORD(ha, reg32, 0xB0200000); 14312 reg32 = (uint32_t *)((caddr_t)ha->iobase + 0xFC); 14313 fw->shadow_reg[2] = RD_REG_DWORD(ha, reg32); 14314 14315 reg32 = (uint32_t *)((caddr_t)ha->iobase + 0xF0); 14316 WRT_REG_DWORD(ha, reg32, 0xB0300000); 14317 reg32 = (uint32_t *)((caddr_t)ha->iobase + 0xFC); 14318 fw->shadow_reg[3] = RD_REG_DWORD(ha, reg32); 14319 14320 reg32 = (uint32_t *)((caddr_t)ha->iobase + 0xF0); 14321 WRT_REG_DWORD(ha, reg32, 0xB0400000); 14322 reg32 = (uint32_t *)((caddr_t)ha->iobase + 0xFC); 14323 fw->shadow_reg[4] = RD_REG_DWORD(ha, reg32); 14324 14325 reg32 = (uint32_t *)((caddr_t)ha->iobase + 0xF0); 14326 WRT_REG_DWORD(ha, reg32, 0xB0500000); 14327 reg32 = (uint32_t *)((caddr_t)ha->iobase + 0xFC); 14328 fw->shadow_reg[5] = RD_REG_DWORD(ha, reg32); 14329 14330 reg32 = (uint32_t *)((caddr_t)ha->iobase + 0xF0); 14331 WRT_REG_DWORD(ha, reg32, 0xB0600000); 14332 reg32 = (uint32_t *)((caddr_t)ha->iobase + 0xFC); 14333 fw->shadow_reg[6] = RD_REG_DWORD(ha, reg32); 14334 14335 reg32 = (uint32_t *)((caddr_t)ha->iobase + 0xF0); 14336 WRT_REG_DWORD(ha, reg32, 0xB0700000); 14337 reg32 = (uint32_t *)((caddr_t)ha->iobase + 0xFC); 14338 fw->shadow_reg[7] = RD_REG_DWORD(ha, reg32); 14339 14340 reg32 = (uint32_t *)((caddr_t)ha->iobase + 0xF0); 14341 WRT_REG_DWORD(ha, reg32, 0xB0800000); 14342 reg32 = (uint32_t *)((caddr_t)ha->iobase + 0xFC); 14343 fw->shadow_reg[8] = RD_REG_DWORD(ha, reg32); 14344 14345 reg32 = (uint32_t *)((caddr_t)ha->iobase + 0xF0); 14346 WRT_REG_DWORD(ha, reg32, 0xB0900000); 14347 reg32 = (uint32_t *)((caddr_t)ha->iobase + 0xFC); 14348 fw->shadow_reg[9] = RD_REG_DWORD(ha, reg32); 14349 14350 reg32 = (uint32_t *)((caddr_t)ha->iobase + 0xF0); 14351 WRT_REG_DWORD(ha, reg32, 0xB0A00000); 14352 reg32 = (uint32_t *)((caddr_t)ha->iobase + 0xFC); 14353 fw->shadow_reg[0xa] = RD_REG_DWORD(ha, reg32); 14354 14355 /* RISC I/O register. */ 14356 14357 WRT32_IO_REG(ha, io_base_addr, 0x0010); 14358 (void) ql_read_regs(ha, &fw->risc_io, ha->iobase + 0xC0, 14359 1, 32); 14360 14361 /* Mailbox registers. */ 14362 14363 (void) ql_read_regs(ha, fw->mailbox_reg, ha->iobase + 0x80, 14364 sizeof (fw->mailbox_reg) / 2, 16); 14365 14366 /* Transfer sequence registers. */ 14367 14368 /* XSEQ GP */ 14369 WRT32_IO_REG(ha, io_base_addr, 0xBF00); 14370 bp = ql_read_regs(ha, fw->xseq_gp_reg, ha->iobase + 0xC0, 14371 16, 32); 14372 WRT32_IO_REG(ha, io_base_addr, 0xBF10); 14373 bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32); 14374 WRT32_IO_REG(ha, io_base_addr, 0xBF20); 14375 bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32); 14376 WRT32_IO_REG(ha, io_base_addr, 0xBF30); 14377 bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32); 14378 WRT32_IO_REG(ha, io_base_addr, 0xBF40); 14379 bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32); 14380 WRT32_IO_REG(ha, io_base_addr, 0xBF50); 14381 bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32); 14382 WRT32_IO_REG(ha, io_base_addr, 0xBF60); 14383 bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32); 14384 WRT32_IO_REG(ha, io_base_addr, 0xBF70); 14385 (void) ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32); 14386 14387 /* XSEQ-0 */ 14388 WRT32_IO_REG(ha, io_base_addr, 0xBFC0); 14389 bp = ql_read_regs(ha, fw->xseq_0_reg, ha->iobase + 0xC0, 14390 16, 32); 14391 WRT32_IO_REG(ha, io_base_addr, 0xBFD0); 14392 bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32); 14393 WRT32_IO_REG(ha, io_base_addr, 0xBFE0); 14394 (void) ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32); 14395 14396 /* XSEQ-1 */ 14397 WRT32_IO_REG(ha, io_base_addr, 0xBFF0); 14398 (void) ql_read_regs(ha, fw->xseq_1_reg, ha->iobase + 0xC0, 14399 16, 32); 14400 14401 /* Receive sequence registers. */ 14402 14403 /* RSEQ GP */ 14404 WRT32_IO_REG(ha, io_base_addr, 0xFF00); 14405 bp = ql_read_regs(ha, fw->rseq_gp_reg, ha->iobase + 0xC0, 14406 16, 32); 14407 WRT32_IO_REG(ha, io_base_addr, 0xFF10); 14408 bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32); 14409 WRT32_IO_REG(ha, io_base_addr, 0xFF20); 14410 bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32); 14411 WRT32_IO_REG(ha, io_base_addr, 0xFF30); 14412 bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32); 14413 WRT32_IO_REG(ha, io_base_addr, 0xFF40); 14414 bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32); 14415 WRT32_IO_REG(ha, io_base_addr, 0xFF50); 14416 bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32); 14417 WRT32_IO_REG(ha, io_base_addr, 0xFF60); 14418 bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32); 14419 WRT32_IO_REG(ha, io_base_addr, 0xFF70); 14420 (void) ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32); 14421 14422 /* RSEQ-0 */ 14423 WRT32_IO_REG(ha, io_base_addr, 0xFFC0); 14424 bp = ql_read_regs(ha, fw->rseq_0_reg, ha->iobase + 0xC0, 14425 16, 32); 14426 WRT32_IO_REG(ha, io_base_addr, 0xFFD0); 14427 (void) ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32); 14428 14429 /* RSEQ-1 */ 14430 WRT32_IO_REG(ha, io_base_addr, 0xFFE0); 14431 (void) ql_read_regs(ha, fw->rseq_1_reg, ha->iobase + 0xC0, 14432 sizeof (fw->rseq_1_reg) / 4, 32); 14433 14434 /* RSEQ-2 */ 14435 WRT32_IO_REG(ha, io_base_addr, 0xFFF0); 14436 (void) ql_read_regs(ha, fw->rseq_2_reg, ha->iobase + 0xC0, 14437 sizeof (fw->rseq_2_reg) / 4, 32); 14438 14439 /* Auxiliary sequencer registers. */ 14440 14441 /* ASEQ GP */ 14442 WRT32_IO_REG(ha, io_base_addr, 0xB000); 14443 bp = ql_read_regs(ha, fw->aseq_gp_reg, ha->iobase + 0xC0, 14444 16, 32); 14445 WRT32_IO_REG(ha, io_base_addr, 0xB010); 14446 bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32); 14447 WRT32_IO_REG(ha, io_base_addr, 0xB020); 14448 bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32); 14449 WRT32_IO_REG(ha, io_base_addr, 0xB030); 14450 bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32); 14451 WRT32_IO_REG(ha, io_base_addr, 0xB040); 14452 bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32); 14453 WRT32_IO_REG(ha, io_base_addr, 0xB050); 14454 bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32); 14455 WRT32_IO_REG(ha, io_base_addr, 0xB060); 14456 bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32); 14457 WRT32_IO_REG(ha, io_base_addr, 0xB070); 14458 (void) ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32); 14459 14460 /* ASEQ-0 */ 14461 WRT32_IO_REG(ha, io_base_addr, 0xB0C0); 14462 bp = ql_read_regs(ha, fw->aseq_0_reg, ha->iobase + 0xC0, 14463 16, 32); 14464 WRT32_IO_REG(ha, io_base_addr, 0xB0D0); 14465 (void) ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32); 14466 14467 /* ASEQ-1 */ 14468 WRT32_IO_REG(ha, io_base_addr, 0xB0E0); 14469 (void) ql_read_regs(ha, fw->aseq_1_reg, ha->iobase + 0xC0, 14470 16, 32); 14471 14472 /* ASEQ-2 */ 14473 WRT32_IO_REG(ha, io_base_addr, 0xB0F0); 14474 (void) ql_read_regs(ha, fw->aseq_2_reg, ha->iobase + 0xC0, 14475 16, 32); 14476 14477 /* Command DMA registers. */ 14478 14479 WRT32_IO_REG(ha, io_base_addr, 0x7100); 14480 (void) ql_read_regs(ha, fw->cmd_dma_reg, ha->iobase + 0xC0, 14481 sizeof (fw->cmd_dma_reg) / 4, 32); 14482 14483 /* Queues. */ 14484 14485 /* RequestQ0 */ 14486 WRT32_IO_REG(ha, io_base_addr, 0x7200); 14487 bp = ql_read_regs(ha, fw->req0_dma_reg, ha->iobase + 0xC0, 14488 8, 32); 14489 (void) ql_read_regs(ha, bp, ha->iobase + 0xE4, 7, 32); 14490 14491 /* ResponseQ0 */ 14492 WRT32_IO_REG(ha, io_base_addr, 0x7300); 14493 bp = ql_read_regs(ha, fw->resp0_dma_reg, ha->iobase + 0xC0, 14494 8, 32); 14495 (void) ql_read_regs(ha, bp, ha->iobase + 0xE4, 7, 32); 14496 14497 /* RequestQ1 */ 14498 WRT32_IO_REG(ha, io_base_addr, 0x7400); 14499 bp = ql_read_regs(ha, fw->req1_dma_reg, ha->iobase + 0xC0, 14500 8, 32); 14501 (void) ql_read_regs(ha, bp, ha->iobase + 0xE4, 7, 32); 14502 14503 /* Transmit DMA registers. */ 14504 14505 /* XMT0 */ 14506 WRT32_IO_REG(ha, io_base_addr, 0x7600); 14507 bp = ql_read_regs(ha, fw->xmt0_dma_reg, ha->iobase + 0xC0, 14508 16, 32); 14509 WRT32_IO_REG(ha, io_base_addr, 0x7610); 14510 (void) ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32); 14511 14512 /* XMT1 */ 14513 WRT32_IO_REG(ha, io_base_addr, 0x7620); 14514 bp = ql_read_regs(ha, fw->xmt1_dma_reg, ha->iobase + 0xC0, 14515 16, 32); 14516 WRT32_IO_REG(ha, io_base_addr, 0x7630); 14517 (void) ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32); 14518 14519 /* XMT2 */ 14520 WRT32_IO_REG(ha, io_base_addr, 0x7640); 14521 bp = ql_read_regs(ha, fw->xmt2_dma_reg, ha->iobase + 0xC0, 14522 16, 32); 14523 WRT32_IO_REG(ha, io_base_addr, 0x7650); 14524 (void) ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32); 14525 14526 /* XMT3 */ 14527 WRT32_IO_REG(ha, io_base_addr, 0x7660); 14528 bp = ql_read_regs(ha, fw->xmt3_dma_reg, ha->iobase + 0xC0, 14529 16, 32); 14530 WRT32_IO_REG(ha, io_base_addr, 0x7670); 14531 (void) ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32); 14532 14533 /* XMT4 */ 14534 WRT32_IO_REG(ha, io_base_addr, 0x7680); 14535 bp = ql_read_regs(ha, fw->xmt4_dma_reg, ha->iobase + 0xC0, 14536 16, 32); 14537 WRT32_IO_REG(ha, io_base_addr, 0x7690); 14538 (void) ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32); 14539 14540 /* XMT Common */ 14541 WRT32_IO_REG(ha, io_base_addr, 0x76A0); 14542 (void) ql_read_regs(ha, fw->xmt_data_dma_reg, 14543 ha->iobase + 0xC0, sizeof (fw->xmt_data_dma_reg) / 4, 32); 14544 14545 /* Receive DMA registers. */ 14546 14547 /* RCVThread0 */ 14548 WRT32_IO_REG(ha, io_base_addr, 0x7700); 14549 bp = ql_read_regs(ha, fw->rcvt0_data_dma_reg, 14550 ha->iobase + 0xC0, 16, 32); 14551 WRT32_IO_REG(ha, io_base_addr, 0x7710); 14552 (void) ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32); 14553 14554 /* RCVThread1 */ 14555 WRT32_IO_REG(ha, io_base_addr, 0x7720); 14556 bp = ql_read_regs(ha, fw->rcvt1_data_dma_reg, 14557 ha->iobase + 0xC0, 16, 32); 14558 WRT32_IO_REG(ha, io_base_addr, 0x7730); 14559 (void) ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32); 14560 14561 /* RISC registers. */ 14562 14563 /* RISC GP */ 14564 WRT32_IO_REG(ha, io_base_addr, 0x0F00); 14565 bp = ql_read_regs(ha, fw->risc_gp_reg, ha->iobase + 0xC0, 14566 16, 32); 14567 WRT32_IO_REG(ha, io_base_addr, 0x0F10); 14568 bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32); 14569 WRT32_IO_REG(ha, io_base_addr, 0x0F20); 14570 bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32); 14571 WRT32_IO_REG(ha, io_base_addr, 0x0F30); 14572 bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32); 14573 WRT32_IO_REG(ha, io_base_addr, 0x0F40); 14574 bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32); 14575 WRT32_IO_REG(ha, io_base_addr, 0x0F50); 14576 bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32); 14577 WRT32_IO_REG(ha, io_base_addr, 0x0F60); 14578 bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32); 14579 WRT32_IO_REG(ha, io_base_addr, 0x0F70); 14580 (void) ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32); 14581 14582 /* Local memory controller (LMC) registers. */ 14583 14584 /* LMC */ 14585 WRT32_IO_REG(ha, io_base_addr, 0x3000); 14586 bp = ql_read_regs(ha, fw->lmc_reg, ha->iobase + 0xC0, 14587 16, 32); 14588 WRT32_IO_REG(ha, io_base_addr, 0x3010); 14589 bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32); 14590 WRT32_IO_REG(ha, io_base_addr, 0x3020); 14591 bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32); 14592 WRT32_IO_REG(ha, io_base_addr, 0x3030); 14593 bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32); 14594 WRT32_IO_REG(ha, io_base_addr, 0x3040); 14595 bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32); 14596 WRT32_IO_REG(ha, io_base_addr, 0x3050); 14597 bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32); 14598 WRT32_IO_REG(ha, io_base_addr, 0x3060); 14599 bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32); 14600 WRT32_IO_REG(ha, io_base_addr, 0x3070); 14601 (void) ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32); 14602 14603 /* Fibre Protocol Module registers. */ 14604 14605 /* FPM hardware */ 14606 WRT32_IO_REG(ha, io_base_addr, 0x4000); 14607 bp = ql_read_regs(ha, fw->fpm_hdw_reg, ha->iobase + 0xC0, 14608 16, 32); 14609 WRT32_IO_REG(ha, io_base_addr, 0x4010); 14610 bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32); 14611 WRT32_IO_REG(ha, io_base_addr, 0x4020); 14612 bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32); 14613 WRT32_IO_REG(ha, io_base_addr, 0x4030); 14614 bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32); 14615 WRT32_IO_REG(ha, io_base_addr, 0x4040); 14616 bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32); 14617 WRT32_IO_REG(ha, io_base_addr, 0x4050); 14618 bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32); 14619 WRT32_IO_REG(ha, io_base_addr, 0x4060); 14620 bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32); 14621 WRT32_IO_REG(ha, io_base_addr, 0x4070); 14622 bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32); 14623 WRT32_IO_REG(ha, io_base_addr, 0x4080); 14624 bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32); 14625 WRT32_IO_REG(ha, io_base_addr, 0x4090); 14626 bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32); 14627 WRT32_IO_REG(ha, io_base_addr, 0x40A0); 14628 bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32); 14629 WRT32_IO_REG(ha, io_base_addr, 0x40B0); 14630 bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32); 14631 WRT32_IO_REG(ha, io_base_addr, 0x40C0); 14632 bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32); 14633 WRT32_IO_REG(ha, io_base_addr, 0x40D0); 14634 (void) ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32); 14635 14636 /* Frame Buffer registers. */ 14637 14638 /* FB hardware */ 14639 WRT32_IO_REG(ha, io_base_addr, 0x6000); 14640 bp = ql_read_regs(ha, fw->fb_hdw_reg, ha->iobase + 0xC0, 14641 16, 32); 14642 WRT32_IO_REG(ha, io_base_addr, 0x6010); 14643 bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32); 14644 WRT32_IO_REG(ha, io_base_addr, 0x6020); 14645 bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32); 14646 WRT32_IO_REG(ha, io_base_addr, 0x6030); 14647 bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32); 14648 WRT32_IO_REG(ha, io_base_addr, 0x6040); 14649 bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32); 14650 WRT32_IO_REG(ha, io_base_addr, 0x6100); 14651 bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32); 14652 WRT32_IO_REG(ha, io_base_addr, 0x6130); 14653 bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32); 14654 WRT32_IO_REG(ha, io_base_addr, 0x6150); 14655 bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32); 14656 WRT32_IO_REG(ha, io_base_addr, 0x6170); 14657 bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32); 14658 WRT32_IO_REG(ha, io_base_addr, 0x6190); 14659 bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32); 14660 WRT32_IO_REG(ha, io_base_addr, 0x61B0); 14661 bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32); 14662 WRT32_IO_REG(ha, io_base_addr, 0x61C0); 14663 bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32); 14664 WRT32_IO_REG(ha, io_base_addr, 0x6F00); 14665 (void) ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32); 14666 } 14667 14668 /* Get the request queue */ 14669 if (rval == QL_SUCCESS) { 14670 uint32_t cnt; 14671 uint32_t *w32 = (uint32_t *)ha->request_ring_bp; 14672 14673 /* Sync DMA buffer. */ 14674 (void) ddi_dma_sync(ha->hba_buf.dma_handle, 14675 REQUEST_Q_BUFFER_OFFSET, sizeof (fw->req_q), 14676 DDI_DMA_SYNC_FORKERNEL); 14677 14678 for (cnt = 0; cnt < sizeof (fw->req_q) / 4; cnt++) { 14679 fw->req_q[cnt] = *w32++; 14680 LITTLE_ENDIAN_32(&fw->req_q[cnt]); 14681 } 14682 } 14683 14684 /* Get the respons queue */ 14685 if (rval == QL_SUCCESS) { 14686 uint32_t cnt; 14687 uint32_t *w32 = (uint32_t *)ha->response_ring_bp; 14688 14689 /* Sync DMA buffer. */ 14690 (void) ddi_dma_sync(ha->hba_buf.dma_handle, 14691 RESPONSE_Q_BUFFER_OFFSET, sizeof (fw->rsp_q), 14692 DDI_DMA_SYNC_FORKERNEL); 14693 14694 for (cnt = 0; cnt < sizeof (fw->rsp_q) / 4; cnt++) { 14695 fw->rsp_q[cnt] = *w32++; 14696 LITTLE_ENDIAN_32(&fw->rsp_q[cnt]); 14697 } 14698 } 14699 14700 /* Reset RISC. */ 14701 14702 ql_reset_chip(ha); 14703 14704 /* Memory. */ 14705 14706 if (rval == QL_SUCCESS) { 14707 /* Code RAM. */ 14708 rval = ql_read_risc_ram(ha, 0x20000, 14709 sizeof (fw->code_ram) / 4, fw->code_ram); 14710 } 14711 if (rval == QL_SUCCESS) { 14712 /* External Memory. */ 14713 rval = ql_read_risc_ram(ha, 0x100000, 14714 ha->fw_ext_memory_size / 4, fw->ext_mem); 14715 } 14716 14717 /* Get the FC event trace buffer */ 14718 if (rval == QL_SUCCESS) { 14719 if (CFG_IST(ha, CFG_ENABLE_FWFCETRACE) && 14720 (ha->fwfcetracebuf.bp != NULL)) { 14721 uint32_t cnt; 14722 uint32_t *w32 = ha->fwfcetracebuf.bp; 14723 14724 /* Sync DMA buffer. */ 14725 (void) ddi_dma_sync(ha->fwfcetracebuf.dma_handle, 0, 14726 FWFCESIZE, DDI_DMA_SYNC_FORKERNEL); 14727 14728 for (cnt = 0; cnt < FWFCESIZE / 4; cnt++) { 14729 fw->fce_trace_buf[cnt] = *w32++; 14730 } 14731 } 14732 } 14733 14734 /* Get the extended trace buffer */ 14735 if (rval == QL_SUCCESS) { 14736 if (CFG_IST(ha, CFG_ENABLE_FWEXTTRACE) && 14737 (ha->fwexttracebuf.bp != NULL)) { 14738 uint32_t cnt; 14739 uint32_t *w32 = ha->fwexttracebuf.bp; 14740 14741 /* Sync DMA buffer. */ 14742 (void) ddi_dma_sync(ha->fwexttracebuf.dma_handle, 0, 14743 FWEXTSIZE, DDI_DMA_SYNC_FORKERNEL); 14744 14745 for (cnt = 0; cnt < FWEXTSIZE / 4; cnt++) { 14746 fw->ext_trace_buf[cnt] = *w32++; 14747 } 14748 } 14749 } 14750 14751 if (rval != QL_SUCCESS) { 14752 EL(ha, "failed=%xh\n", rval); 14753 } else { 14754 /*EMPTY*/ 14755 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance); 14756 } 14757 14758 return (rval); 14759} 14760 14761/* 14762 * ql_read_risc_ram 14763 * Reads RISC RAM one word at a time. 14764 * Risc interrupts must be disabled when this routine is called. 14765 * 14766 * Input: 14767 * ha: adapter state pointer. 14768 * risc_address: RISC code start address. 14769 * len: Number of words. 14770 * buf: buffer pointer. 14771 * 14772 * Returns: 14773 * ql local function return status code. 14774 * 14775 * Context: 14776 * Interrupt or Kernel context, no mailbox commands allowed. 14777 */ 14778static int 14779ql_read_risc_ram(ql_adapter_state_t *ha, uint32_t risc_address, uint32_t len, 14780 void *buf) 14781{ 14782 uint32_t cnt; 14783 uint16_t stat; 14784 clock_t timer; 14785 uint16_t *buf16 = (uint16_t *)buf; 14786 uint32_t *buf32 = (uint32_t *)buf; 14787 int rval = QL_SUCCESS; 14788 14789 for (cnt = 0; cnt < len; cnt++, risc_address++) { 14790 WRT16_IO_REG(ha, mailbox[0], MBC_READ_RAM_EXTENDED); 14791 WRT16_IO_REG(ha, mailbox[1], LSW(risc_address)); 14792 WRT16_IO_REG(ha, mailbox[8], MSW(risc_address)); 14793 CFG_IST(ha, CFG_CTRL_242581) ? 14794 WRT32_IO_REG(ha, hccr, HC24_SET_HOST_INT) : 14795 WRT16_IO_REG(ha, hccr, HC_SET_HOST_INT); 14796 for (timer = 6000000; timer && rval == QL_SUCCESS; timer--) { 14797 if (RD16_IO_REG(ha, istatus) & RISC_INT) { 14798 stat = (uint16_t) 14799 (RD16_IO_REG(ha, intr_info_lo) & 0xff); 14800 if ((stat == 1) || (stat == 0x10)) { 14801 if (CFG_IST(ha, CFG_CTRL_242581)) { 14802 buf32[cnt] = SHORT_TO_LONG( 14803 RD16_IO_REG(ha, 14804 mailbox[2]), 14805 RD16_IO_REG(ha, 14806 mailbox[3])); 14807 } else { 14808 buf16[cnt] = 14809 RD16_IO_REG(ha, mailbox[2]); 14810 } 14811 14812 break; 14813 } else if ((stat == 2) || (stat == 0x11)) { 14814 rval = RD16_IO_REG(ha, mailbox[0]); 14815 break; 14816 } 14817 if (CFG_IST(ha, CFG_CTRL_242581)) { 14818 WRT32_IO_REG(ha, hccr, 14819 HC24_CLR_RISC_INT); 14820 RD32_IO_REG(ha, hccr); 14821 } else { 14822 WRT16_IO_REG(ha, hccr, 14823 HC_CLR_RISC_INT); 14824 } 14825 } 14826 drv_usecwait(5); 14827 } 14828 if (CFG_IST(ha, CFG_CTRL_242581)) { 14829 WRT32_IO_REG(ha, hccr, HC24_CLR_RISC_INT); 14830 RD32_IO_REG(ha, hccr); 14831 } else { 14832 WRT16_IO_REG(ha, hccr, HC_CLR_RISC_INT); 14833 WRT16_IO_REG(ha, semaphore, 0); 14834 } 14835 14836 if (timer == 0) { 14837 rval = QL_FUNCTION_TIMEOUT; 14838 } 14839 } 14840 14841 return (rval); 14842} 14843 14844/* 14845 * ql_read_regs 14846 * Reads adapter registers to buffer. 14847 * 14848 * Input: 14849 * ha: adapter state pointer. 14850 * buf: buffer pointer. 14851 * reg: start address. 14852 * count: number of registers. 14853 * wds: register size. 14854 * 14855 * Context: 14856 * Interrupt or Kernel context, no mailbox commands allowed. 14857 */ 14858static void * 14859ql_read_regs(ql_adapter_state_t *ha, void *buf, void *reg, uint32_t count, 14860 uint8_t wds) 14861{ 14862 uint32_t *bp32, *reg32; 14863 uint16_t *bp16, *reg16; 14864 uint8_t *bp8, *reg8; 14865 14866 switch (wds) { 14867 case 32: 14868 bp32 = buf; 14869 reg32 = reg; 14870 while (count--) { 14871 *bp32++ = RD_REG_DWORD(ha, reg32++); 14872 } 14873 return (bp32); 14874 case 16: 14875 bp16 = buf; 14876 reg16 = reg; 14877 while (count--) { 14878 *bp16++ = RD_REG_WORD(ha, reg16++); 14879 } 14880 return (bp16); 14881 case 8: 14882 bp8 = buf; 14883 reg8 = reg; 14884 while (count--) { 14885 *bp8++ = RD_REG_BYTE(ha, reg8++); 14886 } 14887 return (bp8); 14888 default: 14889 EL(ha, "Unknown word size=%d\n", wds); 14890 return (buf); 14891 } 14892} 14893 14894static int 14895ql_save_config_regs(dev_info_t *dip) 14896{ 14897 ql_adapter_state_t *ha; 14898 int ret; 14899 ql_config_space_t chs; 14900 caddr_t prop = "ql-config-space"; 14901 14902 ha = ddi_get_soft_state(ql_state, ddi_get_instance(dip)); 14903 if (ha == NULL) { 14904 QL_PRINT_2(CE_CONT, "(%d): no adapter\n", 14905 ddi_get_instance(dip)); 14906 return (DDI_FAILURE); 14907 } 14908 14909 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance); 14910 14911 /*LINTED [Solaris DDI_DEV_T_ANY Lint warning]*/ 14912 if (ddi_prop_exists(DDI_DEV_T_ANY, dip, DDI_PROP_DONTPASS, prop) == 14913 1) { 14914 QL_PRINT_2(CE_CONT, "(%d): no prop exit\n", ha->instance); 14915 return (DDI_SUCCESS); 14916 } 14917 14918 chs.chs_command = (uint16_t)ql_pci_config_get16(ha, PCI_CONF_COMM); 14919 chs.chs_header_type = (uint8_t)ql_pci_config_get8(ha, 14920 PCI_CONF_HEADER); 14921 if ((chs.chs_header_type & PCI_HEADER_TYPE_M) == PCI_HEADER_ONE) { 14922 chs.chs_bridge_control = (uint8_t)ql_pci_config_get8(ha, 14923 PCI_BCNF_BCNTRL); 14924 } 14925 14926 chs.chs_cache_line_size = (uint8_t)ql_pci_config_get8(ha, 14927 PCI_CONF_CACHE_LINESZ); 14928 14929 chs.chs_latency_timer = (uint8_t)ql_pci_config_get8(ha, 14930 PCI_CONF_LATENCY_TIMER); 14931 14932 if ((chs.chs_header_type & PCI_HEADER_TYPE_M) == PCI_HEADER_ONE) { 14933 chs.chs_sec_latency_timer = (uint8_t)ql_pci_config_get8(ha, 14934 PCI_BCNF_LATENCY_TIMER); 14935 } 14936 14937 chs.chs_base0 = ql_pci_config_get32(ha, PCI_CONF_BASE0); 14938 chs.chs_base1 = ql_pci_config_get32(ha, PCI_CONF_BASE1); 14939 chs.chs_base2 = ql_pci_config_get32(ha, PCI_CONF_BASE2); 14940 chs.chs_base3 = ql_pci_config_get32(ha, PCI_CONF_BASE3); 14941 chs.chs_base4 = ql_pci_config_get32(ha, PCI_CONF_BASE4); 14942 chs.chs_base5 = ql_pci_config_get32(ha, PCI_CONF_BASE5); 14943 14944 /*LINTED [Solaris DDI_DEV_T_NONE Lint warning]*/ 14945 ret = ndi_prop_update_byte_array(DDI_DEV_T_NONE, dip, prop, 14946 (uchar_t *)&chs, sizeof (ql_config_space_t)); 14947 14948 if (ret != DDI_PROP_SUCCESS) { 14949 cmn_err(CE_WARN, "!Qlogic %s(%d) can't update prop %s", 14950 QL_NAME, ddi_get_instance(dip), prop); 14951 return (DDI_FAILURE); 14952 } 14953 14954 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance); 14955 14956 return (DDI_SUCCESS); 14957} 14958 14959static int 14960ql_restore_config_regs(dev_info_t *dip) 14961{ 14962 ql_adapter_state_t *ha; 14963 uint_t elements; 14964 ql_config_space_t *chs_p; 14965 caddr_t prop = "ql-config-space"; 14966 14967 ha = ddi_get_soft_state(ql_state, ddi_get_instance(dip)); 14968 if (ha == NULL) { 14969 QL_PRINT_2(CE_CONT, "(%d): no adapter\n", 14970 ddi_get_instance(dip)); 14971 return (DDI_FAILURE); 14972 } 14973 14974 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance); 14975 14976 /*LINTED [Solaris DDI_DEV_T_ANY Lint warning]*/ 14977 if (ddi_prop_lookup_byte_array(DDI_DEV_T_ANY, dip, 14978 DDI_PROP_DONTPASS | DDI_PROP_NOTPROM, prop, 14979 (uchar_t **)&chs_p, &elements) != DDI_PROP_SUCCESS) { 14980 QL_PRINT_2(CE_CONT, "(%d): no prop exit\n", ha->instance); 14981 return (DDI_FAILURE); 14982 } 14983 14984 ql_pci_config_put16(ha, PCI_CONF_COMM, chs_p->chs_command); 14985 14986 if ((chs_p->chs_header_type & PCI_HEADER_TYPE_M) == PCI_HEADER_ONE) { 14987 ql_pci_config_put16(ha, PCI_BCNF_BCNTRL, 14988 chs_p->chs_bridge_control); 14989 } 14990 14991 ql_pci_config_put8(ha, PCI_CONF_CACHE_LINESZ, 14992 chs_p->chs_cache_line_size); 14993 14994 ql_pci_config_put8(ha, PCI_CONF_LATENCY_TIMER, 14995 chs_p->chs_latency_timer); 14996 14997 if ((chs_p->chs_header_type & PCI_HEADER_TYPE_M) == PCI_HEADER_ONE) { 14998 ql_pci_config_put8(ha, PCI_BCNF_LATENCY_TIMER, 14999 chs_p->chs_sec_latency_timer); 15000 } 15001 15002 ql_pci_config_put32(ha, PCI_CONF_BASE0, chs_p->chs_base0); 15003 ql_pci_config_put32(ha, PCI_CONF_BASE1, chs_p->chs_base1); 15004 ql_pci_config_put32(ha, PCI_CONF_BASE2, chs_p->chs_base2); 15005 ql_pci_config_put32(ha, PCI_CONF_BASE3, chs_p->chs_base3); 15006 ql_pci_config_put32(ha, PCI_CONF_BASE4, chs_p->chs_base4); 15007 ql_pci_config_put32(ha, PCI_CONF_BASE5, chs_p->chs_base5); 15008 15009 ddi_prop_free(chs_p); 15010 15011 /*LINTED [Solaris DDI_DEV_T_NONE Lint warning]*/ 15012 if (ndi_prop_remove(DDI_DEV_T_NONE, dip, prop) != DDI_PROP_SUCCESS) { 15013 cmn_err(CE_WARN, "!Qlogic %s(%d): can't remove prop %s", 15014 QL_NAME, ddi_get_instance(dip), prop); 15015 } 15016 15017 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance); 15018 15019 return (DDI_SUCCESS); 15020} 15021 15022uint8_t 15023ql_pci_config_get8(ql_adapter_state_t *ha, off_t off) 15024{ 15025 if (CFG_IST(ha, CFG_SBUS_CARD)) { 15026 return (ddi_get8(ha->sbus_config_handle, 15027 (uint8_t *)(ha->sbus_config_base + off))); 15028 } 15029 15030#ifdef KERNEL_32 15031 return (pci_config_getb(ha->pci_handle, off)); 15032#else 15033 return (pci_config_get8(ha->pci_handle, off)); 15034#endif 15035} 15036 15037uint16_t 15038ql_pci_config_get16(ql_adapter_state_t *ha, off_t off) 15039{ 15040 if (CFG_IST(ha, CFG_SBUS_CARD)) { 15041 return (ddi_get16(ha->sbus_config_handle, 15042 (uint16_t *)(ha->sbus_config_base + off))); 15043 } 15044 15045#ifdef KERNEL_32 15046 return (pci_config_getw(ha->pci_handle, off)); 15047#else 15048 return (pci_config_get16(ha->pci_handle, off)); 15049#endif 15050} 15051 15052uint32_t 15053ql_pci_config_get32(ql_adapter_state_t *ha, off_t off) 15054{ 15055 if (CFG_IST(ha, CFG_SBUS_CARD)) { 15056 return (ddi_get32(ha->sbus_config_handle, 15057 (uint32_t *)(ha->sbus_config_base + off))); 15058 } 15059 15060#ifdef KERNEL_32 15061 return (pci_config_getl(ha->pci_handle, off)); 15062#else 15063 return (pci_config_get32(ha->pci_handle, off)); 15064#endif 15065} 15066 15067void 15068ql_pci_config_put8(ql_adapter_state_t *ha, off_t off, uint8_t val) 15069{ 15070 if (CFG_IST(ha, CFG_SBUS_CARD)) { 15071 ddi_put8(ha->sbus_config_handle, 15072 (uint8_t *)(ha->sbus_config_base + off), val); 15073 } else { 15074#ifdef KERNEL_32 15075 pci_config_putb(ha->pci_handle, off, val); 15076#else 15077 pci_config_put8(ha->pci_handle, off, val); 15078#endif 15079 } 15080} 15081 15082void 15083ql_pci_config_put16(ql_adapter_state_t *ha, off_t off, uint16_t val) 15084{ 15085 if (CFG_IST(ha, CFG_SBUS_CARD)) { 15086 ddi_put16(ha->sbus_config_handle, 15087 (uint16_t *)(ha->sbus_config_base + off), val); 15088 } else { 15089#ifdef KERNEL_32 15090 pci_config_putw(ha->pci_handle, off, val); 15091#else 15092 pci_config_put16(ha->pci_handle, off, val); 15093#endif 15094 } 15095} 15096 15097void 15098ql_pci_config_put32(ql_adapter_state_t *ha, off_t off, uint32_t val) 15099{ 15100 if (CFG_IST(ha, CFG_SBUS_CARD)) { 15101 ddi_put32(ha->sbus_config_handle, 15102 (uint32_t *)(ha->sbus_config_base + off), val); 15103 } else { 15104#ifdef KERNEL_32 15105 pci_config_putl(ha->pci_handle, off, val); 15106#else 15107 pci_config_put32(ha->pci_handle, off, val); 15108#endif 15109 } 15110} 15111 15112/* 15113 * ql_halt 15114 * Waits for commands that are running to finish and 15115 * if they do not, commands are aborted. 15116 * Finally the adapter is reset. 15117 * 15118 * Input: 15119 * ha: adapter state pointer. 15120 * pwr: power state. 15121 * 15122 * Context: 15123 * Kernel context. 15124 */ 15125static void 15126ql_halt(ql_adapter_state_t *ha, int pwr) 15127{ 15128 uint32_t cnt; 15129 ql_tgt_t *tq; 15130 ql_srb_t *sp; 15131 uint16_t index; 15132 ql_link_t *link; 15133 15134 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance); 15135 15136 /* Wait for all commands running to finish. */ 15137 for (index = 0; index < DEVICE_HEAD_LIST_SIZE; index++) { 15138 for (link = ha->dev[index].first; link != NULL; 15139 link = link->next) { 15140 tq = link->base_address; 15141 (void) ql_abort_device(ha, tq, 0); 15142 15143 /* Wait for 30 seconds for commands to finish. */ 15144 for (cnt = 3000; cnt != 0; cnt--) { 15145 /* Acquire device queue lock. */ 15146 DEVICE_QUEUE_LOCK(tq); 15147 if (tq->outcnt == 0) { 15148 /* Release device queue lock. */ 15149 DEVICE_QUEUE_UNLOCK(tq); 15150 break; 15151 } else { 15152 /* Release device queue lock. */ 15153 DEVICE_QUEUE_UNLOCK(tq); 15154 ql_delay(ha, 10000); 15155 } 15156 } 15157 15158 /* Finish any commands waiting for more status. */ 15159 if (ha->status_srb != NULL) { 15160 sp = ha->status_srb; 15161 ha->status_srb = NULL; 15162 sp->cmd.next = NULL; 15163 ql_done(&sp->cmd); 15164 } 15165 15166 /* Abort commands that did not finish. */ 15167 if (cnt == 0) { 15168 for (cnt = 1; cnt < MAX_OUTSTANDING_COMMANDS; 15169 cnt++) { 15170 if (ha->pending_cmds.first != NULL) { 15171 ql_start_iocb(ha, NULL); 15172 cnt = 1; 15173 } 15174 sp = ha->outstanding_cmds[cnt]; 15175 if (sp != NULL && 15176 sp->lun_queue->target_queue == 15177 tq) { 15178 (void) ql_abort((opaque_t)ha, 15179 sp->pkt, 0); 15180 } 15181 } 15182 } 15183 } 15184 } 15185 15186 /* Shutdown IP. */ 15187 if (ha->flags & IP_INITIALIZED) { 15188 (void) ql_shutdown_ip(ha); 15189 } 15190 15191 /* Stop all timers. */ 15192 ADAPTER_STATE_LOCK(ha); 15193 ha->port_retry_timer = 0; 15194 ha->loop_down_timer = LOOP_DOWN_TIMER_OFF; 15195 ha->watchdog_timer = 0; 15196 ADAPTER_STATE_UNLOCK(ha); 15197 15198 if (pwr == PM_LEVEL_D3) { 15199 ADAPTER_STATE_LOCK(ha); 15200 ha->flags &= ~ONLINE; 15201 ADAPTER_STATE_UNLOCK(ha); 15202 15203 /* Reset ISP chip. */ 15204 ql_reset_chip(ha); 15205 } 15206 15207 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance); 15208} 15209 15210/* 15211 * ql_get_dma_mem 15212 * Function used to allocate dma memory. 15213 * 15214 * Input: 15215 * ha: adapter state pointer. 15216 * mem: pointer to dma memory object. 15217 * size: size of the request in bytes 15218 * 15219 * Returns: 15220 * qn local function return status code. 15221 * 15222 * Context: 15223 * Kernel context. 15224 */ 15225int 15226ql_get_dma_mem(ql_adapter_state_t *ha, dma_mem_t *mem, uint32_t size, 15227 mem_alloc_type_t allocation_type, mem_alignment_t alignment) 15228{ 15229 int rval; 15230 15231 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance); 15232 15233 mem->size = size; 15234 mem->type = allocation_type; 15235 mem->cookie_count = 1; 15236 15237 switch (alignment) { 15238 case QL_DMA_DATA_ALIGN: 15239 mem->alignment = QL_DMA_ALIGN_8_BYTE_BOUNDARY; 15240 break; 15241 case QL_DMA_RING_ALIGN: 15242 mem->alignment = QL_DMA_ALIGN_64_BYTE_BOUNDARY; 15243 break; 15244 default: 15245 EL(ha, "failed, unknown alignment type %x\n", alignment); 15246 break; 15247 } 15248 15249 if ((rval = ql_alloc_phys(ha, mem, KM_SLEEP)) != QL_SUCCESS) { 15250 ql_free_phys(ha, mem); 15251 EL(ha, "failed, alloc_phys=%xh\n", rval); 15252 } 15253 15254 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance); 15255 15256 return (rval); 15257} 15258 15259/* 15260 * ql_alloc_phys 15261 * Function used to allocate memory and zero it. 15262 * Memory is below 4 GB. 15263 * 15264 * Input: 15265 * ha: adapter state pointer. 15266 * mem: pointer to dma memory object. 15267 * sleep: KM_SLEEP/KM_NOSLEEP flag. 15268 * mem->cookie_count number of segments allowed. 15269 * mem->type memory allocation type. 15270 * mem->size memory size. 15271 * mem->alignment memory alignment. 15272 * 15273 * Returns: 15274 * qn local function return status code. 15275 * 15276 * Context: 15277 * Kernel context. 15278 */ 15279int 15280ql_alloc_phys(ql_adapter_state_t *ha, dma_mem_t *mem, int sleep) 15281{ 15282 size_t rlen; 15283 ddi_dma_attr_t dma_attr; 15284 ddi_device_acc_attr_t acc_attr = ql_dev_acc_attr; 15285 15286 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance); 15287 15288 dma_attr = CFG_IST(ha, CFG_ENABLE_64BIT_ADDRESSING) ? 15289 ql_64bit_io_dma_attr : ql_32bit_io_dma_attr; 15290 15291 dma_attr.dma_attr_align = mem->alignment; /* DMA address alignment */ 15292 dma_attr.dma_attr_sgllen = (int)mem->cookie_count; 15293 15294 /* 15295 * Workaround for SUN XMITS buffer must end and start on 8 byte 15296 * boundary. Else, hardware will overrun the buffer. Simple fix is 15297 * to make sure buffer has enough room for overrun. 15298 */ 15299 if (mem->size & 7) { 15300 mem->size += 8 - (mem->size & 7); 15301 } 15302 15303 mem->flags = DDI_DMA_CONSISTENT; 15304 15305 /* 15306 * Allocate DMA memory for command. 15307 */ 15308 if (ddi_dma_alloc_handle(ha->dip, &dma_attr, (sleep == KM_SLEEP) ? 15309 DDI_DMA_SLEEP : DDI_DMA_DONTWAIT, NULL, &mem->dma_handle) != 15310 DDI_SUCCESS) { 15311 EL(ha, "failed, ddi_dma_alloc_handle\n"); 15312 mem->dma_handle = NULL; 15313 return (QL_MEMORY_ALLOC_FAILED); 15314 } 15315 15316 switch (mem->type) { 15317 case KERNEL_MEM: 15318 mem->bp = kmem_zalloc(mem->size, sleep); 15319 break; 15320 case BIG_ENDIAN_DMA: 15321 case LITTLE_ENDIAN_DMA: 15322 case NO_SWAP_DMA: 15323 if (mem->type == BIG_ENDIAN_DMA) { 15324 acc_attr.devacc_attr_endian_flags = 15325 DDI_STRUCTURE_BE_ACC; 15326 } else if (mem->type == NO_SWAP_DMA) { 15327 acc_attr.devacc_attr_endian_flags = DDI_NEVERSWAP_ACC; 15328 } 15329 if (ddi_dma_mem_alloc(mem->dma_handle, mem->size, &acc_attr, 15330 mem->flags, (sleep == KM_SLEEP) ? DDI_DMA_SLEEP : 15331 DDI_DMA_DONTWAIT, NULL, (caddr_t *)&mem->bp, &rlen, 15332 &mem->acc_handle) == DDI_SUCCESS) { 15333 bzero(mem->bp, mem->size); 15334 /* ensure we got what we asked for (32bit) */ 15335 if (dma_attr.dma_attr_addr_hi == NULL) { 15336 if (mem->cookie.dmac_notused != NULL) { 15337 EL(ha, "failed, ddi_dma_mem_alloc " 15338 "returned 64 bit DMA address\n"); 15339 ql_free_phys(ha, mem); 15340 return (QL_MEMORY_ALLOC_FAILED); 15341 } 15342 } 15343 } else { 15344 mem->acc_handle = NULL; 15345 mem->bp = NULL; 15346 } 15347 break; 15348 default: 15349 EL(ha, "failed, unknown type=%xh\n", mem->type); 15350 mem->acc_handle = NULL; 15351 mem->bp = NULL; 15352 break; 15353 } 15354 15355 if (mem->bp == NULL) { 15356 EL(ha, "failed, ddi_dma_mem_alloc\n"); 15357 ddi_dma_free_handle(&mem->dma_handle); 15358 mem->dma_handle = NULL; 15359 return (QL_MEMORY_ALLOC_FAILED); 15360 } 15361 15362 mem->flags |= DDI_DMA_RDWR; 15363 15364 if (ql_bind_dma_buffer(ha, mem, sleep) != DDI_DMA_MAPPED) { 15365 EL(ha, "failed, ddi_dma_addr_bind_handle\n"); 15366 ql_free_phys(ha, mem); 15367 return (QL_MEMORY_ALLOC_FAILED); 15368 } 15369 15370 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance); 15371 15372 return (QL_SUCCESS); 15373} 15374 15375/* 15376 * ql_free_phys 15377 * Function used to free physical memory. 15378 * 15379 * Input: 15380 * ha: adapter state pointer. 15381 * mem: pointer to dma memory object. 15382 * 15383 * Context: 15384 * Kernel context. 15385 */ 15386void 15387ql_free_phys(ql_adapter_state_t *ha, dma_mem_t *mem) 15388{ 15389 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance); 15390 15391 if (mem != NULL && mem->dma_handle != NULL) { 15392 ql_unbind_dma_buffer(ha, mem); 15393 switch (mem->type) { 15394 case KERNEL_MEM: 15395 if (mem->bp != NULL) { 15396 kmem_free(mem->bp, mem->size); 15397 } 15398 break; 15399 case LITTLE_ENDIAN_DMA: 15400 case BIG_ENDIAN_DMA: 15401 case NO_SWAP_DMA: 15402 if (mem->acc_handle != NULL) { 15403 ddi_dma_mem_free(&mem->acc_handle); 15404 mem->acc_handle = NULL; 15405 } 15406 break; 15407 default: 15408 break; 15409 } 15410 mem->bp = NULL; 15411 ddi_dma_free_handle(&mem->dma_handle); 15412 mem->dma_handle = NULL; 15413 } 15414 15415 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance); 15416} 15417 15418/* 15419 * ql_alloc_dma_resouce. 15420 * Allocates DMA resource for buffer. 15421 * 15422 * Input: 15423 * ha: adapter state pointer. 15424 * mem: pointer to dma memory object. 15425 * sleep: KM_SLEEP/KM_NOSLEEP flag. 15426 * mem->cookie_count number of segments allowed. 15427 * mem->type memory allocation type. 15428 * mem->size memory size. 15429 * mem->bp pointer to memory or struct buf 15430 * 15431 * Returns: 15432 * qn local function return status code. 15433 * 15434 * Context: 15435 * Kernel context. 15436 */ 15437int 15438ql_alloc_dma_resouce(ql_adapter_state_t *ha, dma_mem_t *mem, int sleep) 15439{ 15440 ddi_dma_attr_t dma_attr; 15441 15442 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance); 15443 15444 dma_attr = CFG_IST(ha, CFG_ENABLE_64BIT_ADDRESSING) ? 15445 ql_64bit_io_dma_attr : ql_32bit_io_dma_attr; 15446 dma_attr.dma_attr_sgllen = (int)mem->cookie_count; 15447 15448 /* 15449 * Allocate DMA handle for command. 15450 */ 15451 if (ddi_dma_alloc_handle(ha->dip, &dma_attr, (sleep == KM_SLEEP) ? 15452 DDI_DMA_SLEEP : DDI_DMA_DONTWAIT, NULL, &mem->dma_handle) != 15453 DDI_SUCCESS) { 15454 EL(ha, "failed, ddi_dma_alloc_handle\n"); 15455 mem->dma_handle = NULL; 15456 return (QL_MEMORY_ALLOC_FAILED); 15457 } 15458 15459 mem->flags = DDI_DMA_RDWR | DDI_DMA_CONSISTENT; 15460 15461 if (ql_bind_dma_buffer(ha, mem, sleep) != DDI_DMA_MAPPED) { 15462 EL(ha, "failed, bind_dma_buffer\n"); 15463 ddi_dma_free_handle(&mem->dma_handle); 15464 mem->dma_handle = NULL; 15465 return (QL_MEMORY_ALLOC_FAILED); 15466 } 15467 15468 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance); 15469 15470 return (QL_SUCCESS); 15471} 15472 15473/* 15474 * ql_free_dma_resource 15475 * Frees DMA resources. 15476 * 15477 * Input: 15478 * ha: adapter state pointer. 15479 * mem: pointer to dma memory object. 15480 * mem->dma_handle DMA memory handle. 15481 * 15482 * Context: 15483 * Kernel context. 15484 */ 15485void 15486ql_free_dma_resource(ql_adapter_state_t *ha, dma_mem_t *mem) 15487{ 15488 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance); 15489 15490 ql_free_phys(ha, mem); 15491 15492 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance); 15493} 15494 15495/* 15496 * ql_bind_dma_buffer 15497 * Binds DMA buffer. 15498 * 15499 * Input: 15500 * ha: adapter state pointer. 15501 * mem: pointer to dma memory object. 15502 * sleep: KM_SLEEP or KM_NOSLEEP. 15503 * mem->dma_handle DMA memory handle. 15504 * mem->cookie_count number of segments allowed. 15505 * mem->type memory allocation type. 15506 * mem->size memory size. 15507 * mem->bp pointer to memory or struct buf 15508 * 15509 * Returns: 15510 * mem->cookies pointer to list of cookies. 15511 * mem->cookie_count number of cookies. 15512 * status success = DDI_DMA_MAPPED 15513 * DDI_DMA_PARTIAL_MAP, DDI_DMA_INUSE, 15514 * DDI_DMA_NORESOURCES, DDI_DMA_NOMAPPING or 15515 * DDI_DMA_TOOBIG 15516 * 15517 * Context: 15518 * Kernel context. 15519 */ 15520static int 15521ql_bind_dma_buffer(ql_adapter_state_t *ha, dma_mem_t *mem, int sleep) 15522{ 15523 int rval; 15524 ddi_dma_cookie_t *cookiep; 15525 uint32_t cnt = mem->cookie_count; 15526 15527 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance); 15528 15529 if (mem->type == STRUCT_BUF_MEMORY) { 15530 rval = ddi_dma_buf_bind_handle(mem->dma_handle, mem->bp, 15531 mem->flags, (sleep == KM_SLEEP) ? DDI_DMA_SLEEP : 15532 DDI_DMA_DONTWAIT, NULL, &mem->cookie, &mem->cookie_count); 15533 } else { 15534 rval = ddi_dma_addr_bind_handle(mem->dma_handle, NULL, mem->bp, 15535 mem->size, mem->flags, (sleep == KM_SLEEP) ? 15536 DDI_DMA_SLEEP : DDI_DMA_DONTWAIT, NULL, &mem->cookie, 15537 &mem->cookie_count); 15538 } 15539 15540 if (rval == DDI_DMA_MAPPED) { 15541 if (mem->cookie_count > cnt) { 15542 (void) ddi_dma_unbind_handle(mem->dma_handle); 15543 EL(ha, "failed, cookie_count %d > %d\n", 15544 mem->cookie_count, cnt); 15545 rval = DDI_DMA_TOOBIG; 15546 } else { 15547 if (mem->cookie_count > 1) { 15548 if (mem->cookies = kmem_zalloc( 15549 sizeof (ddi_dma_cookie_t) * 15550 mem->cookie_count, sleep)) { 15551 *mem->cookies = mem->cookie; 15552 cookiep = mem->cookies; 15553 for (cnt = 1; cnt < mem->cookie_count; 15554 cnt++) { 15555 ddi_dma_nextcookie( 15556 mem->dma_handle, 15557 ++cookiep); 15558 } 15559 } else { 15560 (void) ddi_dma_unbind_handle( 15561 mem->dma_handle); 15562 EL(ha, "failed, kmem_zalloc\n"); 15563 rval = DDI_DMA_NORESOURCES; 15564 } 15565 } else { 15566 /* 15567 * It has been reported that dmac_size at times 15568 * may be incorrect on sparc machines so for 15569 * sparc machines that only have one segment 15570 * use the buffer size instead. 15571 */ 15572 mem->cookies = &mem->cookie; 15573 mem->cookies->dmac_size = mem->size; 15574 } 15575 } 15576 } 15577 15578 if (rval != DDI_DMA_MAPPED) { 15579 EL(ha, "failed=%xh\n", rval); 15580 } else { 15581 /*EMPTY*/ 15582 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance); 15583 } 15584 15585 return (rval); 15586} 15587 15588/* 15589 * ql_unbind_dma_buffer 15590 * Unbinds DMA buffer. 15591 * 15592 * Input: 15593 * ha: adapter state pointer. 15594 * mem: pointer to dma memory object. 15595 * mem->dma_handle DMA memory handle. 15596 * mem->cookies pointer to cookie list. 15597 * mem->cookie_count number of cookies. 15598 * 15599 * Context: 15600 * Kernel context. 15601 */ 15602/* ARGSUSED */ 15603static void 15604ql_unbind_dma_buffer(ql_adapter_state_t *ha, dma_mem_t *mem) 15605{ 15606 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance); 15607 15608 (void) ddi_dma_unbind_handle(mem->dma_handle); 15609 if (mem->cookie_count > 1) { 15610 kmem_free(mem->cookies, sizeof (ddi_dma_cookie_t) * 15611 mem->cookie_count); 15612 mem->cookies = NULL; 15613 } 15614 mem->cookie_count = 0; 15615 15616 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance); 15617} 15618 15619static int 15620ql_suspend_adapter(ql_adapter_state_t *ha) 15621{ 15622 clock_t timer; 15623 15624 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance); 15625 15626 /* 15627 * First we will claim mbox ownership so that no 15628 * thread using mbox hangs when we disable the 15629 * interrupt in the middle of it. 15630 */ 15631 MBX_REGISTER_LOCK(ha); 15632 15633 /* Check for mailbox available, if not wait for signal. */ 15634 while (ha->mailbox_flags & MBX_BUSY_FLG) { 15635 ha->mailbox_flags = (uint8_t) 15636 (ha->mailbox_flags | MBX_WANT_FLG); 15637 15638 /* 30 seconds from now */ 15639 timer = ddi_get_lbolt(); 15640 timer += 32 * drv_usectohz(1000000); 15641 if (cv_timedwait(&ha->cv_mbx_wait, &ha->mbx_mutex, 15642 timer) == -1) { 15643 15644 /* Release mailbox register lock. */ 15645 MBX_REGISTER_UNLOCK(ha); 15646 EL(ha, "failed, Suspend mbox"); 15647 return (QL_FUNCTION_TIMEOUT); 15648 } 15649 } 15650 15651 /* Set busy flag. */ 15652 ha->mailbox_flags = (uint8_t)(ha->mailbox_flags | MBX_BUSY_FLG); 15653 MBX_REGISTER_UNLOCK(ha); 15654 15655 (void) ql_wait_outstanding(ha); 15656 15657 /* 15658 * here we are sure that there will not be any mbox interrupt. 15659 * So, let's make sure that we return back all the outstanding 15660 * cmds as well as internally queued commands. 15661 */ 15662 ql_halt(ha, PM_LEVEL_D0); 15663 15664 if (ha->power_level != PM_LEVEL_D3) { 15665 /* Disable ISP interrupts. */ 15666 WRT16_IO_REG(ha, ictrl, 0); 15667 } 15668 15669 ADAPTER_STATE_LOCK(ha); 15670 ha->flags &= ~INTERRUPTS_ENABLED; 15671 ADAPTER_STATE_UNLOCK(ha); 15672 15673 MBX_REGISTER_LOCK(ha); 15674 /* Reset busy status. */ 15675 ha->mailbox_flags = (uint8_t)(ha->mailbox_flags & ~MBX_BUSY_FLG); 15676 15677 /* If thread is waiting for mailbox go signal it to start. */ 15678 if (ha->mailbox_flags & MBX_WANT_FLG) { 15679 ha->mailbox_flags = (uint8_t) 15680 (ha->mailbox_flags & ~MBX_WANT_FLG); 15681 cv_broadcast(&ha->cv_mbx_wait); 15682 } 15683 /* Release mailbox register lock. */ 15684 MBX_REGISTER_UNLOCK(ha); 15685 15686 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance); 15687 15688 return (QL_SUCCESS); 15689} 15690 15691/* 15692 * ql_add_link_b 15693 * Add link to the end of the chain. 15694 * 15695 * Input: 15696 * head = Head of link list. 15697 * link = link to be added. 15698 * LOCK must be already obtained. 15699 * 15700 * Context: 15701 * Interrupt or Kernel context, no mailbox commands allowed. 15702 */ 15703void 15704ql_add_link_b(ql_head_t *head, ql_link_t *link) 15705{ 15706 /* at the end there isn't a next */ 15707 link->next = NULL; 15708 15709 if ((link->prev = head->last) == NULL) { 15710 head->first = link; 15711 } else { 15712 head->last->next = link; 15713 } 15714 15715 head->last = link; 15716 link->head = head; /* the queue we're on */ 15717} 15718 15719/* 15720 * ql_add_link_t 15721 * Add link to the beginning of the chain. 15722 * 15723 * Input: 15724 * head = Head of link list. 15725 * link = link to be added. 15726 * LOCK must be already obtained. 15727 * 15728 * Context: 15729 * Interrupt or Kernel context, no mailbox commands allowed. 15730 */ 15731void 15732ql_add_link_t(ql_head_t *head, ql_link_t *link) 15733{ 15734 link->prev = NULL; 15735 15736 if ((link->next = head->first) == NULL) { 15737 head->last = link; 15738 } else { 15739 head->first->prev = link; 15740 } 15741 15742 head->first = link; 15743 link->head = head; /* the queue we're on */ 15744} 15745 15746/* 15747 * ql_remove_link 15748 * Remove a link from the chain. 15749 * 15750 * Input: 15751 * head = Head of link list. 15752 * link = link to be removed. 15753 * LOCK must be already obtained. 15754 * 15755 * Context: 15756 * Interrupt or Kernel context, no mailbox commands allowed. 15757 */ 15758void 15759ql_remove_link(ql_head_t *head, ql_link_t *link) 15760{ 15761 if (link->prev != NULL) { 15762 if ((link->prev->next = link->next) == NULL) { 15763 head->last = link->prev; 15764 } else { 15765 link->next->prev = link->prev; 15766 } 15767 } else if ((head->first = link->next) == NULL) { 15768 head->last = NULL; 15769 } else { 15770 head->first->prev = NULL; 15771 } 15772 15773 /* not on a queue any more */ 15774 link->prev = link->next = NULL; 15775 link->head = NULL; 15776} 15777 15778/* 15779 * ql_chg_endian 15780 * Change endianess of byte array. 15781 * 15782 * Input: 15783 * buf = array pointer. 15784 * size = size of array in bytes. 15785 * 15786 * Context: 15787 * Interrupt or Kernel context, no mailbox commands allowed. 15788 */ 15789void 15790ql_chg_endian(uint8_t buf[], size_t size) 15791{ 15792 uint8_t byte; 15793 size_t cnt1; 15794 size_t cnt; 15795 15796 cnt1 = size - 1; 15797 for (cnt = 0; cnt < size / 2; cnt++) { 15798 byte = buf[cnt1]; 15799 buf[cnt1] = buf[cnt]; 15800 buf[cnt] = byte; 15801 cnt1--; 15802 } 15803} 15804 15805/* 15806 * ql_bstr_to_dec 15807 * Convert decimal byte string to number. 15808 * 15809 * Input: 15810 * s: byte string pointer. 15811 * ans: interger pointer for number. 15812 * size: number of ascii bytes. 15813 * 15814 * Returns: 15815 * success = number of ascii bytes processed. 15816 * 15817 * Context: 15818 * Kernel/Interrupt context. 15819 */ 15820static int 15821ql_bstr_to_dec(char *s, uint32_t *ans, uint32_t size) 15822{ 15823 int mul, num, cnt, pos; 15824 char *str; 15825 15826 /* Calculate size of number. */ 15827 if (size == 0) { 15828 for (str = s; *str >= '0' && *str <= '9'; str++) { 15829 size++; 15830 } 15831 } 15832 15833 *ans = 0; 15834 for (cnt = 0; *s != '\0' && size; size--, cnt++) { 15835 if (*s >= '0' && *s <= '9') { 15836 num = *s++ - '0'; 15837 } else { 15838 break; 15839 } 15840 15841 for (mul = 1, pos = 1; pos < size; pos++) { 15842 mul *= 10; 15843 } 15844 *ans += num * mul; 15845 } 15846 15847 return (cnt); 15848} 15849 15850/* 15851 * ql_delay 15852 * Calls delay routine if threads are not suspended, otherwise, busy waits 15853 * Minimum = 1 tick = 10ms 15854 * 15855 * Input: 15856 * dly = delay time in microseconds. 15857 * 15858 * Context: 15859 * Kernel or Interrupt context, no mailbox commands allowed. 15860 */ 15861void 15862ql_delay(ql_adapter_state_t *ha, clock_t usecs) 15863{ 15864 if (QL_DAEMON_SUSPENDED(ha) || ddi_in_panic()) { 15865 drv_usecwait(usecs); 15866 } else { 15867 delay(drv_usectohz(usecs)); 15868 } 15869} 15870 15871/* 15872 * ql_stall_drv 15873 * Stalls one or all driver instances, waits for 30 seconds. 15874 * 15875 * Input: 15876 * ha: adapter state pointer or NULL for all. 15877 * options: BIT_0 --> leave driver stalled on exit if 15878 * failed. 15879 * 15880 * Returns: 15881 * ql local function return status code. 15882 * 15883 * Context: 15884 * Kernel context. 15885 */ 15886int 15887ql_stall_driver(ql_adapter_state_t *ha, uint32_t options) 15888{ 15889 ql_link_t *link; 15890 ql_adapter_state_t *ha2; 15891 uint32_t timer; 15892 15893 QL_PRINT_3(CE_CONT, "started\n"); 15894 15895 /* Wait for 30 seconds for daemons unstall. */ 15896 timer = 3000; 15897 link = ha == NULL ? ql_hba.first : &ha->hba; 15898 while (link != NULL && timer) { 15899 ha2 = link->base_address; 15900 15901 ql_awaken_task_daemon(ha2, NULL, DRIVER_STALL, 0); 15902 15903 if ((ha2->task_daemon_flags & TASK_DAEMON_ALIVE_FLG) == 0 || 15904 (ha2->task_daemon_flags & TASK_DAEMON_STOP_FLG) != 0 || 15905 (ha2->task_daemon_flags & TASK_DAEMON_STALLED_FLG && 15906 ql_wait_outstanding(ha2) == MAX_OUTSTANDING_COMMANDS)) { 15907 link = ha == NULL ? link->next : NULL; 15908 continue; 15909 } 15910 15911 ql_delay(ha, 10000); 15912 timer--; 15913 link = ha == NULL ? ql_hba.first : &ha->hba; 15914 } 15915 15916 if (ha2 != NULL && timer == 0) { 15917 EL(ha2, "failed, tdf=%xh, exiting state is: %s\n", 15918 ha2->task_daemon_flags, (options & BIT_0 ? "stalled" : 15919 "unstalled")); 15920 if (options & BIT_0) { 15921 ql_awaken_task_daemon(ha2, NULL, 0, DRIVER_STALL); 15922 } 15923 return (QL_FUNCTION_TIMEOUT); 15924 } 15925 15926 QL_PRINT_3(CE_CONT, "done\n"); 15927 15928 return (QL_SUCCESS); 15929} 15930 15931/* 15932 * ql_restart_driver 15933 * Restarts one or all driver instances. 15934 * 15935 * Input: 15936 * ha: adapter state pointer or NULL for all. 15937 * 15938 * Context: 15939 * Kernel context. 15940 */ 15941void 15942ql_restart_driver(ql_adapter_state_t *ha) 15943{ 15944 ql_link_t *link; 15945 ql_adapter_state_t *ha2; 15946 uint32_t timer; 15947 15948 QL_PRINT_3(CE_CONT, "started\n"); 15949 15950 /* Tell all daemons to unstall. */ 15951 link = ha == NULL ? ql_hba.first : &ha->hba; 15952 while (link != NULL) { 15953 ha2 = link->base_address; 15954 15955 ql_awaken_task_daemon(ha2, NULL, 0, DRIVER_STALL); 15956 15957 link = ha == NULL ? link->next : NULL; 15958 } 15959 15960 /* Wait for 30 seconds for all daemons unstall. */ 15961 timer = 3000; 15962 link = ha == NULL ? ql_hba.first : &ha->hba; 15963 while (link != NULL && timer) { 15964 ha2 = link->base_address; 15965 15966 if ((ha2->task_daemon_flags & TASK_DAEMON_ALIVE_FLG) == 0 || 15967 (ha2->task_daemon_flags & TASK_DAEMON_STOP_FLG) != 0 || 15968 (ha2->task_daemon_flags & TASK_DAEMON_STALLED_FLG) == 0) { 15969 QL_PRINT_2(CE_CONT, "(%d,%d): restarted\n", 15970 ha2->instance, ha2->vp_index); 15971 ql_restart_queues(ha2); 15972 link = ha == NULL ? link->next : NULL; 15973 continue; 15974 } 15975 15976 QL_PRINT_2(CE_CONT, "(%d,%d): failed, tdf=%xh\n", 15977 ha2->instance, ha2->vp_index, ha2->task_daemon_flags); 15978 15979 ql_delay(ha, 10000); 15980 timer--; 15981 link = ha == NULL ? ql_hba.first : &ha->hba; 15982 } 15983 15984 QL_PRINT_3(CE_CONT, "done\n"); 15985} 15986 15987/* 15988 * ql_setup_interrupts 15989 * Sets up interrupts based on the HBA's and platform's 15990 * capabilities (e.g., legacy / MSI / FIXED). 15991 * 15992 * Input: 15993 * ha = adapter state pointer. 15994 * 15995 * Returns: 15996 * DDI_SUCCESS or DDI_FAILURE. 15997 * 15998 * Context: 15999 * Kernel context. 16000 */ 16001static int 16002ql_setup_interrupts(ql_adapter_state_t *ha) 16003{ 16004 int32_t rval = DDI_FAILURE; 16005 int32_t i; 16006 int32_t itypes = 0; 16007 16008 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance); 16009 16010 /* 16011 * The Solaris Advanced Interrupt Functions (aif) are only 16012 * supported on s10U1 or greater. 16013 */ 16014 if (ql_os_release_level < 10 || ql_disable_aif != 0) { 16015 EL(ha, "interrupt framework is not supported or is " 16016 "disabled, using legacy\n"); 16017 return (ql_legacy_intr(ha)); 16018 } else if (ql_os_release_level == 10) { 16019 /* 16020 * See if the advanced interrupt functions (aif) are 16021 * in the kernel 16022 */ 16023 void *fptr = (void *)&ddi_intr_get_supported_types; 16024 16025 if (fptr == NULL) { 16026 EL(ha, "aif is not supported, using legacy " 16027 "interrupts (rev)\n"); 16028 return (ql_legacy_intr(ha)); 16029 } 16030 } 16031 16032 /* See what types of interrupts this HBA and platform support */ 16033 if ((i = ddi_intr_get_supported_types(ha->dip, &itypes)) != 16034 DDI_SUCCESS) { 16035 EL(ha, "get supported types failed, rval=%xh, " 16036 "assuming FIXED\n", i); 16037 itypes = DDI_INTR_TYPE_FIXED; 16038 } 16039 16040 EL(ha, "supported types are: %xh\n", itypes); 16041 16042 if ((itypes & DDI_INTR_TYPE_MSIX) && 16043 (rval = ql_setup_msix(ha)) == DDI_SUCCESS) { 16044 EL(ha, "successful MSI-X setup\n"); 16045 } else if ((itypes & DDI_INTR_TYPE_MSI) && 16046 (rval = ql_setup_msi(ha)) == DDI_SUCCESS) { 16047 EL(ha, "successful MSI setup\n"); 16048 } else { 16049 rval = ql_setup_fixed(ha); 16050 } 16051 16052 if (rval != DDI_SUCCESS) { 16053 EL(ha, "failed, aif, rval=%xh\n", rval); 16054 } else { 16055 /*EMPTY*/ 16056 QL_PRINT_3(CE_CONT, "(%d): done\n"); 16057 } 16058 16059 return (rval); 16060} 16061 16062/* 16063 * ql_setup_msi 16064 * Set up aif MSI interrupts 16065 * 16066 * Input: 16067 * ha = adapter state pointer. 16068 * 16069 * Returns: 16070 * DDI_SUCCESS or DDI_FAILURE. 16071 * 16072 * Context: 16073 * Kernel context. 16074 */ 16075static int 16076ql_setup_msi(ql_adapter_state_t *ha) 16077{ 16078 int32_t count = 0; 16079 int32_t avail = 0; 16080 int32_t actual = 0; 16081 int32_t msitype = DDI_INTR_TYPE_MSI; 16082 int32_t ret; 16083 ql_ifunc_t itrfun[10] = {0}; 16084 16085 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance); 16086 16087 if (ql_disable_msi != 0) { 16088 EL(ha, "MSI is disabled by user\n"); 16089 return (DDI_FAILURE); 16090 } 16091 16092 /* MSI support is only suported on 24xx HBA's. */ 16093 if (!(CFG_IST(ha, CFG_CTRL_242581))) { 16094 EL(ha, "HBA does not support MSI\n"); 16095 return (DDI_FAILURE); 16096 } 16097 16098 /* Get number of MSI interrupts the system supports */ 16099 if (((ret = ddi_intr_get_nintrs(ha->dip, msitype, &count)) != 16100 DDI_SUCCESS) || count == 0) { 16101 EL(ha, "failed, nintrs ret=%xh, cnt=%xh\n", ret, count); 16102 return (DDI_FAILURE); 16103 } 16104 16105 /* Get number of available MSI interrupts */ 16106 if (((ret = ddi_intr_get_navail(ha->dip, msitype, &avail)) != 16107 DDI_SUCCESS) || avail == 0) { 16108 EL(ha, "failed, navail ret=%xh, avail=%xh\n", ret, avail); 16109 return (DDI_FAILURE); 16110 } 16111 16112 /* MSI requires only 1. */ 16113 count = 1; 16114 itrfun[0].ifunc = &ql_isr_aif; 16115 16116 /* Allocate space for interrupt handles */ 16117 ha->hsize = ((uint32_t)(sizeof (ddi_intr_handle_t)) * count); 16118 ha->htable = kmem_zalloc(ha->hsize, KM_SLEEP); 16119 16120 ha->iflags |= IFLG_INTR_MSI; 16121 16122 /* Allocate the interrupts */ 16123 if ((ret = ddi_intr_alloc(ha->dip, ha->htable, msitype, 0, count, 16124 &actual, 0)) != DDI_SUCCESS || actual < count) { 16125 EL(ha, "failed, intr_alloc ret=%xh, count = %xh, " 16126 "actual=%xh\n", ret, count, actual); 16127 ql_release_intr(ha); 16128 return (DDI_FAILURE); 16129 } 16130 16131 ha->intr_cnt = actual; 16132 16133 /* Get interrupt priority */ 16134 if ((ret = ddi_intr_get_pri(ha->htable[0], &ha->intr_pri)) != 16135 DDI_SUCCESS) { 16136 EL(ha, "failed, get_pri ret=%xh\n", ret); 16137 ql_release_intr(ha); 16138 return (ret); 16139 } 16140 16141 /* Add the interrupt handler */ 16142 if ((ret = ddi_intr_add_handler(ha->htable[0], itrfun[0].ifunc, 16143 (caddr_t)ha, (caddr_t)0)) != DDI_SUCCESS) { 16144 EL(ha, "failed, intr_add ret=%xh\n", ret); 16145 ql_release_intr(ha); 16146 return (ret); 16147 } 16148 16149 /* Setup mutexes */ 16150 if ((ret = ql_init_mutex(ha)) != DDI_SUCCESS) { 16151 EL(ha, "failed, mutex init ret=%xh\n", ret); 16152 ql_release_intr(ha); 16153 return (ret); 16154 } 16155 16156 /* Get the capabilities */ 16157 (void) ddi_intr_get_cap(ha->htable[0], &ha->intr_cap); 16158 16159 /* Enable interrupts */ 16160 if (ha->intr_cap & DDI_INTR_FLAG_BLOCK) { 16161 if ((ret = ddi_intr_block_enable(ha->htable, ha->intr_cnt)) != 16162 DDI_SUCCESS) { 16163 EL(ha, "failed, block enable, ret=%xh\n", ret); 16164 ql_destroy_mutex(ha); 16165 ql_release_intr(ha); 16166 return (ret); 16167 } 16168 } else { 16169 if ((ret = ddi_intr_enable(ha->htable[0])) != DDI_SUCCESS) { 16170 EL(ha, "failed, intr enable, ret=%xh\n", ret); 16171 ql_destroy_mutex(ha); 16172 ql_release_intr(ha); 16173 return (ret); 16174 } 16175 } 16176 16177 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance); 16178 16179 return (DDI_SUCCESS); 16180} 16181 16182/* 16183 * ql_setup_msix 16184 * Set up aif MSI-X interrupts 16185 * 16186 * Input: 16187 * ha = adapter state pointer. 16188 * 16189 * Returns: 16190 * DDI_SUCCESS or DDI_FAILURE. 16191 * 16192 * Context: 16193 * Kernel context. 16194 */ 16195static int 16196ql_setup_msix(ql_adapter_state_t *ha) 16197{ 16198 uint16_t hwvect; 16199 int32_t count = 0; 16200 int32_t avail = 0; 16201 int32_t actual = 0; 16202 int32_t msitype = DDI_INTR_TYPE_MSIX; 16203 int32_t ret; 16204 uint32_t i; 16205 ql_ifunc_t itrfun[QL_MSIX_MAXAIF] = {0}; 16206 16207 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance); 16208 16209 if (ql_disable_msix != 0) { 16210 EL(ha, "MSI-X is disabled by user\n"); 16211 return (DDI_FAILURE); 16212 } 16213 16214 /* 16215 * MSI-X support is only available on 24xx HBA's that have 16216 * rev A2 parts (revid = 3) or greater. 16217 */ 16218 if (!((ha->device_id == 0x2532) || (ha->device_id == 0x2432) || 16219 (ha->device_id == 0x8432) || (ha->device_id == 0x8001))) { 16220 EL(ha, "HBA does not support MSI-X\n"); 16221 return (DDI_FAILURE); 16222 } 16223 16224 if (CFG_IST(ha, CFG_CTRL_2422) && (ha->rev_id < 3)) { 16225 EL(ha, "HBA does not support MSI-X (revid)\n"); 16226 return (DDI_FAILURE); 16227 } 16228 16229 /* Per HP, these HP branded HBA's are not supported with MSI-X */ 16230 if (ha->ven_id == 0x103C && (ha->subsys_id == 0x7041 || 16231 ha->subsys_id == 0x7040 || ha->subsys_id == 0x1705)) { 16232 EL(ha, "HBA does not support MSI-X (subdevid)\n"); 16233 return (DDI_FAILURE); 16234 } 16235 16236 /* Get the number of 24xx/25xx MSI-X h/w vectors */ 16237 hwvect = (uint16_t)(((CFG_IST(ha, CFG_CTRL_2422) ? 16238 ql_pci_config_get16(ha, 0x7e) : 16239 ql_pci_config_get16(ha, 0xa2)) & 0x3ff) + 1); 16240 16241 EL(ha, "pcie config space hwvect = %d\n", hwvect); 16242 16243 if (hwvect < QL_MSIX_MAXAIF) { 16244 EL(ha, "failed, min h/w vectors req'd: %d, avail: %d\n", 16245 QL_MSIX_MAXAIF, hwvect); 16246 return (DDI_FAILURE); 16247 } 16248 16249 /* Get number of MSI-X interrupts the platform h/w supports */ 16250 if (((ret = ddi_intr_get_nintrs(ha->dip, msitype, &count)) != 16251 DDI_SUCCESS) || count == 0) { 16252 EL(ha, "failed, nintrs ret=%xh, cnt=%xh\n", ret, count); 16253 return (DDI_FAILURE); 16254 } 16255 16256 /* Get number of available system interrupts */ 16257 if (((ret = ddi_intr_get_navail(ha->dip, msitype, &avail)) != 16258 DDI_SUCCESS) || avail == 0) { 16259 EL(ha, "failed, navail ret=%xh, avail=%xh\n", ret, avail); 16260 return (DDI_FAILURE); 16261 } 16262 16263 /* Fill out the intr table */ 16264 count = QL_MSIX_MAXAIF; 16265 itrfun[QL_MSIX_AIF].ifunc = &ql_isr_aif; 16266 itrfun[QL_MSIX_RSPQ].ifunc = &ql_isr_aif; 16267 16268 /* Allocate space for interrupt handles */ 16269 ha->hsize = ((uint32_t)(sizeof (ddi_intr_handle_t)) * hwvect); 16270 if ((ha->htable = kmem_zalloc(ha->hsize, KM_SLEEP)) == NULL) { 16271 ha->hsize = 0; 16272 EL(ha, "failed, unable to allocate htable space\n"); 16273 return (DDI_FAILURE); 16274 } 16275 16276 ha->iflags |= IFLG_INTR_MSIX; 16277 16278 /* Allocate the interrupts */ 16279 if (((ret = ddi_intr_alloc(ha->dip, ha->htable, msitype, 16280 DDI_INTR_ALLOC_NORMAL, count, &actual, 0)) != DDI_SUCCESS) || 16281 actual < QL_MSIX_MAXAIF) { 16282 EL(ha, "failed, intr_alloc ret=%xh, count = %xh, " 16283 "actual=%xh\n", ret, count, actual); 16284 ql_release_intr(ha); 16285 return (DDI_FAILURE); 16286 } 16287 16288 ha->intr_cnt = actual; 16289 16290 /* Get interrupt priority */ 16291 if ((ret = ddi_intr_get_pri(ha->htable[0], &ha->intr_pri)) != 16292 DDI_SUCCESS) { 16293 EL(ha, "failed, get_pri ret=%xh\n", ret); 16294 ql_release_intr(ha); 16295 return (ret); 16296 } 16297 16298 /* Add the interrupt handlers */ 16299 for (i = 0; i < actual; i++) { 16300 if ((ret = ddi_intr_add_handler(ha->htable[i], itrfun[i].ifunc, 16301 (void *)ha, (void *)((ulong_t)i))) != DDI_SUCCESS) { 16302 EL(ha, "failed, addh#=%xh, act=%xh, ret=%xh\n", i, 16303 actual, ret); 16304 ql_release_intr(ha); 16305 return (ret); 16306 } 16307 } 16308 16309 /* 16310 * duplicate the rest of the intr's 16311 * ddi_intr_dup_handler() isn't working on x86 just yet... 16312 */ 16313#ifdef __sparc 16314 for (i = actual; i < hwvect; i++) { 16315 if ((ret = ddi_intr_dup_handler(ha->htable[0], (int)i, 16316 &ha->htable[i])) != DDI_SUCCESS) { 16317 EL(ha, "failed, intr_dup#=%xh, act=%xh, ret=%xh\n", 16318 i, actual, ret); 16319 ql_release_intr(ha); 16320 return (ret); 16321 } 16322 } 16323#endif 16324 16325 /* Setup mutexes */ 16326 if ((ret = ql_init_mutex(ha)) != DDI_SUCCESS) { 16327 EL(ha, "failed, mutex init ret=%xh\n", ret); 16328 ql_release_intr(ha); 16329 return (ret); 16330 } 16331 16332 /* Get the capabilities */ 16333 (void) ddi_intr_get_cap(ha->htable[0], &ha->intr_cap); 16334 16335 /* Enable interrupts */ 16336 if (ha->intr_cap & DDI_INTR_FLAG_BLOCK) { 16337 if ((ret = ddi_intr_block_enable(ha->htable, ha->intr_cnt)) != 16338 DDI_SUCCESS) { 16339 EL(ha, "failed, block enable, ret=%xh\n", ret); 16340 ql_destroy_mutex(ha); 16341 ql_release_intr(ha); 16342 return (ret); 16343 } 16344 } else { 16345 for (i = 0; i < ha->intr_cnt; i++) { 16346 if ((ret = ddi_intr_enable(ha->htable[i])) != 16347 DDI_SUCCESS) { 16348 EL(ha, "failed, intr enable, ret=%xh\n", ret); 16349 ql_destroy_mutex(ha); 16350 ql_release_intr(ha); 16351 return (ret); 16352 } 16353 } 16354 } 16355 16356 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance); 16357 16358 return (DDI_SUCCESS); 16359} 16360 16361/* 16362 * ql_setup_fixed 16363 * Sets up aif FIXED interrupts 16364 * 16365 * Input: 16366 * ha = adapter state pointer. 16367 * 16368 * Returns: 16369 * DDI_SUCCESS or DDI_FAILURE. 16370 * 16371 * Context: 16372 * Kernel context. 16373 */ 16374static int 16375ql_setup_fixed(ql_adapter_state_t *ha) 16376{ 16377 int32_t count = 0; 16378 int32_t actual = 0; 16379 int32_t ret; 16380 uint32_t i; 16381 16382 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance); 16383 16384 /* Get number of fixed interrupts the system supports */ 16385 if (((ret = ddi_intr_get_nintrs(ha->dip, DDI_INTR_TYPE_FIXED, 16386 &count)) != DDI_SUCCESS) || count == 0) { 16387 EL(ha, "failed, nintrs ret=%xh, cnt=%xh\n", ret, count); 16388 return (DDI_FAILURE); 16389 } 16390 16391 ha->iflags |= IFLG_INTR_FIXED; 16392 16393 /* Allocate space for interrupt handles */ 16394 ha->hsize = ((uint32_t)(sizeof (ddi_intr_handle_t)) * count); 16395 ha->htable = kmem_zalloc(ha->hsize, KM_SLEEP); 16396 16397 /* Allocate the interrupts */ 16398 if (((ret = ddi_intr_alloc(ha->dip, ha->htable, DDI_INTR_TYPE_FIXED, 16399 0, count, &actual, DDI_INTR_ALLOC_STRICT)) != DDI_SUCCESS) || 16400 actual < count) { 16401 EL(ha, "failed, intr_alloc ret=%xh, count=%xh, " 16402 "actual=%xh\n", ret, count, actual); 16403 ql_release_intr(ha); 16404 return (DDI_FAILURE); 16405 } 16406 16407 ha->intr_cnt = actual; 16408 16409 /* Get interrupt priority */ 16410 if ((ret = ddi_intr_get_pri(ha->htable[0], &ha->intr_pri)) != 16411 DDI_SUCCESS) { 16412 EL(ha, "failed, get_pri ret=%xh\n", ret); 16413 ql_release_intr(ha); 16414 return (ret); 16415 } 16416 16417 /* Add the interrupt handlers */ 16418 for (i = 0; i < ha->intr_cnt; i++) { 16419 if ((ret = ddi_intr_add_handler(ha->htable[i], &ql_isr_aif, 16420 (void *)ha, (void *)((ulong_t)(i)))) != DDI_SUCCESS) { 16421 EL(ha, "failed, intr_add ret=%xh\n", ret); 16422 ql_release_intr(ha); 16423 return (ret); 16424 } 16425 } 16426 16427 /* Setup mutexes */ 16428 if ((ret = ql_init_mutex(ha)) != DDI_SUCCESS) { 16429 EL(ha, "failed, mutex init ret=%xh\n", ret); 16430 ql_release_intr(ha); 16431 return (ret); 16432 } 16433 16434 /* Enable interrupts */ 16435 for (i = 0; i < ha->intr_cnt; i++) { 16436 if ((ret = ddi_intr_enable(ha->htable[i])) != DDI_SUCCESS) { 16437 EL(ha, "failed, intr enable, ret=%xh\n", ret); 16438 ql_destroy_mutex(ha); 16439 ql_release_intr(ha); 16440 return (ret); 16441 } 16442 } 16443 16444 EL(ha, "using FIXED interupts\n"); 16445 16446 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance); 16447 16448 return (DDI_SUCCESS); 16449} 16450 16451/* 16452 * ql_disable_intr 16453 * Disables interrupts 16454 * 16455 * Input: 16456 * ha = adapter state pointer. 16457 * 16458 * Returns: 16459 * 16460 * Context: 16461 * Kernel context. 16462 */ 16463static void 16464ql_disable_intr(ql_adapter_state_t *ha) 16465{ 16466 uint32_t i, rval; 16467 16468 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance); 16469 16470 if (!(ha->iflags & IFLG_INTR_AIF)) { 16471 16472 /* Disable legacy interrupts */ 16473 (void) ddi_remove_intr(ha->dip, 0, ha->iblock_cookie); 16474 16475 } else if ((ha->intr_cap & DDI_INTR_FLAG_BLOCK) && 16476 (ha->iflags & (IFLG_INTR_MSI | IFLG_INTR_MSIX))) { 16477 16478 /* Remove AIF block interrupts (MSI) */ 16479 if ((rval = ddi_intr_block_disable(ha->htable, ha->intr_cnt)) 16480 != DDI_SUCCESS) { 16481 EL(ha, "failed intr block disable, rval=%x\n", rval); 16482 } 16483 16484 } else { 16485 16486 /* Remove AIF non-block interrupts (fixed). */ 16487 for (i = 0; i < ha->intr_cnt; i++) { 16488 if ((rval = ddi_intr_disable(ha->htable[i])) != 16489 DDI_SUCCESS) { 16490 EL(ha, "failed intr disable, intr#=%xh, " 16491 "rval=%xh\n", i, rval); 16492 } 16493 } 16494 } 16495 16496 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance); 16497} 16498 16499/* 16500 * ql_release_intr 16501 * Releases aif legacy interrupt resources 16502 * 16503 * Input: 16504 * ha = adapter state pointer. 16505 * 16506 * Returns: 16507 * 16508 * Context: 16509 * Kernel context. 16510 */ 16511static void 16512ql_release_intr(ql_adapter_state_t *ha) 16513{ 16514 int32_t i; 16515 16516 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance); 16517 16518 if (!(ha->iflags & IFLG_INTR_AIF)) { 16519 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance); 16520 return; 16521 } 16522 16523 ha->iflags &= ~(IFLG_INTR_AIF); 16524 if (ha->htable != NULL && ha->hsize > 0) { 16525 i = (int32_t)ha->hsize / (int32_t)sizeof (ddi_intr_handle_t); 16526 while (i-- > 0) { 16527 if (ha->htable[i] == 0) { 16528 EL(ha, "htable[%x]=0h\n", i); 16529 continue; 16530 } 16531 16532 (void) ddi_intr_disable(ha->htable[i]); 16533 16534 if (i < ha->intr_cnt) { 16535 (void) ddi_intr_remove_handler(ha->htable[i]); 16536 } 16537 16538 (void) ddi_intr_free(ha->htable[i]); 16539 } 16540 16541 kmem_free(ha->htable, ha->hsize); 16542 ha->htable = NULL; 16543 } 16544 16545 ha->hsize = 0; 16546 ha->intr_cnt = 0; 16547 ha->intr_pri = 0; 16548 ha->intr_cap = 0; 16549 16550 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance); 16551} 16552 16553/* 16554 * ql_legacy_intr 16555 * Sets up legacy interrupts. 16556 * 16557 * NB: Only to be used if AIF (Advanced Interupt Framework) 16558 * if NOT in the kernel. 16559 * 16560 * Input: 16561 * ha = adapter state pointer. 16562 * 16563 * Returns: 16564 * DDI_SUCCESS or DDI_FAILURE. 16565 * 16566 * Context: 16567 * Kernel context. 16568 */ 16569static int 16570ql_legacy_intr(ql_adapter_state_t *ha) 16571{ 16572 int rval = DDI_SUCCESS; 16573 16574 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance); 16575 16576 /* Setup mutexes */ 16577 if (ql_init_mutex(ha) != DDI_SUCCESS) { 16578 EL(ha, "failed, mutex init\n"); 16579 return (DDI_FAILURE); 16580 } 16581 16582 /* Setup standard/legacy interrupt handler */ 16583 if (ddi_add_intr(ha->dip, (uint_t)0, &ha->iblock_cookie, 16584 (ddi_idevice_cookie_t *)0, ql_isr, (caddr_t)ha) != DDI_SUCCESS) { 16585 cmn_err(CE_WARN, "%s(%d): Failed to add legacy interrupt", 16586 QL_NAME, ha->instance); 16587 ql_destroy_mutex(ha); 16588 rval = DDI_FAILURE; 16589 } 16590 16591 if (rval == DDI_SUCCESS) { 16592 ha->iflags |= IFLG_INTR_LEGACY; 16593 EL(ha, "using legacy interrupts\n"); 16594 } 16595 16596 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance); 16597 16598 return (rval); 16599} 16600 16601/* 16602 * ql_init_mutex 16603 * Initializes mutex's 16604 * 16605 * Input: 16606 * ha = adapter state pointer. 16607 * 16608 * Returns: 16609 * DDI_SUCCESS or DDI_FAILURE. 16610 * 16611 * Context: 16612 * Kernel context. 16613 */ 16614static int 16615ql_init_mutex(ql_adapter_state_t *ha) 16616{ 16617 int ret; 16618 void *intr; 16619 16620 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance); 16621 16622 if (ha->iflags & IFLG_INTR_AIF) { 16623 intr = (void *)(uintptr_t)ha->intr_pri; 16624 } else { 16625 /* Get iblock cookies to initialize mutexes */ 16626 if ((ret = ddi_get_iblock_cookie(ha->dip, 0, 16627 &ha->iblock_cookie)) != DDI_SUCCESS) { 16628 EL(ha, "failed, get_iblock: %xh\n", ret); 16629 return (DDI_FAILURE); 16630 } 16631 intr = (void *)ha->iblock_cookie; 16632 } 16633 16634 /* mutexes to protect the adapter state structure. */ 16635 mutex_init(&ha->mutex, NULL, MUTEX_DRIVER, intr); 16636 16637 /* mutex to protect the ISP response ring. */ 16638 mutex_init(&ha->intr_mutex, NULL, MUTEX_DRIVER, intr); 16639 16640 /* mutex to protect the mailbox registers. */ 16641 mutex_init(&ha->mbx_mutex, NULL, MUTEX_DRIVER, intr); 16642 16643 /* power management protection */ 16644 mutex_init(&ha->pm_mutex, NULL, MUTEX_DRIVER, intr); 16645 16646 /* Mailbox wait and interrupt conditional variable. */ 16647 cv_init(&ha->cv_mbx_wait, NULL, CV_DRIVER, NULL); 16648 cv_init(&ha->cv_mbx_intr, NULL, CV_DRIVER, NULL); 16649 16650 /* mutex to protect the ISP request ring. */ 16651 mutex_init(&ha->req_ring_mutex, NULL, MUTEX_DRIVER, intr); 16652 16653 /* Unsolicited buffer conditional variable. */ 16654 cv_init(&ha->cv_ub, NULL, CV_DRIVER, NULL); 16655 16656 mutex_init(&ha->ub_mutex, NULL, MUTEX_DRIVER, intr); 16657 mutex_init(&ha->cache_mutex, NULL, MUTEX_DRIVER, intr); 16658 16659 /* Suspended conditional variable. */ 16660 cv_init(&ha->cv_dr_suspended, NULL, CV_DRIVER, NULL); 16661 16662 /* mutex to protect task daemon context. */ 16663 mutex_init(&ha->task_daemon_mutex, NULL, MUTEX_DRIVER, intr); 16664 16665 /* Task_daemon thread conditional variable. */ 16666 cv_init(&ha->cv_task_daemon, NULL, CV_DRIVER, NULL); 16667 16668 /* mutex to protect diag port manage interface */ 16669 mutex_init(&ha->portmutex, NULL, MUTEX_DRIVER, intr); 16670 16671 /* mutex to protect per instance f/w dump flags and buffer */ 16672 mutex_init(&ha->dump_mutex, NULL, MUTEX_DRIVER, intr); 16673 16674 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance); 16675 16676 return (DDI_SUCCESS); 16677} 16678 16679/* 16680 * ql_destroy_mutex 16681 * Destroys mutex's 16682 * 16683 * Input: 16684 * ha = adapter state pointer. 16685 * 16686 * Returns: 16687 * 16688 * Context: 16689 * Kernel context. 16690 */ 16691static void 16692ql_destroy_mutex(ql_adapter_state_t *ha) 16693{ 16694 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance); 16695 16696 mutex_destroy(&ha->dump_mutex); 16697 mutex_destroy(&ha->portmutex); 16698 cv_destroy(&ha->cv_task_daemon); 16699 mutex_destroy(&ha->task_daemon_mutex); 16700 cv_destroy(&ha->cv_dr_suspended); 16701 mutex_destroy(&ha->cache_mutex); 16702 mutex_destroy(&ha->ub_mutex); 16703 cv_destroy(&ha->cv_ub); 16704 mutex_destroy(&ha->req_ring_mutex); 16705 cv_destroy(&ha->cv_mbx_intr); 16706 cv_destroy(&ha->cv_mbx_wait); 16707 mutex_destroy(&ha->pm_mutex); 16708 mutex_destroy(&ha->mbx_mutex); 16709 mutex_destroy(&ha->intr_mutex); 16710 mutex_destroy(&ha->mutex); 16711 16712 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance); 16713} 16714 16715/* 16716 * ql_fwmodule_resolve 16717 * Loads and resolves external firmware module and symbols 16718 * 16719 * Input: 16720 * ha: adapter state pointer. 16721 * 16722 * Returns: 16723 * ql local function return status code: 16724 * QL_SUCCESS - external f/w module module and symbols resolved 16725 * QL_FW_NOT_SUPPORTED - Driver does not support ISP type 16726 * QL_FWMODLOAD_FAILED - Could not load f/w module (ddi failed) 16727 * QL_FWSYM_NOT_FOUND - Unable to resolve internal f/w symbol 16728 * Context: 16729 * Kernel context. 16730 * 16731 * NOTE: We currently ddi_modopen/ddi_modclose at attach/detach time. We 16732 * could switch to a tighter scope around acutal download (and add an extra 16733 * ddi_modopen for module opens that occur before root is mounted). 16734 * 16735 */ 16736uint32_t 16737ql_fwmodule_resolve(ql_adapter_state_t *ha) 16738{ 16739 int8_t module[128]; 16740 int8_t fw_version[128]; 16741 uint32_t rval = QL_SUCCESS; 16742 caddr_t code, code02; 16743 uint8_t *p_ucfw; 16744 uint16_t *p_usaddr, *p_uslen; 16745 uint32_t *p_uiaddr, *p_uilen, *p_uifw; 16746 uint32_t *p_uiaddr02, *p_uilen02; 16747 struct fw_table *fwt; 16748 extern struct fw_table fw_table[]; 16749 16750 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance); 16751 16752 if (ha->fw_module != NULL) { 16753 EL(ha, "%x f/w module %d.%02d.%02d is already loaded\n", 16754 ha->fw_class, ha->fw_major_version, ha->fw_minor_version, 16755 ha->fw_subminor_version); 16756 return (rval); 16757 } 16758 16759 /* make sure the fw_class is in the fw_table of supported classes */ 16760 for (fwt = &fw_table[0]; fwt->fw_version; fwt++) { 16761 if (fwt->fw_class == ha->fw_class) 16762 break; /* match */ 16763 } 16764 if (fwt->fw_version == NULL) { 16765 cmn_err(CE_WARN, "%s(%d): can't find f/w class %x " 16766 "in driver's fw_table", QL_NAME, ha->instance, 16767 ha->fw_class); 16768 return (QL_FW_NOT_SUPPORTED); 16769 } 16770 16771 /* 16772 * open the module related to the fw_class 16773 */ 16774 (void) snprintf(module, sizeof (module), "misc/qlc/qlc_fw_%x", 16775 ha->fw_class); 16776 16777 ha->fw_module = ddi_modopen(module, KRTLD_MODE_FIRST, NULL); 16778 if (ha->fw_module == NULL) { 16779 cmn_err(CE_WARN, "%s(%d): can't load firmware file %s", 16780 QL_NAME, ha->instance, module); 16781 return (QL_FWMODLOAD_FAILED); 16782 } 16783 16784 /* 16785 * resolve the fw module symbols, data types depend on fw_class 16786 */ 16787 16788 switch (ha->fw_class) { 16789 case 0x2200: 16790 case 0x2300: 16791 case 0x6322: 16792 16793 if ((code = ddi_modsym(ha->fw_module, "risc_code01", 16794 NULL)) == NULL) { 16795 rval = QL_FWSYM_NOT_FOUND; 16796 EL(ha, "failed, f/w module %d rc01 symbol\n", module); 16797 } else if ((p_usaddr = ddi_modsym(ha->fw_module, 16798 "risc_code_addr01", NULL)) == NULL) { 16799 rval = QL_FWSYM_NOT_FOUND; 16800 EL(ha, "failed, f/w module %d rca01 symbol\n", module); 16801 } else if ((p_uslen = ddi_modsym(ha->fw_module, 16802 "risc_code_length01", NULL)) == NULL) { 16803 rval = QL_FWSYM_NOT_FOUND; 16804 EL(ha, "failed, f/w module %d rcl01 symbol\n", module); 16805 } else if ((p_ucfw = ddi_modsym(ha->fw_module, 16806 "firmware_version", NULL)) == NULL) { 16807 rval = QL_FWSYM_NOT_FOUND; 16808 EL(ha, "failed, f/w module %d fwver symbol\n", module); 16809 } 16810 16811 if (rval == QL_SUCCESS) { 16812 ha->risc_fw[0].code = code; 16813 ha->risc_fw[0].addr = *p_usaddr; 16814 ha->risc_fw[0].length = *p_uslen; 16815 16816 (void) snprintf(fw_version, sizeof (fw_version), 16817 "%d.%02d.%02d", p_ucfw[0], p_ucfw[1], p_ucfw[2]); 16818 } 16819 break; 16820 16821 case 0x2400: 16822 case 0x2500: 16823 case 0x8100: 16824 16825 if ((code = ddi_modsym(ha->fw_module, "risc_code01", 16826 NULL)) == NULL) { 16827 rval = QL_FWSYM_NOT_FOUND; 16828 EL(ha, "failed, f/w module %d rc01 symbol\n", module); 16829 } else if ((p_uiaddr = ddi_modsym(ha->fw_module, 16830 "risc_code_addr01", NULL)) == NULL) { 16831 rval = QL_FWSYM_NOT_FOUND; 16832 EL(ha, "failed, f/w module %d rca01 symbol\n", module); 16833 } else if ((p_uilen = ddi_modsym(ha->fw_module, 16834 "risc_code_length01", NULL)) == NULL) { 16835 rval = QL_FWSYM_NOT_FOUND; 16836 EL(ha, "failed, f/w module %d rcl01 symbol\n", module); 16837 } else if ((p_uifw = ddi_modsym(ha->fw_module, 16838 "firmware_version", NULL)) == NULL) { 16839 rval = QL_FWSYM_NOT_FOUND; 16840 EL(ha, "failed, f/w module %d fwver symbol\n", module); 16841 } 16842 16843 if ((code02 = ddi_modsym(ha->fw_module, "risc_code02", 16844 NULL)) == NULL) { 16845 rval = QL_FWSYM_NOT_FOUND; 16846 EL(ha, "failed, f/w module %d rc02 symbol\n", module); 16847 } else if ((p_uiaddr02 = ddi_modsym(ha->fw_module, 16848 "risc_code_addr02", NULL)) == NULL) { 16849 rval = QL_FWSYM_NOT_FOUND; 16850 EL(ha, "failed, f/w module %d rca02 symbol\n", module); 16851 } else if ((p_uilen02 = ddi_modsym(ha->fw_module, 16852 "risc_code_length02", NULL)) == NULL) { 16853 rval = QL_FWSYM_NOT_FOUND; 16854 EL(ha, "failed, f/w module %d rcl02 symbol\n", module); 16855 } 16856 16857 if (rval == QL_SUCCESS) { 16858 ha->risc_fw[0].code = code; 16859 ha->risc_fw[0].addr = *p_uiaddr; 16860 ha->risc_fw[0].length = *p_uilen; 16861 ha->risc_fw[1].code = code02; 16862 ha->risc_fw[1].addr = *p_uiaddr02; 16863 ha->risc_fw[1].length = *p_uilen02; 16864 16865 (void) snprintf(fw_version, sizeof (fw_version), 16866 "%d.%02d.%02d", p_uifw[0], p_uifw[1], p_uifw[2]); 16867 } 16868 break; 16869 16870 default: 16871 EL(ha, "fw_class: '%x' is not supported\n", ha->fw_class); 16872 rval = QL_FW_NOT_SUPPORTED; 16873 } 16874 16875 if (rval != QL_SUCCESS) { 16876 cmn_err(CE_WARN, "%s(%d): can't resolve firmware " 16877 "module %s (%x)", QL_NAME, ha->instance, module, rval); 16878 if (ha->fw_module != NULL) { 16879 (void) ddi_modclose(ha->fw_module); 16880 ha->fw_module = NULL; 16881 } 16882 } else { 16883 /* 16884 * check for firmware version mismatch between module and 16885 * compiled in fw_table version. 16886 */ 16887 16888 if (strcmp(fwt->fw_version, fw_version) != 0) { 16889 16890 /* 16891 * If f/w / driver version mismatches then 16892 * return a successful status -- however warn 16893 * the user that this is NOT recommended. 16894 */ 16895 16896 cmn_err(CE_WARN, "%s(%d): driver / f/w version " 16897 "mismatch for %x: driver-%s module-%s", QL_NAME, 16898 ha->instance, ha->fw_class, fwt->fw_version, 16899 fw_version); 16900 16901 ha->cfg_flags |= CFG_FW_MISMATCH; 16902 } else { 16903 ha->cfg_flags &= ~CFG_FW_MISMATCH; 16904 } 16905 } 16906 16907 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance); 16908 16909 return (rval); 16910} 16911 16912/* 16913 * ql_port_state 16914 * Set the state on all adapter ports. 16915 * 16916 * Input: 16917 * ha: parent adapter state pointer. 16918 * state: port state. 16919 * flags: task daemon flags to set. 16920 * 16921 * Context: 16922 * Interrupt or Kernel context, no mailbox commands allowed. 16923 */ 16924void 16925ql_port_state(ql_adapter_state_t *ha, uint32_t state, uint32_t flags) 16926{ 16927 ql_adapter_state_t *vha; 16928 16929 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance); 16930 16931 TASK_DAEMON_LOCK(ha); 16932 for (vha = ha->pha; vha != NULL; vha = vha->vp_next) { 16933 if (FC_PORT_STATE_MASK(vha->state) != state) { 16934 vha->state = state != FC_STATE_OFFLINE ? 16935 (FC_PORT_SPEED_MASK(vha->state) | state) : state; 16936 vha->task_daemon_flags |= flags; 16937 } 16938 } 16939 ha->pha->task_daemon_flags |= flags & LOOP_DOWN; 16940 TASK_DAEMON_UNLOCK(ha); 16941 16942 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance); 16943} 16944 16945/* 16946 * ql_el_trace_desc_ctor - Construct an extended logging trace descriptor. 16947 * 16948 * Input: Pointer to the adapter state structure. 16949 * Returns: Success or Failure. 16950 * Context: Kernel context. 16951 */ 16952int 16953ql_el_trace_desc_ctor(ql_adapter_state_t *ha) 16954{ 16955 int rval = DDI_SUCCESS; 16956 16957 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance); 16958 16959 ha->el_trace_desc = 16960 (el_trace_desc_t *)kmem_zalloc(sizeof (el_trace_desc_t), KM_SLEEP); 16961 16962 if (ha->el_trace_desc == NULL) { 16963 cmn_err(CE_WARN, "%s(%d): can't construct trace descriptor", 16964 QL_NAME, ha->instance); 16965 rval = DDI_FAILURE; 16966 } else { 16967 ha->el_trace_desc->next = 0; 16968 ha->el_trace_desc->trace_buffer = 16969 (char *)kmem_zalloc(EL_TRACE_BUF_SIZE, KM_SLEEP); 16970 16971 if (ha->el_trace_desc->trace_buffer == NULL) { 16972 cmn_err(CE_WARN, "%s(%d): can't get trace buffer", 16973 QL_NAME, ha->instance); 16974 kmem_free(ha->el_trace_desc, sizeof (el_trace_desc_t)); 16975 rval = DDI_FAILURE; 16976 } else { 16977 ha->el_trace_desc->trace_buffer_size = 16978 EL_TRACE_BUF_SIZE; 16979 mutex_init(&ha->el_trace_desc->mutex, NULL, 16980 MUTEX_DRIVER, NULL); 16981 } 16982 } 16983 16984 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance); 16985 16986 return (rval); 16987} 16988 16989/* 16990 * ql_el_trace_desc_dtor - Destroy an extended logging trace descriptor. 16991 * 16992 * Input: Pointer to the adapter state structure. 16993 * Returns: Success or Failure. 16994 * Context: Kernel context. 16995 */ 16996int 16997ql_el_trace_desc_dtor(ql_adapter_state_t *ha) 16998{ 16999 int rval = DDI_SUCCESS; 17000 17001 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance); 17002 17003 if (ha->el_trace_desc == NULL) { 17004 cmn_err(CE_WARN, "%s(%d): can't destroy el trace descriptor", 17005 QL_NAME, ha->instance); 17006 rval = DDI_FAILURE; 17007 } else { 17008 if (ha->el_trace_desc->trace_buffer != NULL) { 17009 kmem_free(ha->el_trace_desc->trace_buffer, 17010 ha->el_trace_desc->trace_buffer_size); 17011 } 17012 mutex_destroy(&ha->el_trace_desc->mutex); 17013 kmem_free(ha->el_trace_desc, sizeof (el_trace_desc_t)); 17014 } 17015 17016 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance); 17017 17018 return (rval); 17019} 17020 17021/* 17022 * els_cmd_text - Return a pointer to a string describing the command 17023 * 17024 * Input: els_cmd = the els command opcode. 17025 * Returns: pointer to a string. 17026 * Context: Kernel context. 17027 */ 17028char * 17029els_cmd_text(int els_cmd) 17030{ 17031 cmd_table_t *entry = &els_cmd_tbl[0]; 17032 17033 return (cmd_text(entry, els_cmd)); 17034} 17035 17036/* 17037 * mbx_cmd_text - Return a pointer to a string describing the command 17038 * 17039 * Input: mbx_cmd = the mailbox command opcode. 17040 * Returns: pointer to a string. 17041 * Context: Kernel context. 17042 */ 17043char * 17044mbx_cmd_text(int mbx_cmd) 17045{ 17046 cmd_table_t *entry = &mbox_cmd_tbl[0]; 17047 17048 return (cmd_text(entry, mbx_cmd)); 17049} 17050 17051/* 17052 * cmd_text Return a pointer to a string describing the command 17053 * 17054 * Input: entry = the command table 17055 * cmd = the command. 17056 * Returns: pointer to a string. 17057 * Context: Kernel context. 17058 */ 17059char * 17060cmd_text(cmd_table_t *entry, int cmd) 17061{ 17062 for (; entry->cmd != 0; entry++) { 17063 if (entry->cmd == cmd) { 17064 break; 17065 } 17066 } 17067 return (entry->string); 17068} 17069 17070/* 17071 * ql_els_24xx_mbox_cmd_iocb - els request indication. 17072 * 17073 * Input: ha = adapter state pointer. 17074 * srb = scsi request block pointer. 17075 * arg = els passthru entry iocb pointer. 17076 * Returns: 17077 * Context: Kernel context. 17078 */ 17079void 17080ql_els_24xx_iocb(ql_adapter_state_t *ha, ql_srb_t *srb, void *arg) 17081{ 17082 els_descriptor_t els_desc; 17083 17084 /* Extract the ELS information */ 17085 ql_fca_isp_els_request(ha, (fc_packet_t *)srb->pkt, &els_desc); 17086 17087 /* Construct the passthru entry */ 17088 ql_isp_els_request_ctor(&els_desc, (els_passthru_entry_t *)arg); 17089 17090 /* Ensure correct endianness */ 17091 ql_isp_els_handle_cmd_endian(ha, srb); 17092} 17093 17094/* 17095 * ql_fca_isp_els_request - Extract into an els descriptor the info required 17096 * to build an els_passthru iocb from an fc packet. 17097 * 17098 * Input: ha = adapter state pointer. 17099 * pkt = fc packet pointer 17100 * els_desc = els descriptor pointer 17101 * Returns: 17102 * Context: Kernel context. 17103 */ 17104static void 17105ql_fca_isp_els_request(ql_adapter_state_t *ha, fc_packet_t *pkt, 17106 els_descriptor_t *els_desc) 17107{ 17108 ls_code_t els; 17109 17110 ddi_rep_get8(pkt->pkt_cmd_acc, (uint8_t *)&els, 17111 (uint8_t *)pkt->pkt_cmd, sizeof (els), DDI_DEV_AUTOINCR); 17112 17113 els_desc->els = els.ls_code; 17114 17115 els_desc->els_handle = ha->hba_buf.acc_handle; 17116 els_desc->d_id.b24 = pkt->pkt_cmd_fhdr.d_id; 17117 els_desc->s_id.b24 = pkt->pkt_cmd_fhdr.s_id; 17118 /* if n_port_handle is not < 0x7d use 0 */ 17119 if (LOCAL_LOOP_ID(ha->n_port->n_port_handle)) { 17120 els_desc->n_port_handle = ha->n_port->n_port_handle; 17121 } else { 17122 els_desc->n_port_handle = 0; 17123 } 17124 els_desc->control_flags = 0; 17125 els_desc->cmd_byte_count = pkt->pkt_cmdlen; 17126 /* 17127 * Transmit DSD. This field defines the Fibre Channel Frame payload 17128 * (without the frame header) in system memory. 17129 */ 17130 els_desc->tx_dsd.addr[0] = LSD(pkt->pkt_cmd_cookie->dmac_laddress); 17131 els_desc->tx_dsd.addr[1] = MSD(pkt->pkt_cmd_cookie->dmac_laddress); 17132 els_desc->tx_dsd.length = (uint32_t)pkt->pkt_cmd_cookie->dmac_size; 17133 17134 els_desc->rsp_byte_count = pkt->pkt_rsplen; 17135 /* 17136 * Receive DSD. This field defines the ELS response payload buffer 17137 * for the ISP24xx firmware transferring the received ELS 17138 * response frame to a location in host memory. 17139 */ 17140 els_desc->rx_dsd.addr[0] = LSD(pkt->pkt_resp_cookie->dmac_laddress); 17141 els_desc->rx_dsd.addr[1] = MSD(pkt->pkt_resp_cookie->dmac_laddress); 17142 els_desc->rx_dsd.length = (uint32_t)pkt->pkt_resp_cookie->dmac_size; 17143} 17144 17145/* 17146 * ql_isp_els_request_ctor - Construct an els_passthru_entry iocb 17147 * using the els descriptor. 17148 * 17149 * Input: ha = adapter state pointer. 17150 * els_desc = els descriptor pointer. 17151 * els_entry = els passthru entry iocb pointer. 17152 * Returns: 17153 * Context: Kernel context. 17154 */ 17155static void 17156ql_isp_els_request_ctor(els_descriptor_t *els_desc, 17157 els_passthru_entry_t *els_entry) 17158{ 17159 uint32_t *ptr32; 17160 17161 /* 17162 * Construct command packet. 17163 */ 17164 ddi_put8(els_desc->els_handle, &els_entry->entry_type, 17165 (uint8_t)ELS_PASSTHRU_TYPE); 17166 ddi_put16(els_desc->els_handle, &els_entry->n_port_hdl, 17167 els_desc->n_port_handle); 17168 ddi_put8(els_desc->els_handle, &els_entry->sof_type, (uint8_t)BIT_4); 17169 ddi_put32(els_desc->els_handle, &els_entry->rcv_exch_address, 17170 (uint32_t)0); 17171 ddi_put8(els_desc->els_handle, &els_entry->els_cmd_opcode, 17172 els_desc->els); 17173 ddi_put8(els_desc->els_handle, &els_entry->d_id_7_0, 17174 els_desc->d_id.b.al_pa); 17175 ddi_put8(els_desc->els_handle, &els_entry->d_id_15_8, 17176 els_desc->d_id.b.area); 17177 ddi_put8(els_desc->els_handle, &els_entry->d_id_23_16, 17178 els_desc->d_id.b.domain); 17179 ddi_put8(els_desc->els_handle, &els_entry->s_id_7_0, 17180 els_desc->s_id.b.al_pa); 17181 ddi_put8(els_desc->els_handle, &els_entry->s_id_15_8, 17182 els_desc->s_id.b.area); 17183 ddi_put8(els_desc->els_handle, &els_entry->s_id_23_16, 17184 els_desc->s_id.b.domain); 17185 ddi_put16(els_desc->els_handle, &els_entry->control_flags, 17186 els_desc->control_flags); 17187 ddi_put32(els_desc->els_handle, &els_entry->rcv_payld_data_bcnt, 17188 els_desc->rsp_byte_count); 17189 ddi_put32(els_desc->els_handle, &els_entry->xmt_payld_data_bcnt, 17190 els_desc->cmd_byte_count); 17191 /* Load transmit data segments and count. */ 17192 ptr32 = (uint32_t *)&els_entry->xmt_dseg_0_address; 17193 ddi_put16(els_desc->els_handle, &els_entry->xmt_dseg_count, 1); 17194 ddi_put32(els_desc->els_handle, ptr32++, els_desc->tx_dsd.addr[0]); 17195 ddi_put32(els_desc->els_handle, ptr32++, els_desc->tx_dsd.addr[1]); 17196 ddi_put32(els_desc->els_handle, ptr32++, els_desc->tx_dsd.length); 17197 ddi_put16(els_desc->els_handle, &els_entry->rcv_dseg_count, 1); 17198 ddi_put32(els_desc->els_handle, ptr32++, els_desc->rx_dsd.addr[0]); 17199 ddi_put32(els_desc->els_handle, ptr32++, els_desc->rx_dsd.addr[1]); 17200 ddi_put32(els_desc->els_handle, ptr32++, els_desc->rx_dsd.length); 17201} 17202 17203/* 17204 * ql_isp_els_handle_cmd_endian - els requests must be in big endian 17205 * in host memory. 17206 * 17207 * Input: ha = adapter state pointer. 17208 * srb = scsi request block 17209 * Returns: 17210 * Context: Kernel context. 17211 */ 17212void 17213ql_isp_els_handle_cmd_endian(ql_adapter_state_t *ha, ql_srb_t *srb) 17214{ 17215 ls_code_t els; 17216 fc_packet_t *pkt; 17217 uint8_t *ptr; 17218 17219 pkt = srb->pkt; 17220 17221 ddi_rep_get8(pkt->pkt_cmd_acc, (uint8_t *)&els, 17222 (uint8_t *)pkt->pkt_cmd, sizeof (els), DDI_DEV_AUTOINCR); 17223 17224 ptr = (uint8_t *)pkt->pkt_cmd; 17225 17226 ql_isp_els_handle_endian(ha, ptr, els.ls_code); 17227} 17228 17229/* 17230 * ql_isp_els_handle_rsp_endian - els responses must be in big endian 17231 * in host memory. 17232 * Input: ha = adapter state pointer. 17233 * srb = scsi request block 17234 * Returns: 17235 * Context: Kernel context. 17236 */ 17237void 17238ql_isp_els_handle_rsp_endian(ql_adapter_state_t *ha, ql_srb_t *srb) 17239{ 17240 ls_code_t els; 17241 fc_packet_t *pkt; 17242 uint8_t *ptr; 17243 17244 pkt = srb->pkt; 17245 17246 ddi_rep_get8(pkt->pkt_cmd_acc, (uint8_t *)&els, 17247 (uint8_t *)pkt->pkt_cmd, sizeof (els), DDI_DEV_AUTOINCR); 17248 17249 ptr = (uint8_t *)pkt->pkt_resp; 17250 BIG_ENDIAN_32(&els); 17251 ql_isp_els_handle_endian(ha, ptr, els.ls_code); 17252} 17253 17254/* 17255 * ql_isp_els_handle_endian - els requests/responses must be in big endian 17256 * in host memory. 17257 * Input: ha = adapter state pointer. 17258 * ptr = els request/response buffer pointer. 17259 * ls_code = els command code. 17260 * Returns: 17261 * Context: Kernel context. 17262 */ 17263void 17264ql_isp_els_handle_endian(ql_adapter_state_t *ha, uint8_t *ptr, uint8_t ls_code) 17265{ 17266 switch (ls_code) { 17267 case LA_ELS_PLOGI: { 17268 BIG_ENDIAN_32(ptr); /* Command Code */ 17269 ptr += 4; 17270 BIG_ENDIAN_16(ptr); /* FC-PH version */ 17271 ptr += 2; 17272 BIG_ENDIAN_16(ptr); /* b2b credit */ 17273 ptr += 2; 17274 BIG_ENDIAN_16(ptr); /* Cmn Feature flags */ 17275 ptr += 2; 17276 BIG_ENDIAN_16(ptr); /* Rcv data size */ 17277 ptr += 2; 17278 BIG_ENDIAN_16(ptr); /* Concurrent Seq */ 17279 ptr += 2; 17280 BIG_ENDIAN_16(ptr); /* Rel offset */ 17281 ptr += 2; 17282 BIG_ENDIAN_32(ptr); /* E_D_TOV */ 17283 ptr += 4; /* Port Name */ 17284 ptr += 8; /* Node Name */ 17285 ptr += 8; /* Class 1 */ 17286 ptr += 16; /* Class 2 */ 17287 ptr += 16; /* Class 3 */ 17288 BIG_ENDIAN_16(ptr); /* Service options */ 17289 ptr += 2; 17290 BIG_ENDIAN_16(ptr); /* Initiator control */ 17291 ptr += 2; 17292 BIG_ENDIAN_16(ptr); /* Recipient Control */ 17293 ptr += 2; 17294 BIG_ENDIAN_16(ptr); /* Rcv size */ 17295 ptr += 2; 17296 BIG_ENDIAN_16(ptr); /* Concurrent Seq */ 17297 ptr += 2; 17298 BIG_ENDIAN_16(ptr); /* N_Port e2e credit */ 17299 ptr += 2; 17300 BIG_ENDIAN_16(ptr); /* Open Seq/Exch */ 17301 break; 17302 } 17303 case LA_ELS_PRLI: { 17304 BIG_ENDIAN_32(ptr); /* Command Code/Page length */ 17305 ptr += 4; /* Type */ 17306 ptr += 2; 17307 BIG_ENDIAN_16(ptr); /* Flags */ 17308 ptr += 2; 17309 BIG_ENDIAN_32(ptr); /* Originator Process associator */ 17310 ptr += 4; 17311 BIG_ENDIAN_32(ptr); /* Responder Process associator */ 17312 ptr += 4; 17313 BIG_ENDIAN_32(ptr); /* Flags */ 17314 break; 17315 } 17316 default: 17317 EL(ha, "can't handle els code %x\n", ls_code); 17318 break; 17319 } 17320} 17321 17322/* 17323 * ql_n_port_plogi 17324 * In N port 2 N port topology where an N Port has logged in with the 17325 * firmware because it has the N_Port login initiative, we send up 17326 * a plogi by proxy which stimulates the login procedure to continue. 17327 * 17328 * Input: 17329 * ha = adapter state pointer. 17330 * Returns: 17331 * 17332 * Context: 17333 * Kernel context. 17334 */ 17335static int 17336ql_n_port_plogi(ql_adapter_state_t *ha) 17337{ 17338 int rval; 17339 ql_tgt_t *tq; 17340 ql_head_t done_q = { NULL, NULL }; 17341 17342 rval = QL_SUCCESS; 17343 17344 if (ha->topology & QL_N_PORT) { 17345 /* if we're doing this the n_port_handle must be good */ 17346 if (LOCAL_LOOP_ID(ha->n_port->n_port_handle)) { 17347 tq = ql_loop_id_to_queue(ha, 17348 ha->n_port->n_port_handle); 17349 if (tq != NULL) { 17350 (void) ql_send_plogi(ha, tq, &done_q); 17351 } else { 17352 EL(ha, "n_port_handle = %x, tq = %x\n", 17353 ha->n_port->n_port_handle, tq); 17354 } 17355 } else { 17356 EL(ha, "n_port_handle = %x, tq = %x\n", 17357 ha->n_port->n_port_handle, tq); 17358 } 17359 if (done_q.first != NULL) { 17360 ql_done(done_q.first); 17361 } 17362 } 17363 return (rval); 17364} 17365 17366/* 17367 * Compare two WWNs. The NAA is omitted for comparison. 17368 * 17369 * Note particularly that the indentation used in this 17370 * function isn't according to Sun recommendations. It 17371 * is indented to make reading a bit easy. 17372 * 17373 * Return Values: 17374 * if first == second return 0 17375 * if first > second return 1 17376 * if first < second return -1 17377 */ 17378int 17379ql_wwn_cmp(ql_adapter_state_t *ha, la_wwn_t *first, la_wwn_t *second) 17380{ 17381 la_wwn_t t1, t2; 17382 int rval; 17383 17384 EL(ha, "WWPN=%08x%08x\n", 17385 BE_32(first->i_wwn[0]), BE_32(first->i_wwn[1])); 17386 EL(ha, "WWPN=%08x%08x\n", 17387 BE_32(second->i_wwn[0]), BE_32(second->i_wwn[1])); 17388 /* 17389 * Fibre Channel protocol is big endian, so compare 17390 * as big endian values 17391 */ 17392 t1.i_wwn[0] = BE_32(first->i_wwn[0]); 17393 t1.i_wwn[1] = BE_32(first->i_wwn[1]); 17394 17395 t2.i_wwn[0] = BE_32(second->i_wwn[0]); 17396 t2.i_wwn[1] = BE_32(second->i_wwn[1]); 17397 17398 if (t1.i_wwn[0] == t2.i_wwn[0]) { 17399 if (t1.i_wwn[1] == t2.i_wwn[1]) { 17400 rval = 0; 17401 } else if (t1.i_wwn[1] > t2.i_wwn[1]) { 17402 rval = 1; 17403 } else { 17404 rval = -1; 17405 } 17406 } else { 17407 if (t1.i_wwn[0] > t2.i_wwn[0]) { 17408 rval = 1; 17409 } else { 17410 rval = -1; 17411 } 17412 } 17413 return (rval); 17414} 17415 17416/* 17417 * ql_wait_for_td_stop 17418 * Wait for task daemon to stop running. Internal command timeout 17419 * is approximately 30 seconds, so it may help in some corner 17420 * cases to wait that long 17421 * 17422 * Input: 17423 * ha = adapter state pointer. 17424 * 17425 * Returns: 17426 * DDI_SUCCESS or DDI_FAILURE. 17427 * 17428 * Context: 17429 * Kernel context. 17430 */ 17431 17432static int 17433ql_wait_for_td_stop(ql_adapter_state_t *ha) 17434{ 17435 int rval = DDI_FAILURE; 17436 UINT16 wait_cnt; 17437 17438 for (wait_cnt = 0; wait_cnt < 3000; wait_cnt++) { 17439 /* The task daemon clears the stop flag on exit. */ 17440 if (ha->task_daemon_flags & TASK_DAEMON_STOP_FLG) { 17441 if (ha->cprinfo.cc_events & CALLB_CPR_START || 17442 ddi_in_panic()) { 17443 drv_usecwait(10000); 17444 } else { 17445 delay(drv_usectohz(10000)); 17446 } 17447 } else { 17448 rval = DDI_SUCCESS; 17449 break; 17450 } 17451 } 17452 return (rval); 17453} 17454