示例#1
0
int
main (int argc, char **argv)
{
    char *emulation;
    long start_time = get_run_time ();

#if defined (HAVE_SETLOCALE) && defined (HAVE_LC_MESSAGES)
    setlocale (LC_MESSAGES, "");
#endif
#if defined (HAVE_SETLOCALE)
    setlocale (LC_CTYPE, "");
#endif
    bindtextdomain (PACKAGE, LOCALEDIR);
    textdomain (PACKAGE);

    program_name = argv[0];
    xmalloc_set_program_name (program_name);

    START_PROGRESS (program_name, 0);

    expandargv (&argc, &argv);

    bfd_init ();

    bfd_set_error_program_name (program_name);

    xatexit (remove_output);

    /* Set up the sysroot directory.  */
    ld_sysroot = get_sysroot (argc, argv);
    if (*ld_sysroot)
    {
        if (*TARGET_SYSTEM_ROOT == 0)
        {
            einfo ("%P%F: this linker was not configured to use sysroots\n");
            ld_sysroot = "";
        }
        else
            ld_canon_sysroot = lrealpath (ld_sysroot);
    }
    if (ld_canon_sysroot)
        ld_canon_sysroot_len = strlen (ld_canon_sysroot);
    else
        ld_canon_sysroot_len = -1;

    /* Set the default BFD target based on the configured target.  Doing
       this permits the linker to be configured for a particular target,
       and linked against a shared BFD library which was configured for
       a different target.  The macro TARGET is defined by Makefile.  */
    if (! bfd_set_default_target (TARGET))
    {
        einfo (_("%X%P: can't set BFD default target to `%s': %E\n"), TARGET);
        xexit (1);
    }

#if YYDEBUG
    {
        extern int yydebug;
        yydebug = 1;
    }
#endif

    config.build_constructors = TRUE;
    config.rpath_separator = ':';
    config.split_by_reloc = (unsigned) -1;
    config.split_by_file = (bfd_size_type) -1;
    config.make_executable = TRUE;
    config.magic_demand_paged = TRUE;
    config.text_read_only = TRUE;

    command_line.warn_mismatch = TRUE;
    command_line.warn_search_mismatch = TRUE;
    command_line.check_section_addresses = -1;
    command_line.disable_target_specific_optimizations = -1;
    command_line.poison_system_directories = TRUE;
    command_line.error_poison_system_directories = FALSE;

    /* We initialize DEMANGLING based on the environment variable
       COLLECT_NO_DEMANGLE.  The gcc collect2 program will demangle the
       output of the linker, unless COLLECT_NO_DEMANGLE is set in the
       environment.  Acting the same way here lets us provide the same
       interface by default.  */
    demangling = getenv ("COLLECT_NO_DEMANGLE") == NULL;

    link_info.allow_undefined_version = TRUE;
    link_info.keep_memory = TRUE;
    link_info.combreloc = TRUE;
    link_info.strip_discarded = TRUE;
    link_info.emit_hash = TRUE;
    link_info.callbacks = &link_callbacks;
    link_info.input_bfds_tail = &link_info.input_bfds;
    /* SVR4 linkers seem to set DT_INIT and DT_FINI based on magic _init
       and _fini symbols.  We are compatible.  */
    link_info.init_function = "_init";
    link_info.fini_function = "_fini";
    link_info.relax_pass = 1;
    link_info.pei386_auto_import = -1;
    link_info.spare_dynamic_tags = 5;
    link_info.path_separator = ':';

    ldfile_add_arch ("");
    emulation = get_emulation (argc, argv);
    ldemul_choose_mode (emulation);
    default_target = ldemul_choose_target (argc, argv);
    config.maxpagesize = bfd_emul_get_maxpagesize (default_target);
    config.commonpagesize = bfd_emul_get_commonpagesize (default_target);
    lang_init ();
    ldemul_before_parse ();
    lang_has_input_file = FALSE;
    parse_args (argc, argv);

    if (config.hash_table_size != 0)
        bfd_hash_set_default_size (config.hash_table_size);

    ldemul_set_symbols ();

    if (link_info.relocatable)
    {
        if (command_line.check_section_addresses < 0)
            command_line.check_section_addresses = 0;
        if (link_info.shared)
            einfo (_("%P%F: -r and -shared may not be used together\n"));
    }

    /* We may have -Bsymbolic, -Bsymbolic-functions, --dynamic-list-data,
       --dynamic-list-cpp-new, --dynamic-list-cpp-typeinfo and
       --dynamic-list FILE.  -Bsymbolic and -Bsymbolic-functions are
       for shared libraries.  -Bsymbolic overrides all others and vice
       versa.  */
    switch (command_line.symbolic)
    {
    case symbolic_unset:
        break;
    case symbolic:
        /* -Bsymbolic is for shared library only.  */
        if (link_info.shared)
        {
            link_info.symbolic = TRUE;
            /* Should we free the unused memory?  */
            link_info.dynamic_list = NULL;
            command_line.dynamic_list = dynamic_list_unset;
        }
        break;
    case symbolic_functions:
        /* -Bsymbolic-functions is for shared library only.  */
        if (link_info.shared)
            command_line.dynamic_list = dynamic_list_data;
        break;
    }

    switch (command_line.dynamic_list)
    {
    case dynamic_list_unset:
        break;
    case dynamic_list_data:
        link_info.dynamic_data = TRUE;
    case dynamic_list:
        link_info.dynamic = TRUE;
        break;
    }

    if (! link_info.shared)
    {
        if (command_line.filter_shlib)
            einfo (_("%P%F: -F may not be used without -shared\n"));
        if (command_line.auxiliary_filters)
            einfo (_("%P%F: -f may not be used without -shared\n"));
    }

    if (! link_info.shared || link_info.pie)
        link_info.executable = TRUE;

    /* Treat ld -r -s as ld -r -S -x (i.e., strip all local symbols).  I
       don't see how else this can be handled, since in this case we
       must preserve all externally visible symbols.  */
    if (link_info.relocatable && link_info.strip == strip_all)
    {
        link_info.strip = strip_debugger;
        if (link_info.discard == discard_sec_merge)
            link_info.discard = discard_all;
    }

    /* If we have not already opened and parsed a linker script,
       try the default script from command line first.  */
    if (saved_script_handle == NULL
            && command_line.default_script != NULL)
    {
        ldfile_open_command_file (command_line.default_script);
        parser_input = input_script;
        yyparse ();
    }

    /* If we have not already opened and parsed a linker script
       read the emulation's appropriate default script.  */
    if (saved_script_handle == NULL)
    {
        int isfile;
        char *s = ldemul_get_script (&isfile);

        if (isfile)
            ldfile_open_default_command_file (s);
        else
        {
            lex_string = s;
            lex_redirect (s);
        }
        parser_input = input_script;
        yyparse ();
        lex_string = NULL;
    }

    if (trace_file_tries)
    {
        if (saved_script_handle)
            info_msg (_("using external linker script:"));
        else
            info_msg (_("using internal linker script:"));
        info_msg ("\n==================================================\n");

        if (saved_script_handle)
        {
            static const int ld_bufsz = 8193;
            size_t n;
            char *buf = (char *) xmalloc (ld_bufsz);

            rewind (saved_script_handle);
            while ((n = fread (buf, 1, ld_bufsz - 1, saved_script_handle)) > 0)
            {
                buf[n] = 0;
                info_msg (buf);
            }
            rewind (saved_script_handle);
            free (buf);
        }
        else
        {
            int isfile;

            info_msg (ldemul_get_script (&isfile));
        }

        info_msg ("\n==================================================\n");
    }

    lang_final ();

    if (!lang_has_input_file)
    {
        if (version_printed)
            xexit (0);
        einfo (_("%P%F: no input files\n"));
    }

    if (trace_files)
        info_msg (_("%P: mode %s\n"), emulation);

    ldemul_after_parse ();

    if (config.map_filename)
    {
        if (strcmp (config.map_filename, "-") == 0)
        {
            config.map_file = stdout;
        }
        else
        {
            config.map_file = fopen (config.map_filename, FOPEN_WT);
            if (config.map_file == (FILE *) NULL)
            {
                bfd_set_error (bfd_error_system_call);
                einfo (_("%P%F: cannot open map file %s: %E\n"),
                       config.map_filename);
            }
        }
    }

    lang_process ();

    /* Print error messages for any missing symbols, for any warning
       symbols, and possibly multiple definitions.  */
    if (link_info.relocatable)
        link_info.output_bfd->flags &= ~EXEC_P;
    else
        link_info.output_bfd->flags |= EXEC_P;

    ldwrite ();

    if (config.map_file != NULL)
        lang_map ();
    if (command_line.cref)
        output_cref (config.map_file != NULL ? config.map_file : stdout);
    if (nocrossref_list != NULL)
        check_nocrossrefs ();

    lang_finish ();

    /* Even if we're producing relocatable output, some non-fatal errors should
       be reported in the exit status.  (What non-fatal errors, if any, do we
       want to ignore for relocatable output?)  */
    if (!config.make_executable && !force_make_executable)
    {
        if (trace_files)
            einfo (_("%P: link errors found, deleting executable `%s'\n"),
                   output_filename);

        /* The file will be removed by remove_output.  */
        xexit (1);
    }
    else
    {
        if (! bfd_close (link_info.output_bfd))
            einfo (_("%F%B: final close failed: %E\n"), link_info.output_bfd);

        /* If the --force-exe-suffix is enabled, and we're making an
        executable file and it doesn't end in .exe, copy it to one
         which does.  */
        if (! link_info.relocatable && command_line.force_exe_suffix)
        {
            int len = strlen (output_filename);

            if (len < 4
                    || (strcasecmp (output_filename + len - 4, ".exe") != 0
                        && strcasecmp (output_filename + len - 4, ".dll") != 0))
            {
                FILE *src;
                FILE *dst;
                const int bsize = 4096;
                char *buf = (char *) xmalloc (bsize);
                int l;
                char *dst_name = (char *) xmalloc (len + 5);

                strcpy (dst_name, output_filename);
                strcat (dst_name, ".exe");
                src = fopen (output_filename, FOPEN_RB);
                dst = fopen (dst_name, FOPEN_WB);

                if (!src)
                    einfo (_("%X%P: unable to open for source of copy `%s'\n"),
                           output_filename);
                if (!dst)
                    einfo (_("%X%P: unable to open for destination of copy `%s'\n"),
                           dst_name);
                while ((l = fread (buf, 1, bsize, src)) > 0)
                {
                    int done = fwrite (buf, 1, l, dst);

                    if (done != l)
                        einfo (_("%P: Error writing file `%s'\n"), dst_name);
                }

                fclose (src);
                if (fclose (dst) == EOF)
                    einfo (_("%P: Error closing file `%s'\n"), dst_name);
                free (dst_name);
                free (buf);
            }
        }
    }

    END_PROGRESS (program_name);

    if (config.stats)
    {
#ifdef HAVE_SBRK
        char *lim = (char *) sbrk (0);
#endif
        long run_time = get_run_time () - start_time;

        fprintf (stderr, _("%s: total time in link: %ld.%06ld\n"),
                 program_name, run_time / 1000000, run_time % 1000000);
#ifdef HAVE_SBRK
        fprintf (stderr, _("%s: data size %ld\n"), program_name,
                 (long) (lim - (char *) &environ));
#endif
    }

    /* Prevent remove_output from doing anything, after a successful link.  */
    output_filename = NULL;

    xexit (0);
    return 0;
}
示例#2
0
void cliFunc_ledToggle( char* args )
{
	print( NL ); // No \r\n by default after the command is entered
	info_msg("LEDs Toggle");
	LED_enable = !LED_enable;
}
示例#3
0
// Detect short or open circuit in Matrix
// Only works with IS31FL3733
void LED_shortOpenDetect()
{
#if ISSI_Chip_31FL3733_define == 1
	// Pause ISSI processing
	LED_pause = 1;

	for ( uint8_t ch = 0; ch < ISSI_Chips_define; ch++ )
	{
		uint8_t addr = LED_ChannelMapping[ ch ].addr;
		uint8_t bus = LED_ChannelMapping[ ch ].bus;

		// Set Global Current Control (needed for accurate reading)
		LED_writeReg( bus, addr, 0x01, 0x01, ISSI_ConfigPage );

		// Enable master sync for the first chip and disable software shutdown
		// Also enable OSD (Open/Short Detect)
		if ( ch == 0 )
		{
			LED_writeReg( bus, addr, 0x00, 0x45, ISSI_ConfigPage );
		}
		// Slave sync for the rest and disable software shutdown
		// Also enable OSD (Open/Short Detect)
		else
		{
			LED_writeReg( bus, addr, 0x00, 0x85, ISSI_ConfigPage );
		}

		// Wait for 3.3 ms before reading the value
		// Needs at least 3.264 ms to query the information
		delay_us(3300);

		// Read registers
		info_msg("Bus: ");
		printHex( bus );
		print(" Addr: ");
		printHex( addr );
		print(" - 0x18 -> 0x2F + 0x30 -> 0x47");
		print(NL);

		// Validate open detection
		// TODO
		for ( uint8_t reg = 0x18; reg < 0x30; reg++ )
		{
			uint8_t val = LED_readReg( bus, addr, reg, ISSI_LEDControlPage );
			printHex_op( val, 2 );
			print(" ");
		}
		print(NL);

		// Validate short detection
		// TODO
		for ( uint8_t reg = 0x30; reg < 0x48; reg++ )
		{
			uint8_t val = LED_readReg( bus, addr, reg, ISSI_LEDControlPage );
			printHex_op( val, 2 );
			print(" ");
		}
		print(NL);
	}

	// We have to adjust various settings in order to get the correct reading
	// Reset ISSI configuration
	LED_reset();
#endif
}
示例#4
0
void cliFunc_kbdProtocol( char* args )
{
	print( NL );
	info_msg("Keyboard Protocol: ");
	printInt8( USBKeys_Protocol );
}
示例#5
0
void cliFunc_readLEDs( char* args )
{
	print( NL );
	info_msg("LED State: ");
	printInt8( USBKeys_LEDs );
}
示例#6
0
文件: psl.c 项目: THofstee/pslse
// Initialize and start PSL thread
//
// The return value is encode int a 16-bit value divided into 4 for each
// possible adapter.  Then the 4 bits in each adapter represent the 4 possible
// AFUs on an adapter.  For example: afu0.0 is 0x8000 and afu3.0 is 0x0008.
uint16_t psl_init(struct psl **head, struct parms *parms, char *id, char *host,
		  int port, pthread_mutex_t * lock, FILE * dbg_fp)
{
	struct psl *psl;
	struct job_event *reset;
	uint16_t location;

	location = 0x8000;
	if ((psl = (struct psl *)calloc(1, sizeof(struct psl))) == NULL) {
		perror("malloc");
		error_msg("Unable to allocation memory for psl");
		goto init_fail;
	}
	psl->timeout = parms->timeout;
	if ((strlen(id) != 6) || strncmp(id, "afu", 3) || (id[4] != '.')) {
		warn_msg("Invalid afu name: %s", id);
		goto init_fail;
	}
	if ((id[3] < '0') || (id[3] > '3')) {
		warn_msg("Invalid afu major: %c", id[3]);
		goto init_fail;
	}
	if ((id[5] < '0') || (id[5] > '3')) {
		warn_msg("Invalid afu minor: %c", id[5]);
		goto init_fail;
	}
	psl->dbg_fp = dbg_fp;
	psl->major = id[3] - '0';
	psl->minor = id[5] - '0';
	psl->dbg_id = psl->major << 4;
	psl->dbg_id |= psl->minor;
	location >>= (4 * psl->major);
	location >>= psl->minor;
	if ((psl->name = (char *)malloc(strlen(id) + 1)) == NULL) {
		perror("malloc");
		error_msg("Unable to allocation memory for psl->name");
		goto init_fail;
	}
	strcpy(psl->name, id);
	if ((psl->host = (char *)malloc(strlen(host) + 1)) == NULL) {
		perror("malloc");
		error_msg("Unable to allocation memory for psl->host");
		goto init_fail;
	}
	strcpy(psl->host, host);
	psl->port = port;
	psl->client = NULL;
	psl->idle_cycles = PSL_IDLE_CYCLES;
	psl->lock = lock;

	// Connect to AFU
	psl->afu_event = (struct AFU_EVENT *)malloc(sizeof(struct AFU_EVENT));
	if (psl->afu_event == NULL) {
		perror("malloc");
		goto init_fail;
	}
	info_msg("Attempting to connect AFU: %s @ %s:%d", psl->name,
		 psl->host, psl->port);
	if (psl_init_afu_event(psl->afu_event, psl->host, psl->port) !=
	    PSL_SUCCESS) {
		warn_msg("Unable to connect AFU: %s @ %s:%d", psl->name,
			 psl->host, psl->port);
		goto init_fail;
	}
	// DEBUG
	debug_afu_connect(psl->dbg_fp, psl->dbg_id);

	// Initialize job handler
	if ((psl->job = job_init(psl->afu_event, &(psl->state), psl->dbg_fp,
				 psl->dbg_id)) == NULL) {
		perror("job_init");
		goto init_fail;
	}
	// Initialize mmio handler
	if ((psl->mmio = mmio_init(psl->afu_event, psl->timeout, psl->dbg_fp,
				   psl->dbg_id)) == NULL) {
		perror("mmio_init");
		goto init_fail;
	}
	// Initialize cmd handler
	if ((psl->cmd = cmd_init(psl->afu_event, parms, psl->mmio,
				 &(psl->state), psl->dbg_fp, psl->dbg_id))
	    == NULL) {
		perror("cmd_init");
		goto init_fail;
	}
	// Set credits for AFU
	if (psl_aux1_change(psl->afu_event, psl->cmd->credits) != PSL_SUCCESS) {
		warn_msg("Unable to set credits");
		goto init_fail;
	}
	// Start psl loop thread
	if (pthread_create(&(psl->thread), NULL, _psl_loop, psl)) {
		perror("pthread_create");
		goto init_fail;
	}
	// Add psl to list
	while ((*head != NULL) && ((*head)->major < psl->major)) {
		head = &((*head)->_next);
	}
	while ((*head != NULL) && ((*head)->major == psl->major) &&
	       ((*head)->minor < psl->minor)) {
		head = &((*head)->_next);
	}
	psl->_next = *head;
	if (psl->_next != NULL)
		psl->_next->_prev = psl;
	*head = psl;

	// Send reset to AFU
	reset = add_job(psl->job, PSL_JOB_RESET, 0L);
	while (psl->job->job == reset) {	/*infinite loop */
		lock_delay(psl->lock);
	}

	// Read AFU descriptor
	psl->state = PSLSE_DESC;
	read_descriptor(psl->mmio, psl->lock);

	// Finish PSL configuration
	psl->state = PSLSE_IDLE;
	if (dedicated_mode_support(psl->mmio)) {
		// AFU supports Dedicated Mode
		psl->max_clients = 1;
	}
	if (directed_mode_support(psl->mmio)) {
		// AFU supports Directed Mode
		psl->max_clients = psl->mmio->desc.num_of_processes;
	}
	if (psl->max_clients == 0) {
		error_msg("AFU programming model is invalid");
		goto init_fail;
	}
	psl->client = (struct client **)calloc(psl->max_clients,
					       sizeof(struct client *));
	psl->cmd->client = psl->client;
	psl->cmd->max_clients = psl->max_clients;

	return location;

 init_fail:
	if (psl) {
		if (psl->afu_event) {
			psl_close_afu_event(psl->afu_event);
			free(psl->afu_event);
		}
		if (psl->host)
			free(psl->host);
		if (psl->name)
			free(psl->name);
		free(psl);
	}
	pthread_mutex_unlock(lock);
	return 0;
}
示例#7
0
int
proc_rule(struct htx_data *phtx_info, struct ruleinfo *prule_info,
          char *wbuf, char *rbuf, struct blk_num_typ *pblk_num)
{
  int            dlen, loop, rc;                   
  char           msg[220], path[100];
  unsigned short seed[3];

  rc = 0;
  init_seed(seed);            /* initialize seed for random number generator */
  dlen = prule_info->num_blks * BLK_SIZE;       /* initialize length of data */
                                           /*-------------------------------*/
                                           /* initialize the write buffer   */
                                           /*-------------------------------*/
  if ( (prule_info->pattern_id[0] != '#') && 
       (prule_info->pattern_id[0] != 0) ) {
	 path[0] ='\0';	  
     if ( (int) htx_strlen((char *) htx_strcpy(path, getenv("HTXPATTERNS"))) == 0 )
        htx_strcpy(path, "../pattern/");         /* default ONLY */
     htx_strcat (path, prule_info->pattern_id);
     rc = hxfpat(path, wbuf, dlen);
     if ( rc == 1 ) {
        sprintf(msg, "cannot open pattern file - %s\n", path);
        hxfmsg(phtx_info, 0, SYSERR, msg);
        return(1);
     } 
     if ( rc == 2 ) {
        sprintf(msg, "cannot read pattern file - %s\n", path);
        hxfmsg(phtx_info, 0, SYSERR, msg);
        return(1);
     } 
  } else if ( prule_info->pattern_id[0] == '#' )
     bldbuf((unsigned short*)wbuf, dlen, prule_info->pattern_id, pblk_num);
  pblk_num->in_rule = 0;      /* initialize block number within current rule */
  rc = 0;
  tape_error_code = 0;
  for ( loop = 1; loop <= prule_info->num_oper; loop++ ) {
     if ( strcmp(prule_info->oper, "R") == 0 ) {     
        rc = read_tape(phtx_info, prule_info, loop, pblk_num, rbuf);
     } else if ( strcmp(prule_info->oper, "W") == 0 ) {
        rc = write_tape(phtx_info, prule_info, loop, pblk_num, wbuf);
     } else if ( strcmp(prule_info->oper, "RC") == 0 ) {   
        rc = read_tape(phtx_info, prule_info, loop, pblk_num, rbuf);
        if ( rc >= 0 )     
           rc = cmpbuf(phtx_info, prule_info, loop, pblk_num, wbuf, rbuf);
     } else if ( strcmp(prule_info->oper, "RW") == 0 ) {
        rc = rewind_tape(phtx_info, prule_info, loop, pblk_num);
     } else if ( strcmp(prule_info->oper, "WEOF") == 0 ) { 
        rc = weof_tape(phtx_info, prule_info, loop, pblk_num);
     } else if ( strcmp(prule_info->oper, "SF") == 0 ) {  
        rc = search_file(phtx_info, prule_info, loop, pblk_num);
     } else if ( strcmp(prule_info->oper, "SR") == 0 ) {  
        rc = search_rec(phtx_info, prule_info, loop, pblk_num);
     } else if ( strcmp(prule_info->oper, "D") == 0 ) { 
        rc = diag_tape(phtx_info, prule_info, loop, pblk_num);
     } else if ( strcmp(prule_info->oper, "E") == 0 ) { 
        rc = erase_tape(phtx_info, prule_info, loop, pblk_num);
     } else if ( strcmp(prule_info->oper, "S") == 0 ) { 
        rc = do_sleep(phtx_info, prule_info, loop, pblk_num);
     } else if ( strcmp(prule_info->oper, "CO") == 0 ) { 
        rc = close_open(phtx_info, prule_info, loop, pblk_num);
     } else if ( strcmp(prule_info->oper, "C") == 0 ) { 
        rc = tclose(phtx_info, prule_info, loop, pblk_num);
     } else if ( strcmp(prule_info->oper, "O") == 0 ) {  
        rc = topen(phtx_info, prule_info, loop, pblk_num);
     } else if ( strcmp(prule_info->oper, "WEOT") == 0 ) {
        rc = write_eot(phtx_info, prule_info,loop, pblk_num, wbuf);
     } else if ( strcmp(prule_info->oper, "RCEOT") == 0 ) {
        rc = read_eot(phtx_info, prule_info, loop,pblk_num, wbuf, rbuf);
     } else if ( strcmp(prule_info->oper, "REOT") == 0 ) {  
        rc = read_teot(phtx_info, prule_info, loop, pblk_num, wbuf, rbuf);
     } else if ( strcmp(prule_info->oper, "RS") == 0 ) {  
        rc = prt_req_sense(phtx_info, prule_info, loop, pblk_num);
	 }
#ifndef __HTX_LINUX__		
     else if ( strcmp(prule_info->oper, "ML") == 0 ) { 
        rc = medium_load(phtx_info, prule_info, loop, pblk_num);
     } else if ( strcmp(prule_info->oper, "MUL") == 0 ) {   
        rc = medium_unload(phtx_info, prule_info, loop, pblk_num);
     } else if ( strcmp(prule_info->oper, "RES") == 0 ) {   
        rc = read_status(phtx_info, prule_info, loop, pblk_num);
     } else if ( strcmp(prule_info->oper, "IE") == 0 ) {   
        rc = init_element(phtx_info, prule_info, loop, pblk_num);
     } else if ( strcmp(prule_info->oper, "RP") == 0 ) {  
        rc = read_posit(phtx_info, prule_info, loop, pblk_num);
     } else if ( strcmp(prule_info->oper, "LB") == 0 ) {   
        rc = loc_block(phtx_info, prule_info, loop, pblk_num);
     } else if ( strcmp(prule_info->oper, "ASF") == 0 ) { 
        rc = asearch_file(phtx_info, prule_info, loop, pblk_num);
     } else if ( strcmp(prule_info->oper, "ASR") == 0 ) { 
        rc = asearch_rec(phtx_info, prule_info, loop, pblk_num);
     } else if ( strcmp(prule_info->oper, "ADUL") == 0 ) {  
        rc = write_unload(phtx_info, prule_info, loop, pblk_num, wbuf);
     } else if ( strcmp(prule_info->oper, "TWIE") == 0 ) {  
        rc = twin_tape(phtx_info, prule_info, loop, pblk_num);
     } else if ( strcmp(prule_info->oper, "TWPE") == 0 ) {   
        rc = twps_tape(phtx_info, prule_info, loop, pblk_num);
     } else if ( strcmp(prule_info->oper, "TWRE") == 0 ) {  
        rc = twrd_stat(phtx_info, prule_info, loop, pblk_num);
     } else if ( strcmp(prule_info->oper, "TWMM") == 0 ) { 
        rc = twmv_tape(phtx_info, prule_info, loop, pblk_num);
     } else if ( strcmp(prule_info->oper, "TWUL") == 0 ) {  
        rc = unload_write(phtx_info, prule_info, loop, pblk_num, wbuf);
     } else if ( strcmp(prule_info->oper, "WUL") == 0 ) {   
        rc = tape_unload(phtx_info, prule_info, loop, pblk_num, wbuf);
     } else if ( strcmp(prule_info->oper, "CDRE") == 0 ) {
        rc = cdrd_stat(phtx_info, prule_info, loop, pblk_num);
     } else if ( strcmp(prule_info->oper, "CDMM") == 0 ) {  
        rc = cdmv_tape(phtx_info, prule_info, loop, pblk_num);
     } else if ( strcmp(prule_info->oper, "HUNL") == 0 ) {
        rc = himove(phtx_info, prule_info, loop, pblk_num);
     } else if ( strcmp(prule_info->oper, "HINI") == 0 ) {
        rc = hiinit(phtx_info, prule_info, loop, pblk_num);
     } else if ( strcmp(prule_info->oper, "HREL") == 0 ) {
        rc = hielem(phtx_info, prule_info, loop, pblk_num);
     } else if ( strcmp(prule_info->oper, "HWUN") == 0 ) {
        rc = hidal_unload(phtx_info, prule_info, loop, pblk_num, wbuf);
     } else if ( strcmp(prule_info->oper, "DBUG") == 0 ) {  
       rc = set_dbug(phtx_info, prule_info, pblk_num);
     } 
#endif
	 else if ( strcmp(prule_info->oper, "XCMD") == 0 ) {
       rc = do_cmd(phtx_info, prule_info, pblk_num);
     } else {
        ;
     }
     hxfupdate(UPDATE, phtx_info);
     if ( phtx_info->run_type[0] == 'O' ) {
        info_msg(phtx_info, prule_info, loop, pblk_num, msg);
        hxfmsg(phtx_info, 0, INFO, msg);
     } 
     if ( rc != 0 )
        break;
  } 
  return(rc);
} 
示例#8
0
int proc_rule(struct htx_data *ps, struct ruleinfo *pr, char *wbuf, char *rbuf, unsigned int *last_lba, unsigned int *pblk_size)
{
  int            blkno[3], blkno_save[3]; /* block # ptrs 0-curr,1-up,2-dwn */
  int            rc, i, rc_ptr, save_dlen, loop;
  unsigned short seed[3];
  char           path[100], msg[221], *tbuf, *tbuf_malloc;

  int read_res = -1;

  tbuf_malloc = malloc(TMP_BUF_SIZE + PAGE_SIZE);
  if(tbuf_malloc == NULL) { /* Out of memory? */
     sprintf(msg, "Cannot allocate memory for tbuf: %d bytes\n", TMP_BUF_SIZE + PAGE_SIZE);
     hxfmsg(ps, 0, SYSERR, msg);
     return(1);
  }

#ifndef __HTX_LINUX__     /* AIX */
  tbuf = tbuf_malloc;
#else                     /* Linux */
  /* Page align the tmp buffer for linux raw IO */
  tbuf = (char *)HTX_PAGE_ALIGN(tbuf_malloc);
#endif

  init_seed(seed);                /* init seed for random number generator */
  if ( strcmp(pr->addr_type, "SEQ") == 0 ||         /* init length of data */
       strcmp(pr->type_length, "FIXED") == 0)       /* to be transmitted   */
     pr->dlen = pr->num_blks * pr->bytpsec;
  else
     pr->dlen = random_dlen(pr->bytpsec, pr->tot_blks, seed);
  if ( strcmp(pr->oper, "RC") == 0 ) {      /* init write buff for oper RC */
                                   /* get HTXPATTERNS environment variable */
     strcpy(path, ""); /* Linux will need this initialization */
     if ((char *) getenv("HTXPATTERNS") != NULL) {
                 strcpy(path, (char *) getenv("HTXPATTERNS"));
     } else {
         strcpy(path, "../pattern/");                       /* default ONLY */
     }
     strcat (path, pr->pattern_id);
     rc = hxfpat(path, wbuf, pr->dlen);
     if ( rc == 1 ) {
        sprintf(msg, "Cannot open pattern file - %s\n", path);
        hxfmsg(ps, 0, SYSERR, msg);
        return(1);
     }
     if ( rc == 2 ) {
        sprintf(msg, "Cannot read pattern file - %s\n", path);
        hxfmsg(ps, 0, SYSERR, msg);
        return(1);
     }
  }
  if ( strcmp(pr->addr_type, "SEQ") == 0 )    /* init current block number */
     init_blkno(pr, blkno);
  else
     random_blkno(blkno, pr->dlen, pr->bytpsec, pr->max_blkno, seed,
                  pr->min_blkno);
  for ( i = 0; i < 3; i++ )
      blkno_save[i] = blkno[i];

  for ( loop = 1 ; loop <= pr->num_oper ; loop++ ) {
     if ( strcmp(pr->oper, "MS") == 0 ) {
        ms_get(pr, ps, last_lba, pblk_size);
    } else if ( strcmp(pr->oper, "R") == 0 ) {
        read_cdrom(ps, pr, loop, blkno, rbuf);
    } else if ( strcmp(pr->oper, "RWP") == 0 ) {
        read_write_pattern(ps, pr, loop, blkno, rbuf);
    } else if ( strcmp(pr->oper, "RRC") == 0 ) {
        /*read_cdrom(ps, pr, loop, blkno, wbuf);
        read_cdrom(ps, pr, loop, blkno, rbuf);*/

        if( (read_res = read_cdrom(ps, pr, loop, blkno, wbuf) ) == 0 ) {/* read success */
        	if( (read_res = read_cdrom(ps, pr, loop, blkno, rbuf) ) == 0 ) {/* read success, again */
        		cmpbuf(ps, pr, loop, blkno, wbuf, rbuf); /* safe to compare */
			} else { /* second read fail */
				 sprintf(msg, "read_cdrom() failed in Re-Read sequence of RRC oper\n"
				              "Skipping compare operation\n");
				 prt_msg(ps, pr, loop, blkno, 0, SOFT, msg);
			}
		} else { /* first read fail */
			 sprintf(msg, "read_cdrom() failed in Read sequence of RRC oper\n"
						  "Skipping compare operation\n");
			 prt_msg(ps, pr, loop, blkno, 0, SOFT, msg);
		}

    } else if ( strcmp(pr->oper, "RC") == 0 ) {
        for ( i = 0; i < 3; i++ )
           blkno[i] = blkno_save[i];      /* RC = always start at same blkno */
                       /******************************************************/
                       /*- First, read the successive data blocks into rbuf  -*/
                       /******************************************************/
        save_dlen = pr->dlen;
        rc_ptr = 0;                          /*- init read/compare pointer --*/
        pr->dlen = pr->bytpsec;      /*-- read 1 block at a time into rbuf --*/
        while ( rc_ptr <= pr->num_blks ) {
           /*read_cdrom(ps, pr, loop, blkno, tbuf);*/
           if( ( read_res = read_cdrom(ps, pr, loop, blkno, tbuf) ) != 0 ) /* read un-succesfull ?*/
           		break;

           for ( i = 0; i <= pr->dlen; i++ )
               rbuf[(pr->dlen*rc_ptr)+i] = tbuf[i];
           set_blkno(blkno, pr->direction, pr->increment, 1);
           rc_ptr++;
        }
        if( read_res == 0 ) {/* only if all reads are successful ... */
			pr->dlen = save_dlen;
			cmpbuf(ps, pr, loop, blkno_save, wbuf, rbuf);
		} else { /* read fail */
			 sprintf(msg, "read_cdrom() failed in Read sequence of RC oper\n"
						  "Skipping compare operation\n");
			 prt_msg(ps, pr, loop, blkno, 0, SOFT, msg);
		}

    } else if ( strcmp(pr->oper, "D") == 0 ) {
        diag_cdrom(ps, pr, loop, blkno);
    } else if ( strcmp(pr->oper, "A") == 0 ) {
      #ifndef __HTX_LINUX__
        audio_cdrom(ps, pr, loop, blkno);
      #endif
    } else if ( strcmp(pr->oper, "AMM") == 0 ) {
		if ( (0 != strncmp(device_subclass, "sata", 16)) && (0 != strncmp(device_subclass, "usbif", 16)) ) {
			/* PLAYUDIO MSF is not supported for SATA drives */
        	audio_mm(ps, pr, loop, blkno);
		}
		else {
			sprintf(msg, "Skipping AMM stanza for SATA/USB drive, rule_id = %s\n", pr->rule_id);
       		hxfmsg(ps, 0, INFO, msg);
		}
    } else if ( strcmp(pr->oper, "RS") == 0 ) {
        prt_req_sense(ps, pr, loop, blkno);
    } else if ( strcmp(pr->oper, "S") == 0 ) {
        do_sleep(ps, pr, loop, blkno);
    } else if ( strcmp(pr->oper, "XCMD") == 0 ) {
        rc = do_cmd(ps, pr);
    } else {
        ;
    }

    hxfupdate(UPDATE, ps);
    if ( ps->run_type[0] == 'O' ) {
       info_msg(ps, pr, loop, blkno, msg);
       hxfmsg(ps, 0, INFO, msg);
    }
    if ( strcmp(pr->type_length, "RANDOM") == 0 && /* set lgth of data trans */
         strcmp(pr->addr_type, "RANDOM") == 0 )    /* if random is specified */
       pr->dlen = random_dlen(pr->bytpsec, pr->tot_blks, seed);
    if ( strcmp(pr->addr_type, "RANDOM") == 0 ) /* set block # for next oper */
       random_blkno(blkno, pr->dlen, pr->bytpsec, pr->max_blkno, seed,
                    pr->min_blkno);
    else if ( (strcmp(pr->oper, "RC") != 0 ) /* set blkno if not RC or RWP */
		      && ( strcmp(pr->oper, "RWP") != 0 ))
       set_blkno(blkno, pr->direction, pr->increment, pr->num_blks);
    if ( strcmp(pr->addr_type, "SEQ") == 0 ) {
       rc = wrap(pr, blkno);
       if ( rc == 1 )
          init_blkno(pr,blkno);
    }
  }
  free(tbuf_malloc);
  return(0);
}
示例#9
0
文件: psl.c 项目: THofstee/pslse
// PSL thread loop
static void *_psl_loop(void *ptr)
{
	struct psl *psl = (struct psl *)ptr;
	struct cmd_event *event, *temp;
	int events, i, stopped, reset;
	uint8_t ack = PSLSE_DETACH;

	stopped = 1;
	pthread_mutex_lock(psl->lock);
	while (psl->state != PSLSE_DONE) {
		// idle_cycles continues to generate clock cycles for some
		// time after the AFU has gone idle.  Eventually clocks will
		// not be presented to an idle AFU to keep simulation
		// waveforms from getting huge with no activity cycles.
		if (psl->state != PSLSE_IDLE) {
			psl->idle_cycles = PSL_IDLE_CYCLES;
			if (stopped)
				info_msg("Clocking %s", psl->name);
			fflush(stdout);
			stopped = 0;
		}

		if (psl->idle_cycles) {
			// Clock AFU
			psl_signal_afu_model(psl->afu_event);
			// Check for events from AFU
			events = psl_get_afu_events(psl->afu_event);

			// Error on socket
			if (events < 0) {
				warn_msg("Lost connection with AFU");
				break;
			}
			// Handle events from AFU
			if (events > 0)
				_handle_afu(psl);

			// Drive events to AFU
			send_job(psl->job);
			send_mmio(psl->mmio);

			if (psl->mmio->list == NULL)
				psl->idle_cycles--;
		} else {
			if (!stopped)
				info_msg("Stopping clocks to %s", psl->name);
			stopped = 1;
			lock_delay(psl->lock);
		}

		// Skip client section if AFU descriptor hasn't been read yet
		if (psl->client == NULL) {
			lock_delay(psl->lock);
			continue;
		}
		// Check for event from application
		reset = 0;
		for (i = 0; i < psl->max_clients; i++) {
			if (psl->client[i] == NULL)
				continue;
			if ((psl->client[i]->state == CLIENT_NONE) &&
			    (psl->client[i]->idle_cycles == 0)) {
				put_bytes(psl->client[i]->fd, 1, &ack,
					  psl->dbg_fp, psl->dbg_id,
					  psl->client[i]->context);
				_free(psl, psl->client[i]);
				psl->client[i] = NULL;
				reset = 1;
				continue;
			}
			if (psl->state == PSLSE_RESET)
				continue;
			_handle_client(psl, psl->client[i]);
			if (psl->client[i]->idle_cycles) {
				psl->client[i]->idle_cycles--;
			}
			if (client_cmd(psl->cmd, psl->client[i])) {
				psl->client[i]->idle_cycles = PSL_IDLE_CYCLES;
			}
		}

		// Send reset to AFU
		if (reset == 1) {
			psl->cmd->buffer_read = NULL;
			event = psl->cmd->list;
			while (event != NULL) {
				if (reset) {
					warn_msg
					    ("Client dropped context before AFU completed");
					reset = 0;
				}
				warn_msg("Dumping command tag=0x%02x",
					 event->tag);
				if (event->data) {
					free(event->data);
				}
				if (event->parity) {
					free(event->parity);
				}
				temp = event;
				event = event->_next;
				free(temp);
			}
			psl->cmd->list = NULL;
			info_msg("Sending reset to AFU");
			add_job(psl->job, PSL_JOB_RESET, 0L);
		}

		lock_delay(psl->lock);
	}

	// Disconnect clients
	for (i = 0; i < psl->max_clients; i++) {
		if ((psl->client != NULL) && (psl->client[i] != NULL)) {
			// FIXME: Send warning to clients first?
			info_msg("Disconnecting %s context %d", psl->name,
				 psl->client[i]->context);
			close_socket(&(psl->client[i]->fd));
		}
	}

	// DEBUG
	debug_afu_drop(psl->dbg_fp, psl->dbg_id);

	// Disconnect from simulator, free memory and shut down thread
	info_msg("Disconnecting %s @ %s:%d", psl->name, psl->host, psl->port);
	if (psl->client)
		free(psl->client);
	if (psl->_prev)
		psl->_prev->_next = psl->_next;
	if (psl->_next)
		psl->_next->_prev = psl->_prev;
	if (psl->cmd) {
		free(psl->cmd);
	}
	if (psl->job) {
		free(psl->job);
	}
	if (psl->mmio) {
		free(psl->mmio);
	}
	if (psl->host)
		free(psl->host);
	if (psl->afu_event) {
		psl_close_afu_event(psl->afu_event);
		free(psl->afu_event);
	}
	if (psl->name)
		free(psl->name);
	if (*(psl->head) == psl)
		*(psl->head) = psl->_next;
	pthread_mutex_unlock(psl->lock);
	free(psl);
	pthread_exit(NULL);
}
示例#10
0
bfd_boolean
ldfile_try_open_bfd (const char *attempt,
		     lang_input_statement_type *entry)
{
  entry->the_bfd = bfd_openr (attempt, entry->target);

  if (verbose)
    {
      if (entry->the_bfd == NULL)
	info_msg (_("attempt to open %s failed\n"), attempt);
      else
	info_msg (_("attempt to open %s succeeded\n"), attempt);
    }

  if (entry->the_bfd == NULL)
    {
      if (bfd_get_error () == bfd_error_invalid_target)
	einfo (_("%F%P: invalid BFD target `%s'\n"), entry->target);
      return FALSE;
    }

  /* Linker needs to decompress sections.  */
  entry->the_bfd->flags |= BFD_DECOMPRESS;

  /* If we are searching for this file, see if the architecture is
     compatible with the output file.  If it isn't, keep searching.
     If we can't open the file as an object file, stop the search
     here.  If we are statically linking, ensure that we don't link
     a dynamic object.

     In the code below, it's OK to exit early if the check fails,
     closing the checked BFD and returning FALSE, but if the BFD
     checks out compatible, do not exit early returning TRUE, or
     the plugins will not get a chance to claim the file.  */

  if (entry->flags.search_dirs || !entry->flags.dynamic)
    {
      bfd *check;

      if (bfd_check_format (entry->the_bfd, bfd_archive))
	check = bfd_openr_next_archived_file (entry->the_bfd, NULL);
      else
	check = entry->the_bfd;

      if (check != NULL)
	{
	  if (! bfd_check_format (check, bfd_object))
	    {
	      if (check == entry->the_bfd
		  && entry->flags.search_dirs
		  && bfd_get_error () == bfd_error_file_not_recognized
		  && ! ldemul_unrecognized_file (entry))
		{
		  int token, skip = 0;
		  char *arg, *arg1, *arg2, *arg3;
		  extern FILE *yyin;

		  /* Try to interpret the file as a linker script.  */
		  ldfile_open_command_file (attempt);

		  ldfile_assumed_script = TRUE;
		  parser_input = input_selected;
		  ldlex_both ();
		  token = INPUT_SCRIPT;
		  while (token != 0)
		    {
		      switch (token)
			{
			case OUTPUT_FORMAT:
			  if ((token = yylex ()) != '(')
			    continue;
			  if ((token = yylex ()) != NAME)
			    continue;
			  arg1 = yylval.name;
			  arg2 = NULL;
			  arg3 = NULL;
			  token = yylex ();
			  if (token == ',')
			    {
			      if ((token = yylex ()) != NAME)
				{
				  free (arg1);
				  continue;
				}
			      arg2 = yylval.name;
			      if ((token = yylex ()) != ','
				  || (token = yylex ()) != NAME)
				{
				  free (arg1);
				  free (arg2);
				  continue;
				}
			      arg3 = yylval.name;
			      token = yylex ();
			    }
			  if (token == ')')
			    {
			      switch (command_line.endian)
				{
				default:
				case ENDIAN_UNSET:
				  arg = arg1; break;
				case ENDIAN_BIG:
				  arg = arg2 ? arg2 : arg1; break;
				case ENDIAN_LITTLE:
				  arg = arg3 ? arg3 : arg1; break;
				}
			      if (strcmp (arg, lang_get_output_target ()) != 0)
				skip = 1;
			    }
			  free (arg1);
			  if (arg2) free (arg2);
			  if (arg3) free (arg3);
			  break;
			case NAME:
			case LNAME:
			case VERS_IDENTIFIER:
			case VERS_TAG:
			  free (yylval.name);
			  break;
			case INT:
			  if (yylval.bigint.str)
			    free (yylval.bigint.str);
			  break;
			}
		      token = yylex ();
		    }
		  ldlex_popstate ();
		  ldfile_assumed_script = FALSE;
		  fclose (yyin);
		  yyin = NULL;
		  if (skip)
		    {
		      if (command_line.warn_search_mismatch)
			einfo (_("%P: skipping incompatible %s "
				 "when searching for %s\n"),
			       attempt, entry->local_sym_name);
		      bfd_close (entry->the_bfd);
		      entry->the_bfd = NULL;
		      return FALSE;
		    }
		}
	      goto success;
	    }

	  if (!entry->flags.dynamic && (entry->the_bfd->flags & DYNAMIC) != 0)
	    {
	      einfo (_("%F%P: attempted static link of dynamic object `%s'\n"),
		     attempt);
	      bfd_close (entry->the_bfd);
	      entry->the_bfd = NULL;
	      return FALSE;
	    }

	  if (entry->flags.search_dirs
	      && !bfd_arch_get_compatible (check, link_info.output_bfd,
					   command_line.accept_unknown_input_arch)
	      /* XCOFF archives can have 32 and 64 bit objects.  */
	      && ! (bfd_get_flavour (check) == bfd_target_xcoff_flavour
		    && bfd_get_flavour (link_info.output_bfd) == bfd_target_xcoff_flavour
		    && bfd_check_format (entry->the_bfd, bfd_archive)))
	    {
	      if (command_line.warn_search_mismatch)
		einfo (_("%P: skipping incompatible %s "
			 "when searching for %s\n"),
		       attempt, entry->local_sym_name);
	      bfd_close (entry->the_bfd);
	      entry->the_bfd = NULL;
	      return FALSE;
	    }
	}
    }
success:
#ifdef ENABLE_PLUGINS
  /* If plugins are active, they get first chance to claim
     any successfully-opened input file.  We skip archives
     here; the plugin wants us to offer it the individual
     members when we enumerate them, not the whole file.  We
     also ignore corefiles, because that's just weird.  It is
     a needed side-effect of calling  bfd_check_format with
     bfd_object that it sets the bfd's arch and mach, which
     will be needed when and if we want to bfd_create a new
     one using this one as a template.  */
  if (bfd_check_format (entry->the_bfd, bfd_object)
      && plugin_active_plugins_p ()
      && !no_more_claiming)
    {
      int fd = open (attempt, O_RDONLY | O_BINARY);
      if (fd >= 0)
	{
	  struct ld_plugin_input_file file;

	  file.name = attempt;
	  file.offset = 0;
	  file.filesize = lseek (fd, 0, SEEK_END);
	  file.fd = fd;
	  plugin_maybe_claim (&file, entry);
	}
    }
#endif /* ENABLE_PLUGINS */

  /* It opened OK, the format checked out, and the plugins have had
     their chance to claim it, so this is success.  */
  return TRUE;
}
示例#11
0
JNIEXPORT jint JNICALL Java_com_example_enzocamtest_CamView_startCamera(JNIEnv* env,
		jobject thiz, jstring deviceName, jint width, jint height)
{
	int ret = 0;
	const char* dev_name = (*env)->GetStringUTFChars(env, deviceName, 0);

	/* Initialize all the structures we will be using */
	mjpgDec = (struct decoderInstance *)calloc(1, sizeof(struct decoderInstance));
	usbCam = (struct cameraInstance  *)calloc(1, sizeof(struct cameraInstance));

	camData = (struct mediaBuffer *)calloc(1, sizeof(struct mediaBuffer));
	yuvData = (struct mediaBuffer *)calloc(1, sizeof(struct mediaBuffer));

	y422_buf = (struct g2d_buf *)calloc(1, sizeof(struct g2d_buf));

	/* Set properties for H264 AVC decoder */
	mjpgDec->type = MJPEG;

	/* Set properties for USB camera */
	usbCam->type = MJPEG;
	usbCam->width = width;
	usbCam->height = height;
	usbCam->fps = FPS;
	strcpy(usbCam->deviceName, dev_name);

	/* Init the VPU. This must be done before a codec can be used.
	   If this fails, we need to bail. */
	ret = vpuInit();
	if (ret < 0)
		return -1;

	if (cameraInit(usbCam) < 0)
		ret = -1;
	/* In order to init mjpg decoder, it must be supplied with bitstream
	   parse */
	ret = cameraGetFrame(usbCam, camData);
	if (ret < 0) {
		err_msg("Could not get camera frame\n");
		ret = -1;
	}
	if (decoderInit(mjpgDec, camData) < 0) {
		err_msg("Could not init MJPG decoder\n");
		ret = -1;
	}

	y420_buf = g2d_alloc(width * height * 2, 0);
	rgb_buf = g2d_alloc(width * height * 2, 0);

	rgb_surf.planes[0] = rgb_buf->buf_paddr;
	rgb_surf.left = 0;
	rgb_surf.top = 0;
	rgb_surf.right = width;
	rgb_surf.bottom = height;
	rgb_surf.stride = width;
	rgb_surf.width = width;
	rgb_surf.height = height;
	rgb_surf.rot = G2D_ROTATION_0;
	rgb_surf.format = G2D_RGB565;

	y420_surf.planes[0] = y420_buf->buf_paddr;
	y420_surf.planes[1] = y420_surf.planes[0] + width*height;
	y420_surf.planes[2] = y420_surf.planes[1] + width*height/4;
	y420_surf.left = 0;
	y420_surf.top = 0;
	y420_surf.right = width;
	y420_surf.bottom = height;
	y420_surf.stride = width;
	y420_surf.width  = width;
	y420_surf.height = height;
	y420_surf.rot    = G2D_ROTATION_0;
	y420_surf.format = G2D_I420;

	info_msg("Finished setting up JNI codec and camera!\n");

	return ret;
}
示例#12
0
bfd_boolean
ldfile_try_open_bfd (const char *attempt,
		     lang_input_statement_type *entry)
{
  entry->the_bfd = bfd_openr (attempt, entry->target);

  if (trace_file_tries)
    {
      if (entry->the_bfd == NULL)
	info_msg (_("attempt to open %s failed\n"), attempt);
      else
	info_msg (_("attempt to open %s succeeded\n"), attempt);
    }

  if (entry->the_bfd == NULL)
    {
      if (bfd_get_error () == bfd_error_invalid_target)
	einfo (_("%F%P: invalid BFD target `%s'\n"), entry->target);
      return FALSE;
    }

  /* If we are searching for this file, see if the architecture is
     compatible with the output file.  If it isn't, keep searching.
     If we can't open the file as an object file, stop the search
     here.  If we are statically linking, ensure that we don't link
     a dynamic object.  */

  if (entry->search_dirs_flag || !entry->dynamic)
    {
      bfd *check;

      if (bfd_check_format (entry->the_bfd, bfd_archive))
	check = bfd_openr_next_archived_file (entry->the_bfd, NULL);
      else
	check = entry->the_bfd;

      if (check != NULL)
	{
	  if (! bfd_check_format (check, bfd_object))
	    {
	      if (check == entry->the_bfd
		  && entry->search_dirs_flag
		  && bfd_get_error () == bfd_error_file_not_recognized
		  && ! ldemul_unrecognized_file (entry))
		{
		  int token, skip = 0;
		  char *arg, *arg1, *arg2, *arg3;
		  extern FILE *yyin;

		  /* Try to interpret the file as a linker script.  */
		  ldfile_open_command_file (attempt);

		  ldfile_assumed_script = TRUE;
		  parser_input = input_selected;
		  ldlex_both ();
		  token = INPUT_SCRIPT;
		  while (token != 0)
		    {
		      switch (token)
			{
			case OUTPUT_FORMAT:
			  if ((token = yylex ()) != '(')
			    continue;
			  if ((token = yylex ()) != NAME)
			    continue;
			  arg1 = yylval.name;
			  arg2 = NULL;
			  arg3 = NULL;
			  token = yylex ();
			  if (token == ',')
			    {
			      if ((token = yylex ()) != NAME)
				{
				  free (arg1);
				  continue;
				}
			      arg2 = yylval.name;
			      if ((token = yylex ()) != ','
				  || (token = yylex ()) != NAME)
				{
				  free (arg1);
				  free (arg2);
				  continue;
				}
			      arg3 = yylval.name;
			      token = yylex ();
			    }
			  if (token == ')')
			    {
			      switch (command_line.endian)
				{
				default:
				case ENDIAN_UNSET:
				  arg = arg1; break;
				case ENDIAN_BIG:
				  arg = arg2 ? arg2 : arg1; break;
				case ENDIAN_LITTLE:
				  arg = arg3 ? arg3 : arg1; break;
				}
			      if (strcmp (arg, lang_get_output_target ()) != 0)
				skip = 1;
			    }
			  free (arg1);
			  if (arg2) free (arg2);
			  if (arg3) free (arg3);
			  break;
			case NAME:
			case LNAME:
			case VERS_IDENTIFIER:
			case VERS_TAG:
			  free (yylval.name);
			  break;
			case INT:
			  if (yylval.bigint.str)
			    free (yylval.bigint.str);
			  break;
			}
		      token = yylex ();
		    }
		  ldlex_popstate ();
		  ldfile_assumed_script = FALSE;
		  fclose (yyin);
		  yyin = NULL;
		  if (skip)
		    {
		      if (command_line.warn_search_mismatch)
			einfo (_("%P: skipping incompatible %s "
				 "when searching for %s\n"),
			       attempt, entry->local_sym_name);
		      bfd_close (entry->the_bfd);
		      entry->the_bfd = NULL;
		      return FALSE;
		    }
		}
	      return TRUE;
	    }

	  if (!entry->dynamic && (entry->the_bfd->flags & DYNAMIC) != 0)
	    {
	      einfo (_("%F%P: attempted static link of dynamic object `%s'\n"),
		     attempt);
	      bfd_close (entry->the_bfd);
	      entry->the_bfd = NULL;
	      return FALSE;
	    }

	  if (entry->search_dirs_flag
	      && !bfd_arch_get_compatible (check, link_info.output_bfd,
					   command_line.accept_unknown_input_arch)
	      /* XCOFF archives can have 32 and 64 bit objects.  */
	      && ! (bfd_get_flavour (check) == bfd_target_xcoff_flavour
		    && bfd_get_flavour (link_info.output_bfd) == bfd_target_xcoff_flavour
		    && bfd_check_format (entry->the_bfd, bfd_archive)))
	    {
	      if (command_line.warn_search_mismatch)
		einfo (_("%P: skipping incompatible %s "
			 "when searching for %s\n"),
		       attempt, entry->local_sym_name);
	      bfd_close (entry->the_bfd);
	      entry->the_bfd = NULL;
	      return FALSE;
	    }
	}
    }

  return TRUE;
}
示例#13
0
文件: libcxl.c 项目: e-shannon/pslse
static int _pslse_connect(uint16_t * afu_map, int *fd)
{
	FILE *fp;
	uint8_t buffer[MAX_LINE_CHARS];
	struct sockaddr_in ssadr;
	struct hostent *he;
	char *host, *port_str;
	int port;

	// Get hostname and port of PSLSE server
	DPRINTF("AFU CONNECT\n");
	fp = fopen("pslse_server.dat", "r");
	if (!fp) {
		perror("fopen:pslse_server.dat");
		goto connect_fail;
	}
	do {
		if (fgets((char *)buffer, MAX_LINE_CHARS - 1, fp) == NULL) {
			perror("fgets:pslse_server.dat");
			fclose(fp);
			goto connect_fail;
		}
	}
	while (buffer[0] == '#');
	fclose(fp);
	host = (char *)buffer;
	port_str = strchr((char *)buffer, ':');
	*port_str = '\0';
	port_str++;
	if (!host || !port_str) {
		warn_msg
		    ("cxl_afu_open_dev:Invalid format in pslse_server.data");
		goto connect_fail;
	}
	port = atoi(port_str);

	info_msg("Connecting to host '%s' port %d", host, port);

	// Connect to PSLSE server
	if ((he = gethostbyname(host)) == NULL) {
		herror("gethostbyname");
		puts(host);
		goto connect_fail;
	}
	memset(&ssadr, 0, sizeof(ssadr));
	memcpy(&ssadr.sin_addr, he->h_addr_list[0], he->h_length);
	ssadr.sin_family = AF_INET;
	ssadr.sin_port = htons(port);
	if ((*fd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
		perror("socket");
		goto connect_fail;
	}
	ssadr.sin_family = AF_INET;
	ssadr.sin_port = htons(port);
	if (connect(*fd, (struct sockaddr *)&ssadr, sizeof(ssadr)) < 0) {
		perror("connect");
		goto connect_fail;
	}
	strcpy((char *)buffer, "PSLSE");
	buffer[5] = (uint8_t) PSLSE_VERSION_MAJOR;
	buffer[6] = (uint8_t) PSLSE_VERSION_MINOR;
	if (put_bytes_silent(*fd, 7, buffer) != 7) {
		warn_msg("cxl_afu_open_dev:Failed to write to socket!");
		goto connect_fail;
	}
	if (get_bytes_silent(*fd, 1, buffer, -1, 0) < 0) {
		warn_msg("cxl_afu_open_dev:Socket failed open acknowledge");
		close_socket(fd);
		goto connect_fail;
	}
	if (buffer[0] != (uint8_t) PSLSE_CONNECT) {
		warn_msg("cxl_afu_open_dev:PSLSE bad acknowledge");
		close_socket(fd);
		goto connect_fail;
	}
	if (get_bytes_silent(*fd, sizeof(uint16_t), buffer, 1000, 0) < 0) {
		warn_msg("cxl_afu_open_dev:afu_map");
		close_socket(fd);
		goto connect_fail;
	}
	memcpy((char *)afu_map, (char *)buffer, 2);
	*afu_map = (long)ntohs(*afu_map);
	return 0;

 connect_fail:
	errno = ENODEV;
	return -1;
}
示例#14
0
文件: libcxl.c 项目: e-shannon/pslse
static void *_psl_loop(void *ptr)
{
	struct cxl_afu_h *afu = (struct cxl_afu_h *)ptr;
	uint8_t buffer[MAX_LINE_CHARS];
	uint8_t size;
	uint64_t addr;
	uint16_t value;
	uint32_t lvalue;
	int rc;

	if (!afu)
		fatal_msg("NULL afu passed to libcxl.c:_psl_loop");
	afu->opened = 1;
	while (afu->opened) {
		_delay_1ms();
		// Send any requests to PSLSE over socket
		if (afu->int_req.state == LIBCXL_REQ_REQUEST)
			_req_max_int(afu);
		if (afu->attach.state == LIBCXL_REQ_REQUEST)
			_pslse_attach(afu);
		if (afu->mmio.state == LIBCXL_REQ_REQUEST) {
			switch (afu->mmio.type) {
			case PSLSE_MMIO_MAP:
				_mmio_map(afu);
				break;
			case PSLSE_MMIO_WRITE64:
				_mmio_write64(afu);
				break;
			case PSLSE_MMIO_WRITE32:
				_mmio_write32(afu);
				break;
			case PSLSE_MMIO_EBREAD:
			case PSLSE_MMIO_READ64:
			case PSLSE_MMIO_READ32:	/*fall through */
				_mmio_read(afu);
				break;
			default:
				break;
			}
		}
		// Process socket input from PSLSE
		rc = bytes_ready(afu->fd, 1000, 0);
		if (rc == 0)
			continue;
		if (rc < 0) {
			warn_msg("Socket failure testing bytes_ready");
			_all_idle(afu);
			break;
		}
		if (get_bytes_silent(afu->fd, 1, buffer, 1000, 0) < 0) {
			warn_msg("Socket failure getting PSL event");
			_all_idle(afu);
			break;
		}
		DPRINTF("PSL EVENT\n");
		switch (buffer[0]) {
		case PSLSE_OPEN:
			if (get_bytes_silent(afu->fd, 1, buffer, 1000, 0) < 0) {
				warn_msg("Socket failure getting OPEN context");
				_all_idle(afu);
				break;
			}
			afu->context = (uint16_t) buffer[0];
			afu->open.state = LIBCXL_REQ_IDLE;
			break;
		case PSLSE_ATTACH:
			afu->attach.state = LIBCXL_REQ_IDLE;
			break;
		case PSLSE_DETACH:
		        info_msg("detach response from from pslse");
			afu->mapped = 0;
			afu->attached = 0;
			afu->opened = 0;
			afu->open.state = LIBCXL_REQ_IDLE;
			afu->attach.state = LIBCXL_REQ_IDLE;
			afu->mmio.state = LIBCXL_REQ_IDLE;
			afu->int_req.state = LIBCXL_REQ_IDLE;
			break;
		case PSLSE_MAX_INT:
			size = sizeof(uint16_t);
			if (get_bytes_silent(afu->fd, size, buffer, 1000, 0) <
			    0) {
				warn_msg
				    ("Socket failure getting max interrupt acknowledge");
				_all_idle(afu);
				break;
			}
			memcpy((char *)&value, (char *)buffer,
			       sizeof(uint16_t));
			afu->irqs_max = ntohs(value);
			afu->int_req.state = LIBCXL_REQ_IDLE;
			break;
		case PSLSE_QUERY: {
			size = sizeof(uint16_t) + sizeof(uint16_t) + sizeof(uint16_t) +
			    sizeof(uint64_t) + sizeof(uint64_t) + sizeof(uint64_t) +  
                            sizeof(uint16_t) + sizeof(uint16_t) + sizeof(uint32_t);
			if (get_bytes_silent(afu->fd, size, buffer, 1000, 0) <
			    0) {
				warn_msg("Socket failure getting PSLSE query");
				_all_idle(afu);
				break;
			}
			memcpy((char *)&value, (char *)&(buffer[0]), 2);
			afu->irqs_min = (long)(value);
			memcpy((char *)&value, (char *)&(buffer[2]), 2);
			afu->irqs_max = (long)(value);
                	memcpy((char *)&value, (char *)&(buffer[4]), 2);
			afu->modes_supported = (long)(value);
                	memcpy((char *)&value, (char *)&(buffer[6]), 8);
			afu->mmio_len = (long)(value);
                	memcpy((char *)&value, (char *)&(buffer[14]), 8);
			afu->mmio_off = (long)(value);
                	memcpy((char *)&value, (char *)&(buffer[22]), 8);
			//afu->eb_len = (long)ntohll(value);
			afu->eb_len = (long)(value);
                	memcpy((char *)&value, (char *)&(buffer[30]), 2);
			afu->cr_device = (long)ntohs(value);
                        memcpy((char *)&value, (char *)&(buffer[32]), 2);
			afu->cr_vendor = (long)ntohs(value);
                        memcpy((char *)&lvalue, (char *)&(buffer[34]), 4);
			afu->cr_class = ntohl(lvalue);
			//no better place to put this right now
			afu->prefault_mode = CXL_PREFAULT_MODE_NONE;
			break;
		}
		case PSLSE_MEMORY_READ:
			DPRINTF("AFU MEMORY READ\n");
			if (get_bytes_silent(afu->fd, 1, buffer, 1000, 0) < 0) {
				warn_msg
				    ("Socket failure getting memory read size");
				_all_idle(afu);
				break;
			}
			size = (uint8_t) buffer[0];
			if (get_bytes_silent(afu->fd, sizeof(uint64_t), buffer,
					     -1, 0) < 0) {
				warn_msg
				    ("Socket failure getting memory read addr");
				_all_idle(afu);
				break;
			}
			memcpy((char *)&addr, (char *)buffer, sizeof(uint64_t));
			addr = ntohll(addr);
			_handle_read(afu, addr, size);
			break;
		case PSLSE_MEMORY_WRITE:
			DPRINTF("AFU MEMORY WRITE\n");
			if (get_bytes_silent(afu->fd, 1, buffer, 1000, 0) < 0) {
				warn_msg
				    ("Socket failure getting memory write size");
				_all_idle(afu);
				break;
			}
			size = (uint8_t) buffer[0];
			if (get_bytes_silent(afu->fd, sizeof(uint64_t), buffer,
					     -1, 0) < 0) {
				_all_idle(afu);
				break;
			}
			memcpy((char *)&addr, (char *)buffer, sizeof(uint64_t));
			addr = ntohll(addr);
			if (get_bytes_silent(afu->fd, size, buffer, 1000, 0) <
			    0) {
				warn_msg
				    ("Socket failure getting memory write data");
				_all_idle(afu);
				break;
			}
			_handle_write(afu, addr, size, buffer);
			break;
		case PSLSE_MEMORY_TOUCH:
			DPRINTF("AFU MEMORY TOUCH\n");
			if (get_bytes_silent(afu->fd, 1, buffer, 1000, 0) < 0) {
				warn_msg
				    ("Socket failure getting memory touch size");
				_all_idle(afu);
				break;
			}
			size = buffer[0];
			if (get_bytes_silent(afu->fd, sizeof(uint64_t), buffer,
					     -1, 0) < 0) {
				warn_msg
				    ("Socket failure getting memory touch addr");
				_all_idle(afu);
				break;
			}
			memcpy((char *)&addr, (char *)buffer, sizeof(uint64_t));
			addr = ntohll(addr);
			_handle_touch(afu, addr, size);
			break;
		case PSLSE_MMIO_ACK:
			_handle_ack(afu);
			break;
		case PSLSE_INTERRUPT:
			if (_handle_interrupt(afu) < 0) {
				perror("Interrupt Failure");
				goto psl_fail;
			}
			break;
		case PSLSE_AFU_ERROR:
			if (_handle_afu_error(afu) < 0) {
				perror("AFU ERROR Failure");
				goto psl_fail;
			}
			break;
		default:
			break;
		}
	}

 psl_fail:
	afu->attached = 0;
	pthread_exit(NULL);
}
示例#15
0
文件: psl.c 项目: ibm-capi/pslse
// Attach to AFU
static void _attach(struct psl *psl, struct client *client)
{
	uint64_t wed;
	uint8_t ack;
	uint8_t buffer[MAX_LINE_CHARS];
	size_t size;

	// FIXME: This only works for dedicate mode
	// might work for afu-directed now - lgt

	// Get wed value from application
	// always do the get
        // pass the wed only for dedicated
	ack = PSLSE_DETACH;
	size = sizeof(uint64_t);
	if (get_bytes_silent(client->fd, size, buffer, psl->timeout,
			     &(client->abort)) < 0) {
	  warn_msg("Failed to get WED value from client");
	  client_drop(client, PSL_IDLE_CYCLES, CLIENT_NONE);
	  goto attach_done;
	}

	// but need to save wed if master|slave for future consumption
	// interestingly, I can always save it
	// add to client type.
	memcpy((char *)&wed, (char *)buffer, sizeof(uint64_t));
	// wed came over in be format
	// since we are modeling the psl register here, we should leave it be
#if defined PSL9lite || defined PSL9
	client->wed = wed; // ntohll(wed);
#else
	client->wed = ntohll(wed);
#endif 

	// Send start to AFU
	// only add PSL_JOB_START for dedicated and master clients.
	// send an empty wed in the case of master
	// lgt - new idea:
	// track number of clients in psl
	// if number of clients = 0, then add the start job
	// add llcmd add to client  (loop through clients in send_com)
	// increment number of clients (decrement where we handle the completion of the detach)
	switch (client->type) {
	case 'd':
	  if (psl->attached_clients == 0) {
	    if (add_job(psl->job, PSL_JOB_START, client->wed) != NULL) {
	      // if dedicated, we can ack PSLSE_ATTACH
	      // if master, we might want to wait until after the llcmd add is complete
	      // can I wait here for the START to finish?
	      psl->idle_cycles = PSL_IDLE_CYCLES;
	      ack = PSLSE_ATTACH;
	    }
	  }
	  break;
	case 'm':
	case 's':
	  if (psl->attached_clients < psl->max_clients) {
	    if (psl->attached_clients == 0) {
	      if (add_job(psl->job, PSL_JOB_START, 0L) != NULL) {
		// if master, we might want to wait until after the llcmd add is complete
		// can I wait here for the START to finish?
	      }
	    }
	    psl->idle_cycles = PSL_IDLE_CYCLES;
	    ack = PSLSE_ATTACH;
	  }
	  // running will be set by send/handle_aux2 routines
	  break;
	default:
	  // error?
	  break;
	}

	psl->attached_clients++;
	info_msg( "Attached client context %d: current attached clients = %d: client type = %c\n", client->context, psl->attached_clients, client->type );
	
	// for master and slave send llcmd add
        // master "wed" is 0x0005000000000000 can actually use client->context here as well since context = 0
	// slave "wed" is 0x000500000000hhhh where hhhh is the "handle" from client->context
	// now - about those llcmds :-)
	// put these in a separate list associated with the job?  psl->pe maybe...  or another call to add_job?
	// new routine to job.c?  add_cmd?
	// should a slave know their master?
	if (client->type == 'm' || client->type == 's') {
	        wed = PSL_LLCMD_ADD;
		wed = wed | (uint64_t)client->context;
		// add_pe adds to the client
	        if (add_pe(psl->job, PSL_JOB_LLCMD, wed) != NULL) {
		}
	}

 attach_done:
	if (put_bytes(client->fd, 1, &ack, psl->dbg_fp, psl->dbg_id,
		      client->context) < 0) {
		client_drop(client, PSL_IDLE_CYCLES, CLIENT_NONE);
	}
}
示例#16
0
文件: psl.c 项目: ibm-capi/pslse
// PSL thread loop
static void *_psl_loop(void *ptr)
{
	struct psl *psl = (struct psl *)ptr;
	struct cmd_event *event, *temp;
	int events, i, stopped, reset;
	uint8_t ack = PSLSE_DETACH;

	stopped = 1;
	pthread_mutex_lock(psl->lock);
	while (psl->state != PSLSE_DONE) {
		// idle_cycles continues to generate clock cycles for some
		// time after the AFU has gone idle.  Eventually clocks will
		// not be presented to an idle AFU to keep simulation
		// waveforms from getting huge with no activity cycles.
		if (psl->state != PSLSE_IDLE) {
		  // if we have clients or we are in the reset state, refresh idle_cycles 
		  // so that the afu clock will not be allowed to stop to save afu event simulator cycles
		  if ((psl->attached_clients > 0) || (psl->state == PSLSE_RESET)) {
			psl->idle_cycles = PSL_IDLE_CYCLES;
			if (stopped)
				info_msg("Clocking %s", psl->name);
			fflush(stdout);
			stopped = 0;
		  }
		}
		if (psl->idle_cycles) {
			// Clock AFU
//printf("before psl_signal_afu_model in psl_loop \n");
			psl_signal_afu_model(psl->afu_event);
			// Check for events from AFU
			events = psl_get_afu_events(psl->afu_event);
//printf("after psl_get_afu_events, events is 0x%3x \n", events);
			// Error on socket
			if (events < 0) {
				warn_msg("Lost connection with AFU");
				break;
			}
			// Handle events from AFU
			if (events > 0)
				_handle_afu(psl);

			// Drive events to AFU
			send_job(psl->job);
			send_pe(psl->job);
			send_mmio(psl->mmio);

			if (psl->mmio->list == NULL)
				psl->idle_cycles--;
		} else {
			if (!stopped)
				info_msg("Stopping clocks to %s", psl->name);
			stopped = 1;
			lock_delay(psl->lock);
		}

		// Skip client section if AFU descriptor hasn't been read yet
		if (psl->client == NULL) {
			lock_delay(psl->lock);
			continue;
		}
		// Check for event from application
		reset = 0;
		for (i = 0; i < psl->max_clients; i++) {
			if (psl->client[i] == NULL)
				continue;
			if ((psl->client[i]->type == 'd') && 
			    (psl->client[i]->state == CLIENT_NONE) &&
			    (psl->client[i]->idle_cycles == 0)) {
			        // this was the old way of detaching a dedicated process app/afu pair
			        // we get the detach message, drop the client, and wait for idle cycle to get to 0
				put_bytes(psl->client[i]->fd, 1, &ack,
					  psl->dbg_fp, psl->dbg_id,
					  psl->client[i]->context);
				_free(psl, psl->client[i]);
				psl->client[i] = NULL;  // aha - this is how we only called _free once the old way
				                        // why do we not free client[i]?
				                        // because this was a short cut pointer
				                        // the *real* client point is in client_list in pslse
				reset = 1;
				// for m/s devices we need to do this differently and not send a reset...
				// _handle_client - creates the llcmd's to term and remove
				// send_pe - sends the llcmd pe's to afu one at a time
				// _handle_afu calls _handle_aux2
				// _handle_aux2 finishes the llcmd pe's when jcack is asserted by afu
				//   when the remove llcmd is processed, we should put_bytes, _free and set client[i] to NULL
				continue;
			}
			if (psl->state == PSLSE_RESET)
				continue;
			_handle_client(psl, psl->client[i]);
			if (psl->client[i]->idle_cycles) {
				psl->client[i]->idle_cycles--;
			}
			if (client_cmd(psl->cmd, psl->client[i])) {
				psl->client[i]->idle_cycles = PSL_IDLE_CYCLES;
			}
		}

		// Send reset to AFU
		if (reset == 1) {
			psl->cmd->buffer_read = NULL;
			event = psl->cmd->list;
			while (event != NULL) {
				if (reset) {
					warn_msg
					    ("Client dropped context before AFU completed");
					reset = 0;
				}
				info_msg("Dumping command tag=0x%02x",
					 event->tag);
#ifdef PSL9
				info_msg("Dumping itag=0x%02x utag=0x%02x type=0x%02x state=0x%02x",
					event->itag, event->utag, event->type, event->state);
#endif
				if (event->data) {
					free(event->data);
				}
				if (event->parity) {
					free(event->parity);
				}
				temp = event;
				event = event->_next;
				free(temp);
			}
			psl->cmd->list = NULL;
			info_msg("Sending reset to AFU");
			add_job(psl->job, PSL_JOB_RESET, 0L);
		}

		lock_delay(psl->lock);
	}

	// Disconnect clients
	for (i = 0; i < psl->max_clients; i++) {
		if ((psl->client != NULL) && (psl->client[i] != NULL)) {
			// FIXME: Send warning to clients first?
			info_msg("Disconnecting %s context %d", psl->name,
				 psl->client[i]->context);
			close_socket(&(psl->client[i]->fd));
		}
	}

	// DEBUG
	debug_afu_drop(psl->dbg_fp, psl->dbg_id);

	// Disconnect from simulator, free memory and shut down thread
	info_msg("Disconnecting %s @ %s:%d", psl->name, psl->host, psl->port);
	if (psl->client)
		free(psl->client);
	if (psl->_prev)
		psl->_prev->_next = psl->_next;
	if (psl->_next)
		psl->_next->_prev = psl->_prev;
	if (psl->cmd) {
		free(psl->cmd);
	}
	if (psl->job) {
		free(psl->job);
	}
	if (psl->mmio) {
		free(psl->mmio);
	}
	if (psl->host)
		free(psl->host);
	if (psl->afu_event) {
		psl_close_afu_event(psl->afu_event);
		free(psl->afu_event);
	}
	if (psl->name)
		free(psl->name);
	if (*(psl->head) == psl)
		*(psl->head) = psl->_next;
	pthread_mutex_unlock(psl->lock);
	free(psl);
	pthread_exit(NULL);
}