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