int
SlaveDevice::restore_config_rom(raw1394handle_t handle, struct SlaveDevice::configrom_backup old)
{
    int retval;
//     int i;

    quadlet_t current_rom[0x100];
    size_t current_rom_size;
    unsigned char current_rom_version;

    retval=raw1394_get_config_rom(handle, current_rom, 0x100, &current_rom_size, &current_rom_version);
//     printf("restore_config_rom get_config_rom returned %d, romsize %d, rom_version %d:\n",retval,current_rom_size,current_rom_version);

//     printf("restore_config_rom restoring to romsize %d, rom_version %d:\n",old.rom_size,old.rom_version);

    retval = raw1394_update_config_rom(handle, old.rom, old.rom_size, current_rom_version);
//     printf("restore_config_rom update_config_rom returned %d\n",retval);

    /* get the current rom image */
    retval=raw1394_get_config_rom(handle, current_rom, 0x100, &current_rom_size, &current_rom_version);
    current_rom_size = rom1394_get_size(current_rom);
//     printf("get_config_rom returned %d, romsize %d, rom_version %d:",retval,current_rom_size,current_rom_version);
//     for (i = 0; i < current_rom_size; i++)
//     {
//         if (i % 4 == 0) printf("\n0x%04x:", CSR_CONFIG_ROM+i*4);
//         printf(" %08x", CondSwapFromBus32(current_rom[i]));
//     }
//     printf("\n");

    return retval;
}
int
SlaveDevice::init_config_rom(raw1394handle_t handle)
{
    int retval, i;
    quadlet_t rom[0x100];
    size_t rom_size;
    unsigned char rom_version;
    rom1394_directory dir;
    char *leaf;

    /* get the current rom image */
    retval=raw1394_get_config_rom(handle, rom, 0x100, &rom_size, &rom_version);
    rom_size = rom1394_get_size(rom);
//     printf("get_config_rom returned %d, romsize %d, rom_version %d:",retval,rom_size,rom_version);
//     for (i = 0; i < rom_size; i++)
//     {
//         if (i % 4 == 0) printf("\n0x%04x:", CSR_CONFIG_ROM+i*4);
//         printf(" %08x", CondSwapFromBus32(rom[i]));
//     }
//     printf("\n");

    /* get the local directory */
    rom1394_get_directory( handle, raw1394_get_local_id(handle) & 0x3f, &dir);

    /* change the vendor description for kicks */
    i = strlen(dir.textual_leafs[0]);
    strncpy(dir.textual_leafs[0], FFADO_BOUNCE_SERVER_VENDORNAME "                                          ", i);

    dir.vendor_id=FFADO_BOUNCE_SERVER_VENDORID;
    dir.model_id=FFADO_BOUNCE_SERVER_MODELID;

    /* update the rom */
    retval = rom1394_set_directory(rom, &dir);
//     printf("rom1394_set_directory returned %d, romsize %d:",retval,rom_size);
//     for (i = 0; i < rom_size; i++)
//     {
//         if (i % 4 == 0) printf("\n0x%04x:", CSR_CONFIG_ROM+i*4);
//         printf(" %08x", CondSwapFromBus32(rom[i]));
//     }
//     printf("\n");

    /* free the allocated mem for the textual leaves */
    rom1394_free_directory( &dir);

    /* add an AV/C unit directory */
    dir.unit_spec_id    = FFADO_BOUNCE_SERVER_SPECID;
    dir.unit_sw_version = 0x00010001;
    leaf = (char*)FFADO_BOUNCE_SERVER_MODELNAME;
    dir.nr_textual_leafs = 1;
    dir.textual_leafs = &leaf;

    /* manipulate the rom */
    retval = rom1394_add_unit( rom, &dir);

    /* get the computed size of the rom image */
    rom_size = rom1394_get_size(rom);

//     printf("rom1394_add_unit_directory returned %d, romsize %d:",retval,rom_size);
//     for (i = 0; i < rom_size; i++)
//     {
//         if (i % 4 == 0) printf("\n0x%04x:", CSR_CONFIG_ROM+i*4);
//         printf(" %08x", CondSwapFromBus32(rom[i]));
//     }
//     printf("\n");
//
    /* convert computed rom size from quadlets to bytes before update */
    rom_size *= sizeof(quadlet_t);
    retval = raw1394_update_config_rom(handle, rom, rom_size, rom_version);
//     printf("update_config_rom returned %d\n",retval);

    retval=raw1394_get_config_rom(handle, rom, 0x100, &rom_size, &rom_version);
//     printf("get_config_rom returned %d, romsize %d, rom_version %d:",retval,rom_size,rom_version);
//     for (i = 0; i < rom_size; i++)
//     {
//         if (i % 4 == 0) printf("\n0x%04x:", CSR_CONFIG_ROM+i*4);
//         printf(" %08x", CondSwapFromBus32(rom[i]));
//     }
//     printf("\n");

//     printf("You need to reload your ieee1394 modules to reset the rom.\n");

    return 0;
}
int rom1394_add_unit(quadlet_t *buffer, rom1394_directory *dir)
{	
	int i, length;
	quadlet_t *p = buffer + ROM1394_ROOT_DIRECTORY/4;
	int	key, value;
	quadlet_t quadlet;
	int offset;
	int n_q = 5; /* number of additional quadlets to add */
	int len = rom1394_get_size( buffer);
	
	if (dir->nr_textual_leafs > 0)
		n_q++; /* we only support one textual leaf per unit */
	
	/* get root dir length and move p to after root dir */
	quadlet = ntohl(*p);
	length = quadlet >> 16;
	p += length + 1;
	
	/* get the difference between current position and beginning */
	offset = (p - buffer);
	
	/* move the rest down */
	/* size = original length minus offset */
	memmove( p+n_q, p, (len-offset) * sizeof(quadlet_t) );
	len += n_q;
	
	/* reset p to beginning of root */
	p = buffer + ROM1394_ROOT_DIRECTORY/4;
	
	/* adjust offsets in root dir */
	for (i=0; i < length; i++) {
		p++;
		quadlet = ntohl(*p);
		key = quadlet >> 24;
		value = quadlet & 0x00FFFFFF;
		DEBUG(-1, "key/value: %08x/%08x\n", key, value);
		
		switch (key) {
			case 0xD1: // Unit directory
			case 0x81: // textual leaves
			case 0x82:
				value = (key << 24) | ((value + n_q) & 0x00FFFFFF);
				*p = htonl(value);
				break;
		}
	}
	
	/* add unit directory entry to root */
	p++;
	value = (0xD1 << 24) | 1;
	*p++ = htonl(value);
	
	/* make new unit directory */
	p++;
	value = (0x12 << 24) | (dir->unit_spec_id & 0x00FFFFFF);
	*p++ = htonl(value);
	value = (0x13 << 24) | (dir->unit_sw_version & 0x00FFFFFF);
	*p++ = htonl(value);
	value = (0x17 << 24) | (dir->model_id & 0x00FFFFFF);
	*p++ = htonl(value);
    
    /* TODO: process multiple leafs */
	for (i = 0; i < 1 /* dir->nr_textual_leafs */; i++)
	{
		value = (0x81 << 24) | (((buffer+len)-p) & 0x00FFFFFF);
		*p++ = htonl(value);
		len += add_textual_leaf( buffer + len, dir->textual_leafs[i]);
	}
	
	/* compute CRC for unit directory */
	p = buffer + offset + 1;
	quadlet = ((n_q-2) << 16);
	quadlet |= make_crc(p + 1, n_q-2) & 0x0000FFFF;
	*p = htonl(quadlet);
	
	/* increment root directory length */
	length++;
	
	/* compute CRC for root */
	p = buffer + ROM1394_ROOT_DIRECTORY/4;
	quadlet = (length << 16);
	quadlet |= make_crc(p + 1, length) & 0x0000FFFF;
	*p = htonl(quadlet);

	return 0;
}
Exemple #4
0
int main(int argc, char **argv)
{
	raw1394handle_t handle;
	int retval;
	quadlet_t rom[0x100];
	size_t rom_size;
	unsigned char rom_version;
	rom1394_directory dir;
	char *(leaf[2]);
	
	handle = raw1394_new_handle();
	
	if (!handle) {
		if (!errno) {
				printf(not_compatible);
		} else {
				perror("couldn't get handle");
				printf(not_loaded);
		}
		exit(EXIT_FAILURE);
	}
	
	if (raw1394_set_port(handle, 0) < 0) {
		perror("couldn't set port");
		exit(EXIT_FAILURE);
	}
	
	/* get the current rom image */
	retval=raw1394_get_config_rom(handle, rom, 0x100, &rom_size, &rom_version);
	rom_size = rom1394_get_size(rom);
	printf("get_config_rom returned %d, romsize %d, rom_version %d:",retval,rom_size,rom_version);
	
	/* get the local directory */
	rom1394_get_directory( handle, raw1394_get_local_id(handle) & 0x3f, &dir);
	
	/* free the allocated mem for the textual leaves */
	rom1394_free_directory( &dir);
	
	/* add an RFC 2734 unit directory */
	dir.unit_spec_id    = 0x0000005e;
	dir.unit_sw_version = 0x00000001;
	leaf[0] = "IANA";
    leaf[1] = "IPv4";
	dir.nr_textual_leafs = 2;
	dir.textual_leafs = leaf;
	
	/* manipulate the rom */
	retval = rom1394_add_unit( rom, &dir);
	
	/* get the computed size of the rom image */
	rom_size = rom1394_get_size(rom);
	
	printf("rom1394_add_unit_directory returned %d, romsize %d:",retval,rom_size);
	
	/* convert computed rom size from quadlets to bytes before update */
	rom_size *= sizeof(quadlet_t);
	retval = raw1394_update_config_rom(handle, rom, rom_size, rom_version);
	printf("update_config_rom returned %d\n",retval);
	printf("You need to reload your ieee1394 modules to reset the rom.\n");
    
    raw1394_reset_bus(handle);
	
	exit(EXIT_SUCCESS);
}