qla_sup.c

来自「linux2.6.16版本」· C语言 代码 · 共 1,661 行 · 第 1/3 页

C
1,661
字号
				    (fdata & 0xff00) |((fdata << 16) &				    0xff0000) | ((fdata >> 16) & 0xff));				if (ret != QLA_SUCCESS) {					DEBUG9(printk("%s(%ld) Unable to flash "					    "sector: address=%x.\n", __func__,					    ha->host_no, faddr));					break;				}			}			ret = qla24xx_write_flash_dword(ha,			    flash_data_to_access_addr(faddr),			    cpu_to_le32(*dwptr));			if (ret != QLA_SUCCESS) {				DEBUG9(printk("%s(%ld) Unable to program flash "				    "address=%x data=%x.\n", __func__,				    ha->host_no, faddr, *dwptr));				break;			}		}	} while (0);	/* Enable flash write-protection. */	qla24xx_write_flash_dword(ha, flash_conf_to_access_addr(0x101), 0x9c);	/* Disable flash write. */	WRT_REG_DWORD(&reg->ctrl_status,	    RD_REG_DWORD(&reg->ctrl_status) & ~CSRX_FLASH_ENABLE);	RD_REG_DWORD(&reg->ctrl_status);	/* PCI Posting. */	return ret;}uint8_t *qla2x00_read_nvram_data(scsi_qla_host_t *ha, uint8_t *buf, uint32_t naddr,    uint32_t bytes){	uint32_t i;	uint16_t *wptr;	/* Word reads to NVRAM via registers. */	wptr = (uint16_t *)buf;	qla2x00_lock_nvram_access(ha);	for (i = 0; i < bytes >> 1; i++, naddr++)		wptr[i] = cpu_to_le16(qla2x00_get_nvram_word(ha,		    naddr));	qla2x00_unlock_nvram_access(ha);	return buf;}uint8_t *qla24xx_read_nvram_data(scsi_qla_host_t *ha, uint8_t *buf, uint32_t naddr,    uint32_t bytes){	uint32_t i;	uint32_t *dwptr;	/* Dword reads to flash. */	dwptr = (uint32_t *)buf;	for (i = 0; i < bytes >> 2; i++, naddr++)		dwptr[i] = cpu_to_le32(qla24xx_read_flash_dword(ha,		    nvram_data_to_access_addr(naddr)));	return buf;}intqla2x00_write_nvram_data(scsi_qla_host_t *ha, uint8_t *buf, uint32_t naddr,    uint32_t bytes){	int ret, stat;	uint32_t i;	uint16_t *wptr;	ret = QLA_SUCCESS;	qla2x00_lock_nvram_access(ha);	/* Disable NVRAM write-protection. */	stat = qla2x00_clear_nvram_protection(ha);	wptr = (uint16_t *)buf;	for (i = 0; i < bytes >> 1; i++, naddr++) {		qla2x00_write_nvram_word(ha, naddr,		    cpu_to_le16(*wptr));		wptr++;	}	/* Enable NVRAM write-protection. */	qla2x00_set_nvram_protection(ha, stat);	qla2x00_unlock_nvram_access(ha);	return ret;}intqla24xx_write_nvram_data(scsi_qla_host_t *ha, uint8_t *buf, uint32_t naddr,    uint32_t bytes){	int ret;	uint32_t i;	uint32_t *dwptr;	struct device_reg_24xx __iomem *reg = &ha->iobase->isp24;	ret = QLA_SUCCESS;	/* Enable flash write. */	WRT_REG_DWORD(&reg->ctrl_status,	    RD_REG_DWORD(&reg->ctrl_status) | CSRX_FLASH_ENABLE);	RD_REG_DWORD(&reg->ctrl_status);	/* PCI Posting. */	/* Disable NVRAM write-protection. */	qla24xx_write_flash_dword(ha, nvram_conf_to_access_addr(0x101),	    0);	qla24xx_write_flash_dword(ha, nvram_conf_to_access_addr(0x101),	    0);	/* Dword writes to flash. */	dwptr = (uint32_t *)buf;	for (i = 0; i < bytes >> 2; i++, naddr++, dwptr++) {		ret = qla24xx_write_flash_dword(ha,		    nvram_data_to_access_addr(naddr),		    cpu_to_le32(*dwptr));		if (ret != QLA_SUCCESS) {			DEBUG9(printk("%s(%ld) Unable to program "			    "nvram address=%x data=%x.\n", __func__,			    ha->host_no, naddr, *dwptr));			break;		}	}	/* Enable NVRAM write-protection. */	qla24xx_write_flash_dword(ha, nvram_conf_to_access_addr(0x101),	    0x8c);	/* Disable flash write. */	WRT_REG_DWORD(&reg->ctrl_status,	    RD_REG_DWORD(&reg->ctrl_status) & ~CSRX_FLASH_ENABLE);	RD_REG_DWORD(&reg->ctrl_status);	/* PCI Posting. */	return ret;}static inline voidqla2x00_flip_colors(scsi_qla_host_t *ha, uint16_t *pflags){	if (IS_QLA2322(ha)) {		/* Flip all colors. */		if (ha->beacon_color_state == QLA_LED_ALL_ON) {			/* Turn off. */			ha->beacon_color_state = 0;			*pflags = GPIO_LED_ALL_OFF;		} else {			/* Turn on. */			ha->beacon_color_state = QLA_LED_ALL_ON;			*pflags = GPIO_LED_RGA_ON;		}	} else {		/* Flip green led only. */		if (ha->beacon_color_state == QLA_LED_GRN_ON) {			/* Turn off. */			ha->beacon_color_state = 0;			*pflags = GPIO_LED_GREEN_OFF_AMBER_OFF;		} else {			/* Turn on. */			ha->beacon_color_state = QLA_LED_GRN_ON;			*pflags = GPIO_LED_GREEN_ON_AMBER_OFF;		}	}}voidqla2x00_beacon_blink(struct scsi_qla_host *ha){	uint16_t gpio_enable;	uint16_t gpio_data;	uint16_t led_color = 0;	unsigned long flags;	struct device_reg_2xxx __iomem *reg = &ha->iobase->isp;	if (ha->pio_address)		reg = (struct device_reg_2xxx __iomem *)ha->pio_address;	spin_lock_irqsave(&ha->hardware_lock, flags);	/* Save the Original GPIOE. */	if (ha->pio_address) {		gpio_enable = RD_REG_WORD_PIO(&reg->gpioe);		gpio_data = RD_REG_WORD_PIO(&reg->gpiod);	} else {		gpio_enable = RD_REG_WORD(&reg->gpioe);		gpio_data = RD_REG_WORD(&reg->gpiod);	}	/* Set the modified gpio_enable values */	gpio_enable |= GPIO_LED_MASK;	if (ha->pio_address) {		WRT_REG_WORD_PIO(&reg->gpioe, gpio_enable);	} else {		WRT_REG_WORD(&reg->gpioe, gpio_enable);		RD_REG_WORD(&reg->gpioe);	}	qla2x00_flip_colors(ha, &led_color);	/* Clear out any previously set LED color. */	gpio_data &= ~GPIO_LED_MASK;	/* Set the new input LED color to GPIOD. */	gpio_data |= led_color;	/* Set the modified gpio_data values */	if (ha->pio_address) {		WRT_REG_WORD_PIO(&reg->gpiod, gpio_data);	} else {		WRT_REG_WORD(&reg->gpiod, gpio_data);		RD_REG_WORD(&reg->gpiod);	}	spin_unlock_irqrestore(&ha->hardware_lock, flags);}intqla2x00_beacon_on(struct scsi_qla_host *ha){	uint16_t gpio_enable;	uint16_t gpio_data;	unsigned long flags;	struct device_reg_2xxx __iomem *reg = &ha->iobase->isp;	ha->fw_options[1] &= ~FO1_SET_EMPHASIS_SWING;	ha->fw_options[1] |= FO1_DISABLE_GPIO6_7;	if (qla2x00_set_fw_options(ha, ha->fw_options) != QLA_SUCCESS) {		qla_printk(KERN_WARNING, ha,		    "Unable to update fw options (beacon on).\n");		return QLA_FUNCTION_FAILED;	}	if (ha->pio_address)		reg = (struct device_reg_2xxx __iomem *)ha->pio_address;	/* Turn off LEDs. */	spin_lock_irqsave(&ha->hardware_lock, flags);	if (ha->pio_address) {		gpio_enable = RD_REG_WORD_PIO(&reg->gpioe);		gpio_data = RD_REG_WORD_PIO(&reg->gpiod);	} else {		gpio_enable = RD_REG_WORD(&reg->gpioe);		gpio_data = RD_REG_WORD(&reg->gpiod);	}	gpio_enable |= GPIO_LED_MASK;	/* Set the modified gpio_enable values. */	if (ha->pio_address) {		WRT_REG_WORD_PIO(&reg->gpioe, gpio_enable);	} else {		WRT_REG_WORD(&reg->gpioe, gpio_enable);		RD_REG_WORD(&reg->gpioe);	}	/* Clear out previously set LED colour. */	gpio_data &= ~GPIO_LED_MASK;	if (ha->pio_address) {		WRT_REG_WORD_PIO(&reg->gpiod, gpio_data);	} else {		WRT_REG_WORD(&reg->gpiod, gpio_data);		RD_REG_WORD(&reg->gpiod);	}	spin_unlock_irqrestore(&ha->hardware_lock, flags);	/*	 * Let the per HBA timer kick off the blinking process based on	 * the following flags. No need to do anything else now.	 */	ha->beacon_blink_led = 1;	ha->beacon_color_state = 0;	return QLA_SUCCESS;}intqla2x00_beacon_off(struct scsi_qla_host *ha){	int rval = QLA_SUCCESS;	ha->beacon_blink_led = 0;	/* Set the on flag so when it gets flipped it will be off. */	if (IS_QLA2322(ha))		ha->beacon_color_state = QLA_LED_ALL_ON;	else		ha->beacon_color_state = QLA_LED_GRN_ON;	ha->isp_ops.beacon_blink(ha);	/* This turns green LED off */	ha->fw_options[1] &= ~FO1_SET_EMPHASIS_SWING;	ha->fw_options[1] &= ~FO1_DISABLE_GPIO6_7;	rval = qla2x00_set_fw_options(ha, ha->fw_options);	if (rval != QLA_SUCCESS)		qla_printk(KERN_WARNING, ha,		    "Unable to update fw options (beacon off).\n");	return rval;}static inline voidqla24xx_flip_colors(scsi_qla_host_t *ha, uint16_t *pflags){	/* Flip all colors. */	if (ha->beacon_color_state == QLA_LED_ALL_ON) {		/* Turn off. */		ha->beacon_color_state = 0;		*pflags = 0;	} else {		/* Turn on. */		ha->beacon_color_state = QLA_LED_ALL_ON;		*pflags = GPDX_LED_YELLOW_ON | GPDX_LED_AMBER_ON;	}}voidqla24xx_beacon_blink(struct scsi_qla_host *ha){	uint16_t led_color = 0;	uint32_t gpio_data;	unsigned long flags;	struct device_reg_24xx __iomem *reg = &ha->iobase->isp24;	/* Save the Original GPIOD. */	spin_lock_irqsave(&ha->hardware_lock, flags);	gpio_data = RD_REG_DWORD(&reg->gpiod);	/* Enable the gpio_data reg for update. */	gpio_data |= GPDX_LED_UPDATE_MASK;	WRT_REG_DWORD(&reg->gpiod, gpio_data);	gpio_data = RD_REG_DWORD(&reg->gpiod);	/* Set the color bits. */	qla24xx_flip_colors(ha, &led_color);	/* Clear out any previously set LED color. */	gpio_data &= ~GPDX_LED_COLOR_MASK;	/* Set the new input LED color to GPIOD. */	gpio_data |= led_color;	/* Set the modified gpio_data values. */	WRT_REG_DWORD(&reg->gpiod, gpio_data);	gpio_data = RD_REG_DWORD(&reg->gpiod);	spin_unlock_irqrestore(&ha->hardware_lock, flags);}intqla24xx_beacon_on(struct scsi_qla_host *ha){	uint32_t gpio_data;	unsigned long flags;	struct device_reg_24xx __iomem *reg = &ha->iobase->isp24;	if (ha->beacon_blink_led == 0) {		/* Enable firmware for update */		ha->fw_options[1] |= ADD_FO1_DISABLE_GPIO_LED_CTRL;		if (qla2x00_set_fw_options(ha, ha->fw_options) != QLA_SUCCESS)			return QLA_FUNCTION_FAILED;		if (qla2x00_get_fw_options(ha, ha->fw_options) !=		    QLA_SUCCESS) {			qla_printk(KERN_WARNING, ha,			    "Unable to update fw options (beacon on).\n");			return QLA_FUNCTION_FAILED;		}		spin_lock_irqsave(&ha->hardware_lock, flags);		gpio_data = RD_REG_DWORD(&reg->gpiod);		/* Enable the gpio_data reg for update. */		gpio_data |= GPDX_LED_UPDATE_MASK;		WRT_REG_DWORD(&reg->gpiod, gpio_data);		RD_REG_DWORD(&reg->gpiod);		spin_unlock_irqrestore(&ha->hardware_lock, flags);	}	/* So all colors blink together. */	ha->beacon_color_state = 0;	/* Let the per HBA timer kick off the blinking process. */	ha->beacon_blink_led = 1;	return QLA_SUCCESS;}intqla24xx_beacon_off(struct scsi_qla_host *ha){	uint32_t gpio_data;	unsigned long flags;	struct device_reg_24xx __iomem *reg = &ha->iobase->isp24;	ha->beacon_blink_led = 0;	ha->beacon_color_state = QLA_LED_ALL_ON;	ha->isp_ops.beacon_blink(ha);	/* Will flip to all off. */	/* Give control back to firmware. */	spin_lock_irqsave(&ha->hardware_lock, flags);	gpio_data = RD_REG_DWORD(&reg->gpiod);	/* Disable the gpio_data reg for update. */	gpio_data &= ~GPDX_LED_UPDATE_MASK;	WRT_REG_DWORD(&reg->gpiod, gpio_data);	RD_REG_DWORD(&reg->gpiod);	spin_unlock_irqrestore(&ha->hardware_lock, flags);	ha->fw_options[1] &= ~ADD_FO1_DISABLE_GPIO_LED_CTRL;	if (qla2x00_set_fw_options(ha, ha->fw_options) != QLA_SUCCESS) {		qla_printk(KERN_WARNING, ha,		    "Unable to update fw options (beacon off).\n");		return QLA_FUNCTION_FAILED;	}	if (qla2x00_get_fw_options(ha, ha->fw_options) != QLA_SUCCESS) {		qla_printk(KERN_WARNING, ha,		    "Unable to get fw options (beacon off).\n");		return QLA_FUNCTION_FAILED;	}	return QLA_SUCCESS;}/* * Flash support routines *//** * qla2x00_flash_enable() - Setup flash for reading and writing. * @ha: HA context */static voidqla2x00_flash_enable(scsi_qla_host_t *ha){	uint16_t data;	struct device_reg_2xxx __iomem *reg = &ha->iobase->isp;	data = RD_REG_WORD(&reg->ctrl_status);	data |= CSR_FLASH_ENABLE;	WRT_REG_WORD(&reg->ctrl_status, data);	RD_REG_WORD(&reg->ctrl_status);		/* PCI Posting. */}/** * qla2x00_flash_disable() - Disable flash and allow RISC to run. * @ha: HA context */static voidqla2x00_flash_disable(scsi_qla_host_t *ha){	uint16_t data;	struct device_reg_2xxx __iomem *reg = &ha->iobase->isp;	data = RD_REG_WORD(&reg->ctrl_status);	data &= ~(CSR_FLASH_ENABLE);	WRT_REG_WORD(&reg->ctrl_status, data);	RD_REG_WORD(&reg->ctrl_status);		/* PCI Posting. */}/** * qla2x00_read_flash_byte() - Reads a byte from flash * @ha: HA context * @addr: Address in flash to read * * A word is read from the chip, but, only the lower byte is valid. * * Returns the byte read from flash @addr. */static uint8_tqla2x00_read_flash_byte(scsi_qla_host_t *ha, uint32_t addr){	uint16_t data;	uint16_t bank_select;	struct device_reg_2xxx __iomem *reg = &ha->iobase->isp;	bank_select = RD_REG_WORD(&reg->ctrl_status);	if (IS_QLA2322(ha) || IS_QLA6322(ha)) {		/* Specify 64K address range: */		/*  clear out Module Select and Flash Address bits [19:16]. */		bank_select &= ~0xf8;		bank_select |= addr >> 12 & 0xf0;		bank_select |= CSR_FLASH_64K_BANK;		WRT_REG_WORD(&reg->ctrl_status, bank_select);		RD_REG_WORD(&reg->ctrl_status);	/* PCI Posting. */		WRT_REG_WORD(&reg->flash_address, (uint16_t)addr);		data = RD_REG_WORD(&reg->flash_data);		return (uint8_t)data;	}	/* Setup bit 16 of flash address. */	if ((addr & BIT_16) && ((bank_select & CSR_FLASH_64K_BANK) == 0)) {		bank_select |= CSR_FLASH_64K_BANK;		WRT_REG_WORD(&reg->ctrl_status, bank_select);		RD_REG_WORD(&reg->ctrl_status);	/* PCI Posting. */	} else if (((addr & BIT_16) == 0) &&	    (bank_select & CSR_FLASH_64K_BANK)) {		bank_select &= ~(CSR_FLASH_64K_BANK);		WRT_REG_WORD(&reg->ctrl_status, bank_select);		RD_REG_WORD(&reg->ctrl_status);	/* PCI Posting. */	}	/* Always perform IO mapped accesses to the FLASH registers. */	if (ha->pio_address) {		uint16_t data2;		reg = (struct device_reg_2xxx __iomem *)ha->pio_address;		WRT_REG_WORD_PIO(&reg->flash_address, (uint16_t)addr);		do {			data = RD_REG_WORD_PIO(&reg->flash_data);			barrier();			cpu_relax();			data2 = RD_REG_WORD_PIO(&reg->flash_data);		} while (data != data2);	} else {		WRT_REG_WORD(&reg->flash_address, (uint16_t)addr);		data = qla2x00_debounce_register(&reg->flash_data);	}	return (uint8_t)data;}/** * qla2x00_write_flash_byte() - Write a byte to flash * @ha: HA context * @addr: Address in flash to write * @data: Data to write */static voidqla2x00_write_flash_byte(scsi_qla_host_t *ha, uint32_t addr, uint8_t data){	uint16_t bank_select;	struct device_reg_2xxx __iomem *reg = &ha->iobase->isp;	bank_select = RD_REG_WORD(&reg->ctrl_status);	if (IS_QLA2322(ha) || IS_QLA6322(ha)) {

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?