Exemplo n.º 1
0
void qla4xxx_dump_registers(struct scsi_qla_host *ha)
{
	uint8_t i;

	if (is_qla8022(ha)) {
		for (i = 1; i < MBOX_REG_COUNT; i++)
			printk(KERN_INFO "mailbox[%d]     = 0x%08X\n",
			    i, readl(&ha->qla4_8xxx_reg->mailbox_in[i]));
		return;
	}

	for (i = 0; i < MBOX_REG_COUNT; i++) {
		printk(KERN_INFO "0x%02X mailbox[%d]      = 0x%08X\n",
		    (uint8_t) offsetof(struct isp_reg, mailbox[i]), i,
		    readw(&ha->reg->mailbox[i]));
	}

	printk(KERN_INFO "0x%02X flash_address            = 0x%08X\n",
	    (uint8_t) offsetof(struct isp_reg, flash_address),
	    readw(&ha->reg->flash_address));
	printk(KERN_INFO "0x%02X flash_data               = 0x%08X\n",
	    (uint8_t) offsetof(struct isp_reg, flash_data),
	    readw(&ha->reg->flash_data));
	printk(KERN_INFO "0x%02X ctrl_status              = 0x%08X\n",
	    (uint8_t) offsetof(struct isp_reg, ctrl_status),
	    readw(&ha->reg->ctrl_status));

	if (is_qla4010(ha)) {
		printk(KERN_INFO "0x%02X nvram            = 0x%08X\n",
		    (uint8_t) offsetof(struct isp_reg, u1.isp4010.nvram),
		    readw(&ha->reg->u1.isp4010.nvram));
	} else if (is_qla4022(ha) | is_qla4032(ha)) {
Exemplo n.º 2
0
static ssize_t
qla4_8xxx_sysfs_write_fw_dump(struct file *filep, struct kobject *kobj,
			      struct bin_attribute *ba, char *buf, loff_t off,
			      size_t count)
{
	struct scsi_qla_host *ha = to_qla_host(dev_to_shost(container_of(kobj,
					       struct device, kobj)));
	uint32_t dev_state;
	int reading;

	if (is_qla40XX(ha))
		return -EINVAL;

	if (off != 0)
		return 0;

	reading = simple_strtol(buf, NULL, 10);
	switch (reading) {
	case 0:
		/* clear dump collection flags */
		if (test_and_clear_bit(AF_82XX_DUMP_READING, &ha->flags)) {
			clear_bit(AF_82XX_FW_DUMPED, &ha->flags);
			/* Reload minidump template */
			qla4xxx_alloc_fw_dump(ha);
			DEBUG2(ql4_printk(KERN_INFO, ha,
					  "Firmware template reloaded\n"));
		}

		break;
	case 1:
		/* Set flag to read dump */
		if (test_bit(AF_82XX_FW_DUMPED, &ha->flags) &&
		    !test_bit(AF_82XX_DUMP_READING, &ha->flags)) {
			set_bit(AF_82XX_DUMP_READING, &ha->flags);
			DEBUG2(ql4_printk(KERN_INFO, ha,
					  "Raw firmware dump ready for read on (%ld).\n",
					  ha->host_no));
		}
		break;
	case 2:
		/* Reset HBA and collect FW dump */
		ha->isp_ops->idc_lock(ha);
		dev_state = qla4_8xxx_rd_direct(ha, QLA8XXX_CRB_DEV_STATE);
		if (dev_state == QLA8XXX_DEV_READY) {
			ql4_printk(KERN_INFO, ha, "%s: Setting Need reset\n",
				   __func__);
			qla4_8xxx_wr_direct(ha, QLA8XXX_CRB_DEV_STATE,
					    QLA8XXX_DEV_NEED_RESET);
			if (is_qla8022(ha) ||
			    (is_qla8032(ha) &&
			     qla4_83xx_can_perform_reset(ha))) {
				set_bit(AF_8XXX_RST_OWNER, &ha->flags);
				set_bit(AF_FW_RECOVERY, &ha->flags);
				ql4_printk(KERN_INFO, ha, "%s: Reset owner is 0x%x\n",
					   __func__, ha->func_num);
			}
		} else
			ql4_printk(KERN_INFO, ha,
				   "%s: Reset not performed as device state is 0x%x\n",
				   __func__, dev_state);

		ha->isp_ops->idc_unlock(ha);
		break;
	default:
		/* do nothing */
		break;
	}

	return count;
}
Exemplo n.º 3
0
void qla4xxx_dump_registers(struct scsi_qla_host *ha)
{
	uint8_t i;

	if (is_qla8022(ha)) {
		for (i = 1; i < MBOX_REG_COUNT; i++)
//			printk(KERN_INFO "mailbox[%d]     = 0x%08X\n",
;
		return;
	}

	for (i = 0; i < MBOX_REG_COUNT; i++) {
//		printk(KERN_INFO "0x%02X mailbox[%d]      = 0x%08X\n",
//		    (uint8_t) offsetof(struct isp_reg, mailbox[i]), i,
;
	}

//	printk(KERN_INFO "0x%02X flash_address            = 0x%08X\n",
//	    (uint8_t) offsetof(struct isp_reg, flash_address),
;
//	printk(KERN_INFO "0x%02X flash_data               = 0x%08X\n",
//	    (uint8_t) offsetof(struct isp_reg, flash_data),
;
//	printk(KERN_INFO "0x%02X ctrl_status              = 0x%08X\n",
//	    (uint8_t) offsetof(struct isp_reg, ctrl_status),
;

	if (is_qla4010(ha)) {
//		printk(KERN_INFO "0x%02X nvram            = 0x%08X\n",
//		    (uint8_t) offsetof(struct isp_reg, u1.isp4010.nvram),
;
	} else if (is_qla4022(ha) | is_qla4032(ha)) {
//		printk(KERN_INFO "0x%02X intr_mask        = 0x%08X\n",
//		    (uint8_t) offsetof(struct isp_reg, u1.isp4022.intr_mask),
;
//		printk(KERN_INFO "0x%02X nvram            = 0x%08X\n",
//		    (uint8_t) offsetof(struct isp_reg, u1.isp4022.nvram),
;
//		printk(KERN_INFO "0x%02X semaphore	  = 0x%08X\n",
//		    (uint8_t) offsetof(struct isp_reg, u1.isp4022.semaphore),
;
	}
//	printk(KERN_INFO "0x%02X req_q_in                 = 0x%08X\n",
//	    (uint8_t) offsetof(struct isp_reg, req_q_in),
;
//	printk(KERN_INFO "0x%02X rsp_q_out                = 0x%08X\n",
//	    (uint8_t) offsetof(struct isp_reg, rsp_q_out),
;

	if (is_qla4010(ha)) {
//		printk(KERN_INFO "0x%02X ext_hw_conf      = 0x%08X\n",
//		    (uint8_t) offsetof(struct isp_reg, u2.isp4010.ext_hw_conf),
;
//		printk(KERN_INFO "0x%02X port_ctrl        = 0x%08X\n",
//		    (uint8_t) offsetof(struct isp_reg, u2.isp4010.port_ctrl),
;
//		printk(KERN_INFO "0x%02X port_status      = 0x%08X\n",
//		    (uint8_t) offsetof(struct isp_reg, u2.isp4010.port_status),
;
//		printk(KERN_INFO "0x%02X req_q_out        = 0x%08X\n",
//		    (uint8_t) offsetof(struct isp_reg, u2.isp4010.req_q_out),
;
//		printk(KERN_INFO "0x%02X gp_out           = 0x%08X\n",
//		    (uint8_t) offsetof(struct isp_reg, u2.isp4010.gp_out),
;
//		printk(KERN_INFO "0x%02X gp_in	          = 0x%08X\n",
//		    (uint8_t) offsetof(struct isp_reg, u2.isp4010.gp_in),
;
//		printk(KERN_INFO "0x%02X port_err_status  = 0x%08X\n", (uint8_t)
//		    offsetof(struct isp_reg, u2.isp4010.port_err_status),
;
	} else if (is_qla4022(ha) | is_qla4032(ha)) {
;
//		printk(KERN_INFO "0x%02X ext_hw_conf      = 0x%08X\n", (uint8_t)
//		    offsetof(struct isp_reg, u2.isp4022.p0.ext_hw_conf),
;
//		printk(KERN_INFO "0x%02X port_ctrl        = 0x%08X\n", (uint8_t)
//		    offsetof(struct isp_reg, u2.isp4022.p0.port_ctrl),
;
//		printk(KERN_INFO "0x%02X port_status      = 0x%08X\n", (uint8_t)
//		    offsetof(struct isp_reg, u2.isp4022.p0.port_status),
;
//		printk(KERN_INFO "0x%02X gp_out           = 0x%08X\n",
//		    (uint8_t) offsetof(struct isp_reg, u2.isp4022.p0.gp_out),
;
//		printk(KERN_INFO "0x%02X gp_in            = 0x%08X\n",
//		    (uint8_t) offsetof(struct isp_reg, u2.isp4022.p0.gp_in),
;
//		printk(KERN_INFO "0x%02X port_err_status  = 0x%08X\n", (uint8_t)
//		    offsetof(struct isp_reg, u2.isp4022.p0.port_err_status),
;
;
		writel(HOST_MEM_CFG_PAGE & set_rmask(CSR_SCSI_PAGE_SELECT),
		    &ha->reg->ctrl_status);
//		printk(KERN_INFO "0x%02X req_q_out        = 0x%08X\n",
//		    (uint8_t) offsetof(struct isp_reg, u2.isp4022.p1.req_q_out),
;
		writel(PORT_CTRL_STAT_PAGE & set_rmask(CSR_SCSI_PAGE_SELECT),
		    &ha->reg->ctrl_status);
	}
}
Exemplo n.º 4
0
/**
 * qla4xxx_mailbox_command - issues mailbox commands
 * @ha: Pointer to host adapter structure.
 * @inCount: number of mailbox registers to load.
 * @outCount: number of mailbox registers to return.
 * @mbx_cmd: data pointer for mailbox in registers.
 * @mbx_sts: data pointer for mailbox out registers.
 *
 * This routine isssue mailbox commands and waits for completion.
 * If outCount is 0, this routine completes successfully WITHOUT waiting
 * for the mailbox command to complete.
 **/
int qla4xxx_mailbox_command(struct scsi_qla_host *ha, uint8_t inCount,
			    uint8_t outCount, uint32_t *mbx_cmd,
			    uint32_t *mbx_sts)
{
	int status = QLA_ERROR;
	uint8_t i;
	u_long wait_count;
	uint32_t intr_status;
	unsigned long flags = 0;

	/* Make sure that pointers are valid */
	if (!mbx_cmd || !mbx_sts) {
		DEBUG2(printk("scsi%ld: %s: Invalid mbx_cmd or mbx_sts "
			      "pointer\n", ha->host_no, __func__));
		return status;
	}

	if (is_qla8022(ha) &&
	    test_bit(AF_FW_RECOVERY, &ha->flags)) {
		DEBUG2(ql4_printk(KERN_WARNING, ha, "scsi%ld: %s: prematurely "
		    "completing mbx cmd as firmware recovery detected\n",
		    ha->host_no, __func__));
		return status;
	}

	if ((is_aer_supported(ha)) &&
	    (test_bit(AF_PCI_CHANNEL_IO_PERM_FAILURE, &ha->flags))) {
		DEBUG2(printk(KERN_WARNING "scsi%ld: %s: Perm failure on EEH, "
		    "timeout MBX Exiting.\n", ha->host_no, __func__));
		return status;
	}

	/* Mailbox code active */
	wait_count = MBOX_TOV * 100;

	while (wait_count--) {
		mutex_lock(&ha->mbox_sem);
		if (!test_bit(AF_MBOX_COMMAND, &ha->flags)) {
			set_bit(AF_MBOX_COMMAND, &ha->flags);
			mutex_unlock(&ha->mbox_sem);
			break;
		}
		mutex_unlock(&ha->mbox_sem);
		if (!wait_count) {
			DEBUG2(printk("scsi%ld: %s: mbox_sem failed\n",
				ha->host_no, __func__));
			return status;
		}
		msleep(10);
	}

	/* To prevent overwriting mailbox registers for a command that has
	 * not yet been serviced, check to see if an active command
	 * (AEN, IOCB, etc.) is interrupting, then service it.
	 * -----------------------------------------------------------------
	 */
	spin_lock_irqsave(&ha->hardware_lock, flags);

	if (is_qla8022(ha)) {
		intr_status = readl(&ha->qla4_8xxx_reg->host_int);
		if (intr_status & ISRX_82XX_RISC_INT) {
			/* Service existing interrupt */
			DEBUG2(printk("scsi%ld: %s: "
			    "servicing existing interrupt\n",
			    ha->host_no, __func__));
			intr_status = readl(&ha->qla4_8xxx_reg->host_status);
			ha->isp_ops->interrupt_service_routine(ha, intr_status);
			clear_bit(AF_MBOX_COMMAND_DONE, &ha->flags);
			if (test_bit(AF_INTERRUPTS_ON, &ha->flags) &&
			    test_bit(AF_INTx_ENABLED, &ha->flags))
				qla4_8xxx_wr_32(ha,
				    ha->nx_legacy_intr.tgt_mask_reg,
				    0xfbff);
		}
	} else {
		intr_status = readl(&ha->reg->ctrl_status);
		if (intr_status & CSR_SCSI_PROCESSOR_INTR) {
			/* Service existing interrupt */
			ha->isp_ops->interrupt_service_routine(ha, intr_status);
			clear_bit(AF_MBOX_COMMAND_DONE, &ha->flags);
		}
	}

	ha->mbox_status_count = outCount;
	for (i = 0; i < outCount; i++)
		ha->mbox_status[i] = 0;

	if (is_qla8022(ha)) {
		/* Load all mailbox registers, except mailbox 0. */
		DEBUG5(
		    printk("scsi%ld: %s: Cmd ", ha->host_no, __func__);
		    for (i = 0; i < inCount; i++)
			printk("mb%d=%04x ", i, mbx_cmd[i]);
		    printk("\n"));

		for (i = 1; i < inCount; i++)
			writel(mbx_cmd[i], &ha->qla4_8xxx_reg->mailbox_in[i]);
		writel(mbx_cmd[0], &ha->qla4_8xxx_reg->mailbox_in[0]);
		readl(&ha->qla4_8xxx_reg->mailbox_in[0]);
		writel(HINT_MBX_INT_PENDING, &ha->qla4_8xxx_reg->hint);
	} else {
		/* Load all mailbox registers, except mailbox 0. */
		for (i = 1; i < inCount; i++)
Exemplo n.º 5
0
/**
 * qla4xxx_mailbox_command - issues mailbox commands
 * @ha: Pointer to host adapter structure.
 * @inCount: number of mailbox registers to load.
 * @outCount: number of mailbox registers to return.
 * @mbx_cmd: data pointer for mailbox in registers.
 * @mbx_sts: data pointer for mailbox out registers.
 *
 * This routine issue mailbox commands and waits for completion.
 * If outCount is 0, this routine completes successfully WITHOUT waiting
 * for the mailbox command to complete.
 **/
int qla4xxx_mailbox_command(struct scsi_qla_host *ha, uint8_t inCount,
                            uint8_t outCount, uint32_t *mbx_cmd,
                            uint32_t *mbx_sts)
{
    int status = QLA_ERROR;
    uint8_t i;
    u_long wait_count;
    uint32_t intr_status;
    unsigned long flags = 0;
    uint32_t dev_state;

    /* Make sure that pointers are valid */
    if (!mbx_cmd || !mbx_sts) {
        DEBUG2(printk("scsi%ld: %s: Invalid mbx_cmd or mbx_sts "
                      "pointer\n", ha->host_no, __func__));
        return status;
    }

    if (is_qla8022(ha)) {
        if (test_bit(AF_FW_RECOVERY, &ha->flags)) {
            DEBUG2(ql4_printk(KERN_WARNING, ha, "scsi%ld: %s: "
                              "prematurely completing mbx cmd as firmware "
                              "recovery detected\n", ha->host_no, __func__));
            return status;
        }
        /* Do not send any mbx cmd if h/w is in failed state*/
        qla4_8xxx_idc_lock(ha);
        dev_state = qla4_8xxx_rd_32(ha, QLA82XX_CRB_DEV_STATE);
        qla4_8xxx_idc_unlock(ha);
        if (dev_state == QLA82XX_DEV_FAILED) {
            ql4_printk(KERN_WARNING, ha, "scsi%ld: %s: H/W is in "
                       "failed state, do not send any mailbox commands\n",
                       ha->host_no, __func__);
            return status;
        }
    }

    if ((is_aer_supported(ha)) &&
            (test_bit(AF_PCI_CHANNEL_IO_PERM_FAILURE, &ha->flags))) {
        DEBUG2(printk(KERN_WARNING "scsi%ld: %s: Perm failure on EEH, "
                      "timeout MBX Exiting.\n", ha->host_no, __func__));
        return status;
    }

    /* Mailbox code active */
    wait_count = MBOX_TOV * 100;

    while (wait_count--) {
        mutex_lock(&ha->mbox_sem);
        if (!test_bit(AF_MBOX_COMMAND, &ha->flags)) {
            set_bit(AF_MBOX_COMMAND, &ha->flags);
            mutex_unlock(&ha->mbox_sem);
            break;
        }
        mutex_unlock(&ha->mbox_sem);
        if (!wait_count) {
            DEBUG2(printk("scsi%ld: %s: mbox_sem failed\n",
                          ha->host_no, __func__));
            return status;
        }
        msleep(10);
    }

    spin_lock_irqsave(&ha->hardware_lock, flags);

    ha->mbox_status_count = outCount;
    for (i = 0; i < outCount; i++)
        ha->mbox_status[i] = 0;

    if (is_qla8022(ha)) {
        /* Load all mailbox registers, except mailbox 0. */
        DEBUG5(
            printk("scsi%ld: %s: Cmd ", ha->host_no, __func__);
            for (i = 0; i < inCount; i++)
            printk("mb%d=%04x ", i, mbx_cmd[i]);
            printk("\n"));

        for (i = 1; i < inCount; i++)
            writel(mbx_cmd[i], &ha->qla4_8xxx_reg->mailbox_in[i]);
        writel(mbx_cmd[0], &ha->qla4_8xxx_reg->mailbox_in[0]);
        readl(&ha->qla4_8xxx_reg->mailbox_in[0]);
        writel(HINT_MBX_INT_PENDING, &ha->qla4_8xxx_reg->hint);
    } else {
        /* Load all mailbox registers, except mailbox 0. */
        for (i = 1; i < inCount; i++)