1/* 2 * QLogic iSCSI HBA Driver 3 * Copyright (c) 2003-2006 QLogic Corporation 4 * 5 * See LICENSE.qla4xxx for copyright and licensing details. 6 */ 7 8#include "ql4_def.h" 9 10 11/** 12 * qla4xxx_mailbox_command - issues mailbox commands 13 * @ha: Pointer to host adapter structure. 14 * @inCount: number of mailbox registers to load. 15 * @outCount: number of mailbox registers to return. 16 * @mbx_cmd: data pointer for mailbox in registers. 17 * @mbx_sts: data pointer for mailbox out registers. 18 * 19 * This routine sssue mailbox commands and waits for completion. 20 * If outCount is 0, this routine completes successfully WITHOUT waiting 21 * for the mailbox command to complete. 22 **/ 23static int qla4xxx_mailbox_command(struct scsi_qla_host *ha, uint8_t inCount, 24 uint8_t outCount, uint32_t *mbx_cmd, 25 uint32_t *mbx_sts) 26{ 27 int status = QLA_ERROR; 28 uint8_t i; 29 u_long wait_count; 30 uint32_t intr_status; 31 unsigned long flags = 0; 32 33 /* Make sure that pointers are valid */ 34 if (!mbx_cmd || !mbx_sts) { 35 DEBUG2(printk("scsi%ld: %s: Invalid mbx_cmd or mbx_sts " 36 "pointer\n", ha->host_no, __func__)); 37 return status; 38 } 39 /* Mailbox code active */ 40 wait_count = MBOX_TOV * 100; 41 42 while (wait_count--) { 43 mutex_lock(&ha->mbox_sem); 44 if (!test_bit(AF_MBOX_COMMAND, &ha->flags)) { 45 set_bit(AF_MBOX_COMMAND, &ha->flags); 46 mutex_unlock(&ha->mbox_sem); 47 break; 48 } 49 mutex_unlock(&ha->mbox_sem); 50 if (!wait_count) { 51 DEBUG2(printk("scsi%ld: %s: mbox_sem failed\n", 52 ha->host_no, __func__)); 53 return status; 54 } 55 msleep(10); 56 } 57 58 /* To prevent overwriting mailbox registers for a command that has 59 * not yet been serviced, check to see if a previously issued 60 * mailbox command is interrupting. 61 * ----------------------------------------------------------------- 62 */ 63 spin_lock_irqsave(&ha->hardware_lock, flags); 64 intr_status = readl(&ha->reg->ctrl_status); 65 if (intr_status & CSR_SCSI_PROCESSOR_INTR) { 66 /* Service existing interrupt */ 67 qla4xxx_interrupt_service_routine(ha, intr_status); 68 clear_bit(AF_MBOX_COMMAND_DONE, &ha->flags); 69 } 70 71 /* Send the mailbox command to the firmware */ 72 ha->mbox_status_count = outCount; 73 for (i = 0; i < outCount; i++) 74 ha->mbox_status[i] = 0; 75 76 /* Load all mailbox registers, except mailbox 0. */ 77 for (i = 1; i < inCount; i++) 78 writel(mbx_cmd[i], &ha->reg->mailbox[i]); 79 80 /* Wakeup firmware */ 81 writel(mbx_cmd[0], &ha->reg->mailbox[0]); 82 readl(&ha->reg->mailbox[0]); 83 writel(set_rmask(CSR_INTR_RISC), &ha->reg->ctrl_status); 84 readl(&ha->reg->ctrl_status); 85 spin_unlock_irqrestore(&ha->hardware_lock, flags); 86 87 /* Wait for completion */ 88 89 /* 90 * If we don't want status, don't wait for the mailbox command to 91 * complete. For example, MBOX_CMD_RESET_FW doesn't return status, 92 * you must poll the inbound Interrupt Mask for completion. 93 */ 94 if (outCount == 0) { 95 status = QLA_SUCCESS; 96 goto mbox_exit; 97 } 98 /* Wait for command to complete */ 99 wait_count = jiffies + MBOX_TOV * HZ; 100 while (test_bit(AF_MBOX_COMMAND_DONE, &ha->flags) == 0) { 101 if (time_after_eq(jiffies, wait_count)) 102 break; 103 104 spin_lock_irqsave(&ha->hardware_lock, flags); 105 intr_status = readl(&ha->reg->ctrl_status); 106 if (intr_status & INTR_PENDING) { 107 /* 108 * Service the interrupt. 109 * The ISR will save the mailbox status registers 110 * to a temporary storage location in the adapter 111 * structure. 112 */ 113 ha->mbox_status_count = outCount; 114 qla4xxx_interrupt_service_routine(ha, intr_status); 115 } 116 spin_unlock_irqrestore(&ha->hardware_lock, flags); 117 msleep(10); 118 } 119 120 /* Check for mailbox timeout. */ 121 if (!test_bit(AF_MBOX_COMMAND_DONE, &ha->flags)) { 122 DEBUG2(printk("scsi%ld: Mailbox Cmd 0x%08X timed out ...," 123 " Scheduling Adapter Reset\n", ha->host_no, 124 mbx_cmd[0])); 125 ha->mailbox_timeout_count++; 126 mbx_sts[0] = (-1); 127 set_bit(DPC_RESET_HA, &ha->dpc_flags); 128 goto mbox_exit; 129 } 130 131 /* 132 * Copy the mailbox out registers to the caller's mailbox in/out 133 * structure. 134 */ 135 spin_lock_irqsave(&ha->hardware_lock, flags); 136 for (i = 0; i < outCount; i++) 137 mbx_sts[i] = ha->mbox_status[i]; 138 139 /* Set return status and error flags (if applicable). */ 140 switch (ha->mbox_status[0]) { 141 case MBOX_STS_COMMAND_COMPLETE: 142 status = QLA_SUCCESS; 143 break; 144 145 case MBOX_STS_INTERMEDIATE_COMPLETION: 146 status = QLA_SUCCESS; 147 break; 148 149 case MBOX_STS_BUSY: 150 DEBUG2( printk("scsi%ld: %s: Cmd = %08X, ISP BUSY\n", 151 ha->host_no, __func__, mbx_cmd[0])); 152 ha->mailbox_timeout_count++; 153 break; 154 155 default: 156 DEBUG2(printk("scsi%ld: %s: **** FAILED, cmd = %08X, " 157 "sts = %08X ****\n", ha->host_no, __func__, 158 mbx_cmd[0], mbx_sts[0])); 159 break; 160 } 161 spin_unlock_irqrestore(&ha->hardware_lock, flags); 162 163mbox_exit: 164 mutex_lock(&ha->mbox_sem); 165 clear_bit(AF_MBOX_COMMAND, &ha->flags); 166 mutex_unlock(&ha->mbox_sem); 167 clear_bit(AF_MBOX_COMMAND_DONE, &ha->flags); 168 169 return status; 170} 171 172 173 174/** 175 * qla4xxx_initialize_fw_cb - initializes firmware control block. 176 * @ha: Pointer to host adapter structure. 177 **/ 178int qla4xxx_initialize_fw_cb(struct scsi_qla_host * ha) 179{ 180 struct init_fw_ctrl_blk *init_fw_cb; 181 dma_addr_t init_fw_cb_dma; 182 uint32_t mbox_cmd[MBOX_REG_COUNT]; 183 uint32_t mbox_sts[MBOX_REG_COUNT]; 184 int status = QLA_ERROR; 185 186 init_fw_cb = dma_alloc_coherent(&ha->pdev->dev, 187 sizeof(struct init_fw_ctrl_blk), 188 &init_fw_cb_dma, GFP_KERNEL); 189 if (init_fw_cb == NULL) { 190 DEBUG2(printk("scsi%ld: %s: Unable to alloc init_cb\n", 191 ha->host_no, __func__)); 192 return 10; 193 } 194 memset(init_fw_cb, 0, sizeof(struct init_fw_ctrl_blk)); 195 196 /* Get Initialize Firmware Control Block. */ 197 memset(&mbox_cmd, 0, sizeof(mbox_cmd)); 198 memset(&mbox_sts, 0, sizeof(mbox_sts)); 199 mbox_cmd[0] = MBOX_CMD_GET_INIT_FW_CTRL_BLOCK; 200 mbox_cmd[2] = LSDW(init_fw_cb_dma); 201 mbox_cmd[3] = MSDW(init_fw_cb_dma); 202 if (qla4xxx_mailbox_command(ha, 4, 1, &mbox_cmd[0], &mbox_sts[0]) != 203 QLA_SUCCESS) { 204 dma_free_coherent(&ha->pdev->dev, 205 sizeof(struct init_fw_ctrl_blk), 206 init_fw_cb, init_fw_cb_dma); 207 return status; 208 } 209 210 /* Initialize request and response queues. */ 211 qla4xxx_init_rings(ha); 212 213 /* Fill in the request and response queue information. */ 214 init_fw_cb->ReqQConsumerIndex = cpu_to_le16(ha->request_out); 215 init_fw_cb->ComplQProducerIndex = cpu_to_le16(ha->response_in); 216 init_fw_cb->ReqQLen = __constant_cpu_to_le16(REQUEST_QUEUE_DEPTH); 217 init_fw_cb->ComplQLen = __constant_cpu_to_le16(RESPONSE_QUEUE_DEPTH); 218 init_fw_cb->ReqQAddrLo = cpu_to_le32(LSDW(ha->request_dma)); 219 init_fw_cb->ReqQAddrHi = cpu_to_le32(MSDW(ha->request_dma)); 220 init_fw_cb->ComplQAddrLo = cpu_to_le32(LSDW(ha->response_dma)); 221 init_fw_cb->ComplQAddrHi = cpu_to_le32(MSDW(ha->response_dma)); 222 init_fw_cb->ShadowRegBufAddrLo = 223 cpu_to_le32(LSDW(ha->shadow_regs_dma)); 224 init_fw_cb->ShadowRegBufAddrHi = 225 cpu_to_le32(MSDW(ha->shadow_regs_dma)); 226 227 /* Set up required options. */ 228 init_fw_cb->FwOptions |= 229 __constant_cpu_to_le16(FWOPT_SESSION_MODE | 230 FWOPT_INITIATOR_MODE); 231 init_fw_cb->FwOptions &= __constant_cpu_to_le16(~FWOPT_TARGET_MODE); 232 233 /* Save some info in adapter structure. */ 234 ha->firmware_options = le16_to_cpu(init_fw_cb->FwOptions); 235 ha->tcp_options = le16_to_cpu(init_fw_cb->TCPOptions); 236 ha->heartbeat_interval = init_fw_cb->HeartbeatInterval; 237 memcpy(ha->ip_address, init_fw_cb->IPAddr, 238 min(sizeof(ha->ip_address), sizeof(init_fw_cb->IPAddr))); 239 memcpy(ha->subnet_mask, init_fw_cb->SubnetMask, 240 min(sizeof(ha->subnet_mask), sizeof(init_fw_cb->SubnetMask))); 241 memcpy(ha->gateway, init_fw_cb->GatewayIPAddr, 242 min(sizeof(ha->gateway), sizeof(init_fw_cb->GatewayIPAddr))); 243 memcpy(ha->name_string, init_fw_cb->iSCSINameString, 244 min(sizeof(ha->name_string), 245 sizeof(init_fw_cb->iSCSINameString))); 246 memcpy(ha->alias, init_fw_cb->Alias, 247 min(sizeof(ha->alias), sizeof(init_fw_cb->Alias))); 248 249 /* Save Command Line Paramater info */ 250 ha->port_down_retry_count = le16_to_cpu(init_fw_cb->KeepAliveTimeout); 251 ha->discovery_wait = ql4xdiscoverywait; 252 253 /* Send Initialize Firmware Control Block. */ 254 mbox_cmd[0] = MBOX_CMD_INITIALIZE_FIRMWARE; 255 mbox_cmd[1] = 0; 256 mbox_cmd[2] = LSDW(init_fw_cb_dma); 257 mbox_cmd[3] = MSDW(init_fw_cb_dma); 258 if (qla4xxx_mailbox_command(ha, 4, 1, &mbox_cmd[0], &mbox_sts[0]) == 259 QLA_SUCCESS) 260 status = QLA_SUCCESS; 261 else { 262 DEBUG2(printk("scsi%ld: %s: MBOX_CMD_INITIALIZE_FIRMWARE " 263 "failed w/ status %04X\n", ha->host_no, __func__, 264 mbox_sts[0])); 265 } 266 dma_free_coherent(&ha->pdev->dev, sizeof(struct init_fw_ctrl_blk), 267 init_fw_cb, init_fw_cb_dma); 268 269 return status; 270} 271 272/** 273 * qla4xxx_get_dhcp_ip_address - gets HBA ip address via DHCP 274 * @ha: Pointer to host adapter structure. 275 **/ 276int qla4xxx_get_dhcp_ip_address(struct scsi_qla_host * ha) 277{ 278 struct init_fw_ctrl_blk *init_fw_cb; 279 dma_addr_t init_fw_cb_dma; 280 uint32_t mbox_cmd[MBOX_REG_COUNT]; 281 uint32_t mbox_sts[MBOX_REG_COUNT]; 282 283 init_fw_cb = dma_alloc_coherent(&ha->pdev->dev, 284 sizeof(struct init_fw_ctrl_blk), 285 &init_fw_cb_dma, GFP_KERNEL); 286 if (init_fw_cb == NULL) { 287 printk("scsi%ld: %s: Unable to alloc init_cb\n", ha->host_no, 288 __func__); 289 return 10; 290 } 291 292 /* Get Initialize Firmware Control Block. */ 293 memset(&mbox_cmd, 0, sizeof(mbox_cmd)); 294 memset(&mbox_sts, 0, sizeof(mbox_sts)); 295 memset(init_fw_cb, 0, sizeof(struct init_fw_ctrl_blk)); 296 mbox_cmd[0] = MBOX_CMD_GET_INIT_FW_CTRL_BLOCK; 297 mbox_cmd[2] = LSDW(init_fw_cb_dma); 298 mbox_cmd[3] = MSDW(init_fw_cb_dma); 299 300 if (qla4xxx_mailbox_command(ha, 4, 1, &mbox_cmd[0], &mbox_sts[0]) != 301 QLA_SUCCESS) { 302 DEBUG2(printk("scsi%ld: %s: Failed to get init_fw_ctrl_blk\n", 303 ha->host_no, __func__)); 304 dma_free_coherent(&ha->pdev->dev, 305 sizeof(struct init_fw_ctrl_blk), 306 init_fw_cb, init_fw_cb_dma); 307 return QLA_ERROR; 308 } 309 310 /* Save IP Address. */ 311 memcpy(ha->ip_address, init_fw_cb->IPAddr, 312 min(sizeof(ha->ip_address), sizeof(init_fw_cb->IPAddr))); 313 memcpy(ha->subnet_mask, init_fw_cb->SubnetMask, 314 min(sizeof(ha->subnet_mask), sizeof(init_fw_cb->SubnetMask))); 315 memcpy(ha->gateway, init_fw_cb->GatewayIPAddr, 316 min(sizeof(ha->gateway), sizeof(init_fw_cb->GatewayIPAddr))); 317 318 dma_free_coherent(&ha->pdev->dev, sizeof(struct init_fw_ctrl_blk), 319 init_fw_cb, init_fw_cb_dma); 320 321 return QLA_SUCCESS; 322} 323 324/** 325 * qla4xxx_get_firmware_state - gets firmware state of HBA 326 * @ha: Pointer to host adapter structure. 327 **/ 328int qla4xxx_get_firmware_state(struct scsi_qla_host * ha) 329{ 330 uint32_t mbox_cmd[MBOX_REG_COUNT]; 331 uint32_t mbox_sts[MBOX_REG_COUNT]; 332 333 /* Get firmware version */ 334 memset(&mbox_cmd, 0, sizeof(mbox_cmd)); 335 memset(&mbox_sts, 0, sizeof(mbox_sts)); 336 mbox_cmd[0] = MBOX_CMD_GET_FW_STATE; 337 if (qla4xxx_mailbox_command(ha, 1, 4, &mbox_cmd[0], &mbox_sts[0]) != 338 QLA_SUCCESS) { 339 DEBUG2(printk("scsi%ld: %s: MBOX_CMD_GET_FW_STATE failed w/ " 340 "status %04X\n", ha->host_no, __func__, 341 mbox_sts[0])); 342 return QLA_ERROR; 343 } 344 ha->firmware_state = mbox_sts[1]; 345 ha->board_id = mbox_sts[2]; 346 ha->addl_fw_state = mbox_sts[3]; 347 DEBUG2(printk("scsi%ld: %s firmware_state=0x%x\n", 348 ha->host_no, __func__, ha->firmware_state);) 349 350 return QLA_SUCCESS; 351} 352 353/** 354 * qla4xxx_get_firmware_status - retrieves firmware status 355 * @ha: Pointer to host adapter structure. 356 **/ 357int qla4xxx_get_firmware_status(struct scsi_qla_host * ha) 358{ 359 uint32_t mbox_cmd[MBOX_REG_COUNT]; 360 uint32_t mbox_sts[MBOX_REG_COUNT]; 361 362 /* Get firmware version */ 363 memset(&mbox_cmd, 0, sizeof(mbox_cmd)); 364 memset(&mbox_sts, 0, sizeof(mbox_sts)); 365 mbox_cmd[0] = MBOX_CMD_GET_FW_STATUS; 366 if (qla4xxx_mailbox_command(ha, 1, 3, &mbox_cmd[0], &mbox_sts[0]) != 367 QLA_SUCCESS) { 368 DEBUG2(printk("scsi%ld: %s: MBOX_CMD_GET_FW_STATUS failed w/ " 369 "status %04X\n", ha->host_no, __func__, 370 mbox_sts[0])); 371 return QLA_ERROR; 372 } 373 374 /* High-water mark of IOCBs */ 375 ha->iocb_hiwat = mbox_sts[2]; 376 if (ha->iocb_hiwat > IOCB_HIWAT_CUSHION) 377 ha->iocb_hiwat -= IOCB_HIWAT_CUSHION; 378 else 379 dev_info(&ha->pdev->dev, "WARNING!!! You have less than %d " 380 "firmare IOCBs available (%d).\n", 381 IOCB_HIWAT_CUSHION, ha->iocb_hiwat); 382 383 return QLA_SUCCESS; 384} 385 386/** 387 * qla4xxx_get_fwddb_entry - retrieves firmware ddb entry 388 * @ha: Pointer to host adapter structure. 389 * @fw_ddb_index: Firmware's device database index 390 * @fw_ddb_entry: Pointer to firmware's device database entry structure 391 * @num_valid_ddb_entries: Pointer to number of valid ddb entries 392 * @next_ddb_index: Pointer to next valid device database index 393 * @fw_ddb_device_state: Pointer to device state 394 **/ 395int qla4xxx_get_fwddb_entry(struct scsi_qla_host *ha, 396 uint16_t fw_ddb_index, 397 struct dev_db_entry *fw_ddb_entry, 398 dma_addr_t fw_ddb_entry_dma, 399 uint32_t *num_valid_ddb_entries, 400 uint32_t *next_ddb_index, 401 uint32_t *fw_ddb_device_state, 402 uint32_t *conn_err_detail, 403 uint16_t *tcp_source_port_num, 404 uint16_t *connection_id) 405{ 406 int status = QLA_ERROR; 407 uint32_t mbox_cmd[MBOX_REG_COUNT]; 408 uint32_t mbox_sts[MBOX_REG_COUNT]; 409 410 /* Make sure the device index is valid */ 411 if (fw_ddb_index >= MAX_DDB_ENTRIES) { 412 DEBUG2(printk("scsi%ld: %s: index [%d] out of range.\n", 413 ha->host_no, __func__, fw_ddb_index)); 414 goto exit_get_fwddb; 415 } 416 memset(&mbox_cmd, 0, sizeof(mbox_cmd)); 417 memset(&mbox_sts, 0, sizeof(mbox_sts)); 418 mbox_cmd[0] = MBOX_CMD_GET_DATABASE_ENTRY; 419 mbox_cmd[1] = (uint32_t) fw_ddb_index; 420 mbox_cmd[2] = LSDW(fw_ddb_entry_dma); 421 mbox_cmd[3] = MSDW(fw_ddb_entry_dma); 422 if (qla4xxx_mailbox_command(ha, 4, 7, &mbox_cmd[0], &mbox_sts[0]) == 423 QLA_ERROR) { 424 DEBUG2(printk("scsi%ld: %s: MBOX_CMD_GET_DATABASE_ENTRY failed" 425 " with status 0x%04X\n", ha->host_no, __func__, 426 mbox_sts[0])); 427 goto exit_get_fwddb; 428 } 429 if (fw_ddb_index != mbox_sts[1]) { 430 DEBUG2(printk("scsi%ld: %s: index mismatch [%d] != [%d].\n", 431 ha->host_no, __func__, fw_ddb_index, 432 mbox_sts[1])); 433 goto exit_get_fwddb; 434 } 435 if (fw_ddb_entry) { 436 dev_info(&ha->pdev->dev, "DDB[%d] MB0 %04x Tot %d Next %d " 437 "State %04x ConnErr %08x %d.%d.%d.%d:%04d \"%s\"\n", 438 fw_ddb_index, mbox_sts[0], mbox_sts[2], mbox_sts[3], 439 mbox_sts[4], mbox_sts[5], fw_ddb_entry->ipAddr[0], 440 fw_ddb_entry->ipAddr[1], fw_ddb_entry->ipAddr[2], 441 fw_ddb_entry->ipAddr[3], 442 le16_to_cpu(fw_ddb_entry->portNumber), 443 fw_ddb_entry->iscsiName); 444 } 445 if (num_valid_ddb_entries) 446 *num_valid_ddb_entries = mbox_sts[2]; 447 if (next_ddb_index) 448 *next_ddb_index = mbox_sts[3]; 449 if (fw_ddb_device_state) 450 *fw_ddb_device_state = mbox_sts[4]; 451 452 /* 453 * RA: This mailbox has been changed to pass connection error and 454 * details. Its true for ISP4010 as per Version E - Not sure when it 455 * was changed. Get the time2wait from the fw_dd_entry field : 456 * default_time2wait which we call it as minTime2Wait DEV_DB_ENTRY 457 * struct. 458 */ 459 if (conn_err_detail) 460 *conn_err_detail = mbox_sts[5]; 461 if (tcp_source_port_num) 462 *tcp_source_port_num = (uint16_t) mbox_sts[6] >> 16; 463 if (connection_id) 464 *connection_id = (uint16_t) mbox_sts[6] & 0x00FF; 465 status = QLA_SUCCESS; 466 467exit_get_fwddb: 468 return status; 469} 470 471/** 472 * qla4xxx_set_fwddb_entry - sets a ddb entry. 473 * @ha: Pointer to host adapter structure. 474 * @fw_ddb_index: Firmware's device database index 475 * @fw_ddb_entry: Pointer to firmware's ddb entry structure, or NULL. 476 * 477 * This routine initializes or updates the adapter's device database 478 * entry for the specified device. It also triggers a login for the 479 * specified device. Therefore, it may also be used as a secondary 480 * login routine when a NULL pointer is specified for the fw_ddb_entry. 481 **/ 482int qla4xxx_set_ddb_entry(struct scsi_qla_host * ha, uint16_t fw_ddb_index, 483 dma_addr_t fw_ddb_entry_dma) 484{ 485 uint32_t mbox_cmd[MBOX_REG_COUNT]; 486 uint32_t mbox_sts[MBOX_REG_COUNT]; 487 488 /* Do not wait for completion. The firmware will send us an 489 * ASTS_DATABASE_CHANGED (0x8014) to notify us of the login status. 490 */ 491 memset(&mbox_cmd, 0, sizeof(mbox_cmd)); 492 memset(&mbox_sts, 0, sizeof(mbox_sts)); 493 494 mbox_cmd[0] = MBOX_CMD_SET_DATABASE_ENTRY; 495 mbox_cmd[1] = (uint32_t) fw_ddb_index; 496 mbox_cmd[2] = LSDW(fw_ddb_entry_dma); 497 mbox_cmd[3] = MSDW(fw_ddb_entry_dma); 498 return qla4xxx_mailbox_command(ha, 4, 1, &mbox_cmd[0], &mbox_sts[0]); 499} 500 501 502/** 503 * qla4xxx_get_crash_record - retrieves crash record. 504 * @ha: Pointer to host adapter structure. 505 * 506 * This routine retrieves a crash record from the QLA4010 after an 8002h aen. 507 **/ 508void qla4xxx_get_crash_record(struct scsi_qla_host * ha) 509{ 510 uint32_t mbox_cmd[MBOX_REG_COUNT]; 511 uint32_t mbox_sts[MBOX_REG_COUNT]; 512 struct crash_record *crash_record = NULL; 513 dma_addr_t crash_record_dma = 0; 514 uint32_t crash_record_size = 0; 515 memset(&mbox_cmd, 0, sizeof(mbox_cmd)); 516 memset(&mbox_sts, 0, sizeof(mbox_cmd)); 517 518 /* Get size of crash record. */ 519 mbox_cmd[0] = MBOX_CMD_GET_CRASH_RECORD; 520 if (qla4xxx_mailbox_command(ha, 5, 5, &mbox_cmd[0], &mbox_sts[0]) != 521 QLA_SUCCESS) { 522 DEBUG2(printk("scsi%ld: %s: ERROR: Unable to retrieve size!\n", 523 ha->host_no, __func__)); 524 goto exit_get_crash_record; 525 } 526 crash_record_size = mbox_sts[4]; 527 if (crash_record_size == 0) { 528 DEBUG2(printk("scsi%ld: %s: ERROR: Crash record size is 0!\n", 529 ha->host_no, __func__)); 530 goto exit_get_crash_record; 531 } 532 533 /* Alloc Memory for Crash Record. */ 534 crash_record = dma_alloc_coherent(&ha->pdev->dev, crash_record_size, 535 &crash_record_dma, GFP_KERNEL); 536 if (crash_record == NULL) 537 goto exit_get_crash_record; 538 539 /* Get Crash Record. */ 540 mbox_cmd[0] = MBOX_CMD_GET_CRASH_RECORD; 541 mbox_cmd[2] = LSDW(crash_record_dma); 542 mbox_cmd[3] = MSDW(crash_record_dma); 543 mbox_cmd[4] = crash_record_size; 544 if (qla4xxx_mailbox_command(ha, 5, 5, &mbox_cmd[0], &mbox_sts[0]) != 545 QLA_SUCCESS) 546 goto exit_get_crash_record; 547 548 /* Dump Crash Record. */ 549 550exit_get_crash_record: 551 if (crash_record) 552 dma_free_coherent(&ha->pdev->dev, crash_record_size, 553 crash_record, crash_record_dma); 554} 555 556 557/** 558 * qla4xxx_reset_lun - issues LUN Reset 559 * @ha: Pointer to host adapter structure. 560 * @db_entry: Pointer to device database entry 561 * @un_entry: Pointer to lun entry structure 562 * 563 * This routine performs a LUN RESET on the specified target/lun. 564 * The caller must ensure that the ddb_entry and lun_entry pointers 565 * are valid before calling this routine. 566 **/ 567int qla4xxx_reset_lun(struct scsi_qla_host * ha, struct ddb_entry * ddb_entry, 568 int lun) 569{ 570 uint32_t mbox_cmd[MBOX_REG_COUNT]; 571 uint32_t mbox_sts[MBOX_REG_COUNT]; 572 int status = QLA_SUCCESS; 573 574 DEBUG2(printk("scsi%ld:%d:%d: lun reset issued\n", ha->host_no, 575 ddb_entry->os_target_id, lun)); 576 577 /* 578 * Send lun reset command to ISP, so that the ISP will return all 579 * outstanding requests with RESET status 580 */ 581 memset(&mbox_cmd, 0, sizeof(mbox_cmd)); 582 memset(&mbox_sts, 0, sizeof(mbox_sts)); 583 mbox_cmd[0] = MBOX_CMD_LUN_RESET; 584 mbox_cmd[1] = ddb_entry->fw_ddb_index; 585 mbox_cmd[2] = lun << 8; 586 mbox_cmd[5] = 0x01; /* Immediate Command Enable */ 587 qla4xxx_mailbox_command(ha, 6, 1, &mbox_cmd[0], &mbox_sts[0]); 588 if (mbox_sts[0] != MBOX_STS_COMMAND_COMPLETE && 589 mbox_sts[0] != MBOX_STS_COMMAND_ERROR) 590 status = QLA_ERROR; 591 592 return status; 593} 594 595 596int qla4xxx_get_flash(struct scsi_qla_host * ha, dma_addr_t dma_addr, 597 uint32_t offset, uint32_t len) 598{ 599 uint32_t mbox_cmd[MBOX_REG_COUNT]; 600 uint32_t mbox_sts[MBOX_REG_COUNT]; 601 602 memset(&mbox_cmd, 0, sizeof(mbox_cmd)); 603 memset(&mbox_sts, 0, sizeof(mbox_sts)); 604 mbox_cmd[0] = MBOX_CMD_READ_FLASH; 605 mbox_cmd[1] = LSDW(dma_addr); 606 mbox_cmd[2] = MSDW(dma_addr); 607 mbox_cmd[3] = offset; 608 mbox_cmd[4] = len; 609 if (qla4xxx_mailbox_command(ha, 5, 2, &mbox_cmd[0], &mbox_sts[0]) != 610 QLA_SUCCESS) { 611 DEBUG2(printk("scsi%ld: %s: MBOX_CMD_READ_FLASH, failed w/ " 612 "status %04X %04X, offset %08x, len %08x\n", ha->host_no, 613 __func__, mbox_sts[0], mbox_sts[1], offset, len)); 614 return QLA_ERROR; 615 } 616 return QLA_SUCCESS; 617} 618 619/** 620 * qla4xxx_get_fw_version - gets firmware version 621 * @ha: Pointer to host adapter structure. 622 * 623 * Retrieves the firmware version on HBA. In QLA4010, mailboxes 2 & 3 may 624 * hold an address for data. Make sure that we write 0 to those mailboxes, 625 * if unused. 626 **/ 627int qla4xxx_get_fw_version(struct scsi_qla_host * ha) 628{ 629 uint32_t mbox_cmd[MBOX_REG_COUNT]; 630 uint32_t mbox_sts[MBOX_REG_COUNT]; 631 632 /* Get firmware version. */ 633 memset(&mbox_cmd, 0, sizeof(mbox_cmd)); 634 memset(&mbox_sts, 0, sizeof(mbox_sts)); 635 mbox_cmd[0] = MBOX_CMD_ABOUT_FW; 636 if (qla4xxx_mailbox_command(ha, 4, 5, &mbox_cmd[0], &mbox_sts[0]) != 637 QLA_SUCCESS) { 638 DEBUG2(printk("scsi%ld: %s: MBOX_CMD_ABOUT_FW failed w/ " 639 "status %04X\n", ha->host_no, __func__, mbox_sts[0])); 640 return QLA_ERROR; 641 } 642 643 /* Save firmware version information. */ 644 ha->firmware_version[0] = mbox_sts[1]; 645 ha->firmware_version[1] = mbox_sts[2]; 646 ha->patch_number = mbox_sts[3]; 647 ha->build_number = mbox_sts[4]; 648 649 return QLA_SUCCESS; 650} 651 652static int qla4xxx_get_default_ddb(struct scsi_qla_host *ha, 653 dma_addr_t dma_addr) 654{ 655 uint32_t mbox_cmd[MBOX_REG_COUNT]; 656 uint32_t mbox_sts[MBOX_REG_COUNT]; 657 658 memset(&mbox_cmd, 0, sizeof(mbox_cmd)); 659 memset(&mbox_sts, 0, sizeof(mbox_sts)); 660 661 mbox_cmd[0] = MBOX_CMD_GET_DATABASE_ENTRY_DEFAULTS; 662 mbox_cmd[2] = LSDW(dma_addr); 663 mbox_cmd[3] = MSDW(dma_addr); 664 665 if (qla4xxx_mailbox_command(ha, 4, 1, &mbox_cmd[0], &mbox_sts[0]) != 666 QLA_SUCCESS) { 667 DEBUG2(printk("scsi%ld: %s: failed status %04X\n", 668 ha->host_no, __func__, mbox_sts[0])); 669 return QLA_ERROR; 670 } 671 return QLA_SUCCESS; 672} 673 674static int qla4xxx_req_ddb_entry(struct scsi_qla_host *ha, uint32_t *ddb_index) 675{ 676 uint32_t mbox_cmd[MBOX_REG_COUNT]; 677 uint32_t mbox_sts[MBOX_REG_COUNT]; 678 679 memset(&mbox_cmd, 0, sizeof(mbox_cmd)); 680 memset(&mbox_sts, 0, sizeof(mbox_sts)); 681 682 mbox_cmd[0] = MBOX_CMD_REQUEST_DATABASE_ENTRY; 683 mbox_cmd[1] = MAX_PRST_DEV_DB_ENTRIES; 684 685 if (qla4xxx_mailbox_command(ha, 2, 3, &mbox_cmd[0], &mbox_sts[0]) != 686 QLA_SUCCESS) { 687 if (mbox_sts[0] == MBOX_STS_COMMAND_ERROR) { 688 *ddb_index = mbox_sts[2]; 689 } else { 690 DEBUG2(printk("scsi%ld: %s: failed status %04X\n", 691 ha->host_no, __func__, mbox_sts[0])); 692 return QLA_ERROR; 693 } 694 } else { 695 *ddb_index = MAX_PRST_DEV_DB_ENTRIES; 696 } 697 698 return QLA_SUCCESS; 699} 700 701 702int qla4xxx_send_tgts(struct scsi_qla_host *ha, char *ip, uint16_t port) 703{ 704 struct dev_db_entry *fw_ddb_entry; 705 dma_addr_t fw_ddb_entry_dma; 706 uint32_t ddb_index; 707 int ret_val = QLA_SUCCESS; 708 709 710 fw_ddb_entry = dma_alloc_coherent(&ha->pdev->dev, 711 sizeof(*fw_ddb_entry), 712 &fw_ddb_entry_dma, GFP_KERNEL); 713 if (!fw_ddb_entry) { 714 DEBUG2(printk("scsi%ld: %s: Unable to allocate dma buffer.\n", 715 ha->host_no, __func__)); 716 ret_val = QLA_ERROR; 717 goto qla4xxx_send_tgts_exit; 718 } 719 720 ret_val = qla4xxx_get_default_ddb(ha, fw_ddb_entry_dma); 721 if (ret_val != QLA_SUCCESS) 722 goto qla4xxx_send_tgts_exit; 723 724 ret_val = qla4xxx_req_ddb_entry(ha, &ddb_index); 725 if (ret_val != QLA_SUCCESS) 726 goto qla4xxx_send_tgts_exit; 727 728 memset((void *)fw_ddb_entry->iSCSIAlias, 0, 729 sizeof(fw_ddb_entry->iSCSIAlias)); 730 731 memset((void *)fw_ddb_entry->iscsiName, 0, 732 sizeof(fw_ddb_entry->iscsiName)); 733 734 memset((void *)fw_ddb_entry->ipAddr, 0, sizeof(fw_ddb_entry->ipAddr)); 735 memset((void *)fw_ddb_entry->targetAddr, 0, 736 sizeof(fw_ddb_entry->targetAddr)); 737 738 fw_ddb_entry->options = (DDB_OPT_DISC_SESSION | DDB_OPT_TARGET); 739 fw_ddb_entry->portNumber = cpu_to_le16(ntohs(port)); 740 741 fw_ddb_entry->ipAddr[0] = *ip; 742 fw_ddb_entry->ipAddr[1] = *(ip + 1); 743 fw_ddb_entry->ipAddr[2] = *(ip + 2); 744 fw_ddb_entry->ipAddr[3] = *(ip + 3); 745 746 ret_val = qla4xxx_set_ddb_entry(ha, ddb_index, fw_ddb_entry_dma); 747 748qla4xxx_send_tgts_exit: 749 dma_free_coherent(&ha->pdev->dev, sizeof(*fw_ddb_entry), 750 fw_ddb_entry, fw_ddb_entry_dma); 751 return ret_val; 752} 753