linux/drivers/scsi/qla4xxx/ql4_mbx.c
<<
>>
Prefs
   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 **/
  26static 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
 166mbox_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 **/
 179int 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 **/
 285int 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 **/
 339int 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 **/
 370int 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 **/
 410int 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
 485exit_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 **/
 500int 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 **/
 527void 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
 575exit_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 **/
 585void 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
 670exit_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 **/
 686int 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
 717int 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 **/
 750int 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
 777static 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
 799static 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
 827int 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
 873qla4xxx_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