示例#1
0
/* Reset adapter's CPU. */
static int reset_cyc2x(void __iomem *addr)
{
	writeb(0, addr + RST_ENABLE);
	delay_cycx(2);
	writeb(0, addr + RST_DISABLE);
	delay_cycx(2);

	return memory_exists(addr);
}
示例#2
0
/* Reset adapter's CPU. */
static int reset_cyc2x(u32 addr)
{
	cyc2x_writeb(0, addr + RST_ENABLE);
	delay_cycx(2);
	cyc2x_writeb(0, addr + RST_DISABLE);
	delay_cycx(2);

	return memory_exists(addr);
}
示例#3
0
/* Load and boot reset code. */
static void cycx_reset_boot(void __iomem *addr, u8 *code, u32 len)
{
	void __iomem *pt_start = addr + START_OFFSET;

	writeb(0xea, pt_start++); /* jmp to f000:3f00 */
	writeb(0x00, pt_start++);
	writeb(0xfc, pt_start++);
	writeb(0x00, pt_start++);
	writeb(0xf0, pt_start);
	reset_load(addr, code, len);

	/* 80186 was in hold, go */
	writeb(0, addr + START_CPU);
	delay_cycx(1);
}
示例#4
0
/* Reset board hardware.
   return 1 if memory exists at addr and 0 if not. */
static int memory_exists(void __iomem *addr)
{
	int tries = 0;

	for (; tries < 3 ; tries++) {
		writew(TEST_PATTERN, addr + 0x10);

		if (readw(addr + 0x10) == TEST_PATTERN)
			if (readw(addr + 0x10) == TEST_PATTERN)
				return 1;

		delay_cycx(1);
	}

	return 0;
}
示例#5
0
/* Reset board hardware.
   return 1 if memory exists at addr and 0 if not. */
static int memory_exists(u32 addr)
{
	int tries = 0;

	for (; tries < 3 ; tries++) {
		cyc2x_writew(TEST_PATTERN, addr + 0x10);

		if (cyc2x_readw(addr + 0x10) == TEST_PATTERN)
			if (cyc2x_readw(addr + 0x10) == TEST_PATTERN)
				return 1;

		delay_cycx(1);
	}

	return 0;
}
示例#6
0
/* Load adapter from the memory image of the CYCX firmware module.
 * o verify firmware integrity and compatibility
 * o start adapter up */
static int load_cyc2x(struct cycx_hw *hw, struct cycx_firmware *cfm, u32 len)
{
	int i, j;
	struct cycx_fw_header *img_hdr;
	u8 *reset_image,
	   *data_image,
	   *code_image;
	void __iomem *pt_cycld = hw->dpmbase + 0x400;
	u16 cksum;

	/* Announce */
	printk(KERN_INFO "%s: firmware signature=\"%s\"\n", modname,
							    cfm->signature);

	/* Verify firmware signature */
	if (strcmp(cfm->signature, CFM_SIGNATURE)) {
		printk(KERN_ERR "%s:load_cyc2x: not Cyclom-2X firmware!\n",
				modname);
		return -EINVAL;
	}

	printk(KERN_INFO "%s: firmware version=%u\n", modname, cfm->version);

	/* Verify firmware module format version */
	if (cfm->version != CFM_VERSION) {
		printk(KERN_ERR "%s:%s: firmware format %u rejected! "
				"Expecting %u.\n",
				modname, __FUNCTION__, cfm->version, CFM_VERSION);
		return -EINVAL;
	}

	/* Verify firmware module length and checksum */
	cksum = checksum((u8*)&cfm->info, sizeof(struct cycx_fw_info) +
					  cfm->info.codesize);
/*
	FIXME cfm->info.codesize is off by 2
	if (((len - sizeof(struct cycx_firmware) - 1) != cfm->info.codesize) ||
*/
	if (cksum != cfm->checksum) {
		printk(KERN_ERR "%s:%s: firmware corrupted!\n",
				modname, __FUNCTION__);
		printk(KERN_ERR " cdsize = 0x%x (expected 0x%lx)\n",
				len - (int)sizeof(struct cycx_firmware) - 1,
				cfm->info.codesize);
		printk(KERN_ERR " chksum = 0x%x (expected 0x%x)\n",
				cksum, cfm->checksum);
		return -EINVAL;
	}

	/* If everything is ok, set reset, data and code pointers */
	img_hdr = (struct cycx_fw_header *)&cfm->image;
#ifdef FIRMWARE_DEBUG
	printk(KERN_INFO "%s:%s: image sizes\n", __FUNCTION__, modname);
	printk(KERN_INFO " reset=%lu\n", img_hdr->reset_size);
	printk(KERN_INFO "  data=%lu\n", img_hdr->data_size);
	printk(KERN_INFO "  code=%lu\n", img_hdr->code_size);
#endif
	reset_image = ((u8 *)img_hdr) + sizeof(struct cycx_fw_header);
	data_image = reset_image + img_hdr->reset_size;
	code_image = data_image + img_hdr->data_size;

	/*---- Start load ----*/
	/* Announce */
	printk(KERN_INFO "%s: loading firmware %s (ID=%u)...\n", modname,
			 cfm->descr[0] ? cfm->descr : "unknown firmware",
			 cfm->info.codeid);

	for (i = 0 ; i < 5 ; i++) {
		/* Reset Cyclom hardware */
		if (!reset_cyc2x(hw->dpmbase)) {
			printk(KERN_ERR "%s: dpm problem or board not found\n",
					modname);
			return -EINVAL;
		}

		/* Load reset.bin */
		cycx_reset_boot(hw->dpmbase, reset_image, img_hdr->reset_size);
		/* reset is waiting for boot */
		writew(GEN_POWER_ON, pt_cycld);
		delay_cycx(1);

		for (j = 0 ; j < 3 ; j++)
			if (!readw(pt_cycld))
				goto reset_loaded;
			else
				delay_cycx(1);
	}

	printk(KERN_ERR "%s: reset not started.\n", modname);
	return -EINVAL;

reset_loaded:
	/* Load data.bin */
	if (cycx_data_boot(hw->dpmbase, data_image, img_hdr->data_size)) {
		printk(KERN_ERR "%s: cannot load data file.\n", modname);
		return -EINVAL;
	}

	/* Load code.bin */
	if (cycx_code_boot(hw->dpmbase, code_image, img_hdr->code_size)) {
		printk(KERN_ERR "%s: cannot load code file.\n", modname);
		return -EINVAL;
	}

	/* Prepare boot-time configuration data */
	cycx_bootcfg(hw);

	/* kick-off CPU */
	cycx_start(hw->dpmbase);

	/* Arthur Ganzert's tip: wait a while after the firmware loading...
	   seg abr 26 17:17:12 EST 1999 - acme */
	delay_cycx(7);
	printk(KERN_INFO "%s: firmware loaded!\n", modname);

	/* enable interrupts */
	cycx_inten(hw);

	return 0;
}