Example #1
0
static void firmware_cleanup(struct sec_firmware *fw)
{
	free_firmware(&fw->pa_bin);
	free_firmware(&fw->pafmt_bin);
	free_firmware(&fw->papub_bin);
	kfree(fw->format.cmd);
	memset(fw, 0, sizeof(*fw));
}
Example #2
0
static int read_firmware(unsigned char* data, off_t size, struct firmware** f_res) {
	char *name = malloc(33);
	unsigned char *p = data;
	struct firmware* f = alloc_firmware();
	unsigned int i;

	if(size < HEADER_LENGTH) {
		printf("Invalid firmware header length.\n");
		free_firmware(f);
		return -1;
	}
	name[32] = 0;
	memcpy(name, data, 32);
	f->name = name;
	p += 32;
	f->version = __le16_to_cpu(*(__u16*)p);
	p += sizeof(f->version);
	f->nr_desc = __le16_to_cpu(*(__u16*)p);
	p += sizeof(f->nr_desc);
	f->desc = malloc(f->nr_desc * sizeof(*(f->desc)));

	for(i = 0; i < f->nr_desc; ++i) {
		if(p + DESC_HEADER_LENGTH > data + size) {
			printf("Invalid description header length.\n");
			free_firmware(f);
			return -1;
		}
		f->desc[i].type = __le32_to_cpu(*(__u32*) p);
		p += sizeof(f->desc[i].type);
		f->desc[i].id = __le64_to_cpu(*(__u64*) p);
		p += sizeof(f->desc[i].id);

		if (f->desc[i].type & HAS_IF) {
			f->desc[i].int_freq = __le16_to_cpu(*(__u16 *) p);
			p += sizeof(f->desc[i].int_freq);
		}

		f->desc[i].size = __le32_to_cpu(*(__u32*) p);
		p += sizeof(f->desc[i].size);

		if(p + f->desc[i].size > data + size) {
			printf("Invalid firmware standard length.\n");
			f->nr_desc = (f->nr_desc == 0) ? 0 : f->nr_desc -1;
			free_firmware(f);
			return -1;
		}

		f->desc[i].data = malloc(f->desc[i].size);
		memcpy(f->desc[i].data, p, f->desc[i].size);

		p += f->desc[i].size;
	}

	*f_res = f;
	return 0;
}
Example #3
0
/* This returns path of the firmware blob on the disk */
static int download_firmware(struct gb_bootrom *bootrom, u8 stage)
{
	struct gb_connection *connection = bootrom->connection;
	struct gb_interface *intf = connection->bundle->intf;
	char firmware_name[48];
	int rc;

	/* Already have a firmware, free it */
	free_firmware(bootrom);

	/*
	 * Create firmware name
	 *
	 * XXX Name it properly..
	 */
	snprintf(firmware_name, sizeof(firmware_name),
		 "ara_%08x_%08x_%08x_%08x_%02x.tftf",
		 intf->ddbl1_manufacturer_id, intf->ddbl1_product_id,
		 intf->vendor_id, intf->product_id, stage);

	// FIXME:
	// Turn to dev_dbg later after everyone has valid bootloaders with good
	// ids, but leave this as dev_info for now to make it easier to track
	// down "empty" vid/pid modules.
	dev_info(&connection->bundle->dev, "Firmware file '%s' requested\n",
		 firmware_name);

	rc = request_firmware(&bootrom->fw, firmware_name,
		&connection->bundle->dev);
	if (rc)
		dev_err(&connection->bundle->dev,
			"Firmware request for %s has failed : %d",
			firmware_name, rc);
	return rc;
}
static int load_firmware(struct echoaudio *chip)
{
	const struct firmware *fw;
	int box_type, err;

	if (snd_BUG_ON(!chip->comm_page))
		return -EPERM;

	/*                                                                            */
	if (chip->dsp_code) {
		if ((box_type = check_asic_status(chip)) >= 0)
			return box_type;
		/*                                            */
		chip->dsp_code = NULL;
	}

	err = get_firmware(&fw, chip, chip->dsp_code_to_load);
	if (err < 0)
		return err;
	err = load_dsp(chip, (u16 *)fw->data);
	free_firmware(fw);
	if (err < 0)
		return err;

	if ((box_type = load_asic(chip)) < 0)
		return box_type;	/*       */

	return box_type;
}
Example #5
0
File: bootrom.c Project: mhei/linux
static void gb_bootrom_timedout(struct work_struct *work)
{
    struct delayed_work *dwork = to_delayed_work(work);
    struct gb_bootrom *bootrom = container_of(dwork, struct gb_bootrom, dwork);
    struct device *dev = &bootrom->connection->bundle->dev;
    const char *reason;

    switch (bootrom->next_request) {
    case NEXT_REQ_FIRMWARE_SIZE:
        reason = "Firmware Size Request";
        break;
    case NEXT_REQ_GET_FIRMWARE:
        reason = "Get Firmware Request";
        break;
    case NEXT_REQ_READY_TO_BOOT:
        reason = "Ready to Boot Request";
        break;
    case NEXT_REQ_MODE_SWITCH:
        reason = "Interface Mode Switch";
        break;
    default:
        reason = NULL;
        dev_err(dev, "Invalid next-request: %u", bootrom->next_request);
        break;
    }

    dev_err(dev, "Timed out waiting for %s from the Module\n", reason);

    mutex_lock(&bootrom->mutex);
    free_firmware(bootrom);
    mutex_unlock(&bootrom->mutex);

    /* TODO: Power-off Module ? */
}
Example #6
0
/* load_firmware takes care of loading the DSP and any ASIC code. */
static int load_firmware(struct echoaudio *chip)
{
	const struct firmware *fw;
	int box_type, err;

	if (snd_BUG_ON(!chip->comm_page))
		return -EPERM;

	/* See if the ASIC is present and working - only if the DSP is already loaded */
	if (chip->dsp_code) {
		if ((box_type = check_asic_status(chip)) >= 0)
			return box_type;
		/* ASIC check failed; force the DSP to reload */
		chip->dsp_code = NULL;
	}

	err = get_firmware(&fw, chip, chip->dsp_code_to_load);
	if (err < 0)
		return err;
	err = load_dsp(chip, (u16 *)fw->data);
	free_firmware(fw, chip);
	if (err < 0)
		return err;

	if ((box_type = load_asic(chip)) < 0)
		return box_type;	/* error */

	return box_type;
}
Example #7
0
static int gb_bootrom_firmware_size_request(struct gb_operation *op)
{
	struct gb_bootrom *bootrom = gb_connection_get_data(op->connection);
	struct gb_bootrom_firmware_size_request *size_request =
		op->request->payload;
	struct gb_bootrom_firmware_size_response *size_response;
	struct device *dev = &op->connection->bundle->dev;
	int ret;

	/* Disable timeouts */
	gb_bootrom_cancel_timeout(bootrom);

	if (op->request->payload_size != sizeof(*size_request)) {
		dev_err(dev, "%s: illegal size of firmware size request (%zu != %zu)\n",
			__func__, op->request->payload_size,
			sizeof(*size_request));
		ret = -EINVAL;
		goto queue_work;
	}

	mutex_lock(&bootrom->mutex);

	ret = find_firmware(bootrom, size_request->stage);
	if (ret)
		goto unlock;

	if (!gb_operation_response_alloc(op, sizeof(*size_response),
					 GFP_KERNEL)) {
		dev_err(dev, "%s: error allocating response\n", __func__);
		free_firmware(bootrom);
		ret = -ENOMEM;
		goto unlock;
	}

	size_response = op->response->payload;
	size_response->size = cpu_to_le32(bootrom->fw->size);

	dev_dbg(dev, "%s: firmware size %d bytes\n",
		__func__, size_response->size);

unlock:
	mutex_unlock(&bootrom->mutex);

queue_work:
	if (!ret) {
		/* Refresh timeout */
		gb_bootrom_set_timeout(bootrom, NEXT_REQ_GET_FIRMWARE,
				       NEXT_REQ_TIMEOUT_MS);
	}

	return ret;
}
static int load_asic_generic(struct echoaudio *chip, u32 cmd, short asic)
{
	const struct firmware *fw;
	int err;
	u32 i, size;
	u8 *code;

	err = get_firmware(&fw, chip, asic);
	if (err < 0) {
		snd_printk(KERN_WARNING "Firmware not found !\n");
		return err;
	}

	code = (u8 *)fw->data;
	size = fw->size;

	/*                                        */
	if (write_dsp(chip, cmd) < 0)
		goto la_error;

	/*                                    */
	if (write_dsp(chip, size) < 0)
		goto la_error;

	for (i = 0; i < size; i++) {
		if (write_dsp(chip, code[i]) < 0)
			goto la_error;
	}

	DE_INIT(("ASIC loaded\n"));
	free_firmware(fw);
	return 0;

la_error:
	DE_INIT(("failed on write_dsp\n"));
	free_firmware(fw);
	return -EIO;
}
Example #9
0
/* Load ASIC code - done after the DSP is loaded */
static int load_asic_generic(struct echoaudio *chip, u32 cmd,
			     const struct firmware *asic)
{
	const struct firmware *fw;
	int err;
	u32 i, size;
	u8 *code;

	if ((err = get_firmware(&fw, asic, chip)) < 0) {
		snd_printk(KERN_WARNING "Firmware not found !\n");
		return err;
	}

	code = (u8 *)fw->data;
	size = fw->size;

	/* Send the "Here comes the ASIC" command */
	if (write_dsp(chip, cmd) < 0)
		goto la_error;

	/* Write length of ASIC file in bytes */
	if (write_dsp(chip, size) < 0)
		goto la_error;

	for (i = 0; i < size; i++) {
		if (write_dsp(chip, code[i]) < 0)
			goto la_error;
	}

	DE_INIT(("ASIC loaded\n"));
	free_firmware(fw);
	return 0;

la_error:
	DE_INIT(("failed on write_dsp\n"));
	free_firmware(fw);
	return -EIO;
}
Example #10
0
static void gb_bootrom_timedout(struct work_struct *work)
{
	struct delayed_work *dwork = to_delayed_work(work);
	struct gb_bootrom *bootrom = container_of(dwork, struct gb_bootrom, dwork);
	struct device *dev = &bootrom->connection->bundle->dev;

	dev_err(dev, "Timed out waiting for request from the Module\n");

	mutex_lock(&bootrom->mutex);
	free_firmware(bootrom);
	mutex_unlock(&bootrom->mutex);

	/* TODO: Power-off Module ? */
}
Example #11
0
/* Load ASIC code - done after the DSP is loaded */
static int load_asic_generic(struct echoaudio *chip, u32 cmd, short asic)
{
	const struct firmware *fw;
	int err;
	u32 i, size;
	u8 *code;

	err = get_firmware(&fw, chip, asic);
	if (err < 0) {
		dev_warn(chip->card->dev, "Firmware not found !\n");
		return err;
	}

	code = (u8 *)fw->data;
	size = fw->size;

	/* Send the "Here comes the ASIC" command */
	if (write_dsp(chip, cmd) < 0)
		goto la_error;

	/* Write length of ASIC file in bytes */
	if (write_dsp(chip, size) < 0)
		goto la_error;

	for (i = 0; i < size; i++) {
		if (write_dsp(chip, code[i]) < 0)
			goto la_error;
	}

	free_firmware(fw, chip);
	return 0;

la_error:
	dev_err(chip->card->dev, "failed on write_dsp\n");
	free_firmware(fw, chip);
	return -EIO;
}
Example #12
0
static void gb_firmware_disconnect(struct gb_bundle *bundle)
{
	struct gb_firmware *firmware = greybus_get_drvdata(bundle);

	dev_dbg(&bundle->dev, "%s\n", __func__);

	gb_connection_disable(firmware->connection);

	/* Release firmware */
	if (firmware->fw)
		free_firmware(firmware);

	gb_connection_destroy(firmware->connection);
	kfree(firmware);
}
Example #13
0
File: bootrom.c Project: mhei/linux
/* This returns path of the firmware blob on the disk */
static int find_firmware(struct gb_bootrom *bootrom, u8 stage)
{
    struct gb_connection *connection = bootrom->connection;
    struct gb_interface *intf = connection->bundle->intf;
    char firmware_name[49];
    int rc;

    /* Already have a firmware, free it */
    free_firmware(bootrom);

    /* Bootrom protocol is only supported for loading Stage 2 firmware */
    if (stage != 2) {
        dev_err(&connection->bundle->dev, "Invalid boot stage: %u\n",
                stage);
        return -EINVAL;
    }

    /*
     * Create firmware name
     *
     * XXX Name it properly..
     */
    snprintf(firmware_name, sizeof(firmware_name),
             FW_NAME_PREFIX "%08x_%08x_%08x_%08x_s2l.tftf",
             intf->ddbl1_manufacturer_id, intf->ddbl1_product_id,
             intf->vendor_id, intf->product_id);

    // FIXME:
    // Turn to dev_dbg later after everyone has valid bootloaders with good
    // ids, but leave this as dev_info for now to make it easier to track
    // down "empty" vid/pid modules.
    dev_info(&connection->bundle->dev, "Firmware file '%s' requested\n",
             firmware_name);

    rc = request_firmware(&bootrom->fw, firmware_name,
                          &connection->bundle->dev);
    if (rc) {
        dev_err(&connection->bundle->dev,
                "failed to find %s firmware (%d)\n", firmware_name, rc);
    }

    return rc;
}
Example #14
0
File: bootrom.c Project: mhei/linux
static void gb_bootrom_disconnect(struct gb_bundle *bundle)
{
    struct gb_bootrom *bootrom = greybus_get_drvdata(bundle);

    dev_dbg(&bundle->dev, "%s\n", __func__);

    gb_connection_disable(bootrom->connection);

    /* Disable timeouts */
    gb_bootrom_cancel_timeout(bootrom);

    /*
     * Release firmware:
     *
     * As the connection and the delayed work are already disabled, we don't
     * need to lock access to bootrom->fw here.
     */
    free_firmware(bootrom);

    gb_connection_destroy(bootrom->connection);
    kfree(bootrom);
}
Example #15
0
static int gb_firmware_size_request(struct gb_operation *op)
{
	struct gb_firmware *firmware = gb_connection_get_data(op->connection);
	struct gb_firmware_size_request *size_request = op->request->payload;
	struct gb_firmware_size_response *size_response;
	struct device *dev = &op->connection->bundle->dev;
	int ret;

	if (op->request->payload_size != sizeof(*size_request)) {
		dev_err(dev, "%s: illegal size of firmware size request (%zu != %zu)\n",
			__func__, op->request->payload_size,
			sizeof(*size_request));
		return -EINVAL;
	}

	ret = download_firmware(firmware, size_request->stage);
	if (ret) {
		dev_err(dev, "%s: failed to download firmware (%d)\n", __func__,
			ret);
		return ret;
	}

	if (!gb_operation_response_alloc(op, sizeof(*size_response),
					 GFP_KERNEL)) {
		dev_err(dev, "%s: error allocating response\n", __func__);
		free_firmware(firmware);
		return -ENOMEM;
	}

	size_response = op->response->payload;
	size_response->size = cpu_to_le32(firmware->fw->size);

	dev_dbg(dev, "%s: firmware size %d bytes\n", __func__, size_response->size);

	return 0;
}
static int install_resident_loader(struct echoaudio *chip)
{
	u32 address;
	int index, words, i;
	u16 *code;
	u32 status;
	const struct firmware *fw;

	/*                                                                 
                 */
	if (chip->device_id != DEVICE_ID_56361)
		return 0;

	/*                                                                
                                                      */
	status = get_dsp_register(chip, CHI32_STATUS_REG);
	if (status & CHI32_STATUS_REG_HF5) {
		DE_INIT(("Resident loader already installed; status is 0x%x\n",
			 status));
		return 0;
	}

	i = get_firmware(&fw, chip, FW_361_LOADER);
	if (i < 0) {
		snd_printk(KERN_WARNING "Firmware not found !\n");
		return i;
	}

	/*                                                                   
                                                                     
                              
                                                                     
                           
                                                                   
                                                                     */

	/*                                     */
	set_dsp_register(chip, CHI32_CONTROL_REG,
			 get_dsp_register(chip, CHI32_CONTROL_REG) | 0x900);

	code = (u16 *)fw->data;

	/*                                                                 
                                                                   
                */
	index = code[0];

	/*                                                            */
	index += 3;

	/*                                      */
	words = code[index++];

	/*                                                                      */
	address = ((u32)code[index] << 16) + code[index + 1];
	index += 2;

	/*                            */
	if (write_dsp(chip, words)) {
		DE_INIT(("install_resident_loader: Failed to write word count!\n"));
		goto irl_error;
	}
	/*                       */
	if (write_dsp(chip, address)) {
		DE_INIT(("install_resident_loader: Failed to write DSP address!\n"));
		goto irl_error;
	}
	/*                                         */
	for (i = 0; i < words; i++) {
		u32 data;

		data = ((u32)code[index] << 16) + code[index + 1];
		if (write_dsp(chip, data)) {
			DE_INIT(("install_resident_loader: Failed to write DSP code\n"));
			goto irl_error;
		}
		index += 2;
	}

	/*                            */
	for (i = 0; i < 200; i++) {	/*                              */
		udelay(50);
		status = get_dsp_register(chip, CHI32_STATUS_REG);
		if (status & CHI32_STATUS_REG_HF5)
			break;
	}

	if (i == 200) {
		DE_INIT(("Resident loader failed to set HF5\n"));
		goto irl_error;
	}

	DE_INIT(("Resident loader successfully installed\n"));
	free_firmware(fw);
	return 0;

irl_error:
	free_firmware(fw);
	return -EIO;
}
Example #17
0
/* Install the resident loader for 56361 DSPs;  The resident loader is on
the EPROM on the board for 56301 DSP. The resident loader is a tiny little
program that is used to load the real DSP code. */
static int install_resident_loader(struct echoaudio *chip)
{
	u32 address;
	int index, words, i;
	u16 *code;
	u32 status;
	const struct firmware *fw;

	/* 56361 cards only!  This check is required by the old 56301-based
	Mona and Gina24 */
	if (chip->device_id != DEVICE_ID_56361)
		return 0;

	/* Look to see if the resident loader is present.  If the resident
	loader is already installed, host flag 5 will be on. */
	status = get_dsp_register(chip, CHI32_STATUS_REG);
	if (status & CHI32_STATUS_REG_HF5) {
		dev_dbg(chip->card->dev,
			"Resident loader already installed; status is 0x%x\n",
			 status);
		return 0;
	}

	i = get_firmware(&fw, chip, FW_361_LOADER);
	if (i < 0) {
		dev_warn(chip->card->dev, "Firmware not found !\n");
		return i;
	}

	/* The DSP code is an array of 16 bit words.  The array is divided up
	into sections.  The first word of each section is the size in words,
	followed by the section type.
	Since DSP addresses and data are 24 bits wide, they each take up two
	16 bit words in the array.
	This is a lot like the other loader loop, but it's not a loop, you
	don't write the memory type, and you don't write a zero at the end. */

	/* Set DSP format bits for 24 bit mode */
	set_dsp_register(chip, CHI32_CONTROL_REG,
			 get_dsp_register(chip, CHI32_CONTROL_REG) | 0x900);

	code = (u16 *)fw->data;

	/* Skip the header section; the first word in the array is the size
	of the first section, so the first real section of code is pointed
	to by Code[0]. */
	index = code[0];

	/* Skip the section size, LRS block type, and DSP memory type */
	index += 3;

	/* Get the number of DSP words to write */
	words = code[index++];

	/* Get the DSP address for this block; 24 bits, so build from two words */
	address = ((u32)code[index] << 16) + code[index + 1];
	index += 2;

	/* Write the count to the DSP */
	if (write_dsp(chip, words)) {
		dev_err(chip->card->dev,
			"install_resident_loader: Failed to write word count!\n");
		goto irl_error;
	}
	/* Write the DSP address */
	if (write_dsp(chip, address)) {
		dev_err(chip->card->dev,
			"install_resident_loader: Failed to write DSP address!\n");
		goto irl_error;
	}
	/* Write out this block of code to the DSP */
	for (i = 0; i < words; i++) {
		u32 data;

		data = ((u32)code[index] << 16) + code[index + 1];
		if (write_dsp(chip, data)) {
			dev_err(chip->card->dev,
				"install_resident_loader: Failed to write DSP code\n");
			goto irl_error;
		}
		index += 2;
	}

	/* Wait for flag 5 to come up */
	for (i = 0; i < 200; i++) {	/* Timeout is 50us * 200 = 10ms */
		udelay(50);
		status = get_dsp_register(chip, CHI32_STATUS_REG);
		if (status & CHI32_STATUS_REG_HF5)
			break;
	}

	if (i == 200) {
		dev_err(chip->card->dev, "Resident loader failed to set HF5\n");
		goto irl_error;
	}

	dev_dbg(chip->card->dev, "Resident loader successfully installed\n");
	free_firmware(fw, chip);
	return 0;

irl_error:
	free_firmware(fw, chip);
	return -EIO;
}