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, ¤t_rom_size, ¤t_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, ¤t_rom_size, ¤t_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; }
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); }