Ejemplo n.º 1
0
static void free_finished_channel(void)
{
	//int i;
  CCHANNEL *ch;
	char channel;

	if (read(_pipe[0], &channel, 1) != 1)
		return;

	ch = _cache[(int)channel];
	if (ch)
	{
		if (ch->free)
			free_channel(ch);
		//fprintf(stderr, "raise finish %d\n", (int)channel);
		GB.Raise(ch, EVENT_Finish, 0);
	}

	/*for (i = 0; i < MAX_CHANNEL; i++)
	{
		ch = channel_cache[i];
		if (ch && ch->free)
			free_channel(ch);
	}*/
}
Ejemplo n.º 2
0
void al_stream_update()
{
	int   processed;
	ALint state;

	if ( source_handle == -1 )
	{
		return;
	}

	// Un-queue any buffers, and delete them
	qalGetSourcei( source, AL_BUFFERS_PROCESSED, &processed );

	if ( processed )
	{
		while ( processed-- )
		{
			ALuint buffer;
			qalSourceUnqueueBuffers( source, 1, &buffer );
			qalDeleteBuffers( 1, &buffer );
		}
	}

	// If it's stopped, release the source
	qalGetSourcei( source, AL_SOURCE_STATE, &state );

	if ( state == AL_STOPPED )
	{
		is_playing = qfalse;
		qalSourceStop( source );
		free_channel();
	}
}
Ejemplo n.º 3
0
HRESULT create_channel( WS_CHANNEL_TYPE type, WS_CHANNEL_BINDING binding,
                        const WS_CHANNEL_PROPERTY *properties, ULONG count, struct channel **ret )
{
    struct channel *channel;
    ULONG i, msg_size = 65536;
    HRESULT hr;

    if (!(channel = alloc_channel())) return E_OUTOFMEMORY;

    prop_set( channel->prop, channel->prop_count, WS_CHANNEL_PROPERTY_MAX_BUFFERED_MESSAGE_SIZE,
              &msg_size, sizeof(msg_size) );

    for (i = 0; i < count; i++)
    {
        hr = prop_set( channel->prop, channel->prop_count, properties[i].id, properties[i].value,
                       properties[i].valueSize );
        if (hr != S_OK)
        {
            free_channel( channel );
            return hr;
        }
    }

    channel->type    = type;
    channel->binding = binding;

    *ret = channel;
    return S_OK;
}
Ejemplo n.º 4
0
/*
**	When deleting a channel we first look at if there are no more requests
**	using the channel (the semaphore is <= 0). Then, if the socket supports
**	persistent connections then we register the channel in the Host cache
**	and wait until the other end closes it or we get a time out on our side
*/
PUBLIC BOOL HTChannel_delete (HTChannel * channel, int status)
{
    if (channel) {
        HTTRACE(PROT_TRACE, "Channel..... Delete %p with semaphore %d, status %d\n" _
                channel _ channel->semaphore _ status);
        /*
        **  We call the free methods on both the input stream and the output
        **  stream so that we can free up the stream pipes. However, note that
        **  this doesn't mean that we close the input stream and output stream
        **  them selves - only the generic streams
        */
        HTChannel_deleteInput(channel, status);
        HTChannel_deleteOutput(channel, status);

        /*
        **  Check whether this channel is used by other objects or we can
        **  delete it and free memory.
        */
        if (channel->semaphore <= 0 && channels && (
                    channel->sockfd != INVSOC || channel->fp != NULL)) {
            int hash = HASH(channel->sockfd);
            HTList * list = channels[hash];
            if (list) {
                HTList_removeObject(list, (void *) channel);
                free_channel(channel);
                return YES;
            }
        } else
            HTChannel_downSemaphore(channel);
    }
    return NO;
}
Ejemplo n.º 5
0
/**************************************************************************
 *          WsCreateServiceProxy		[webservices.@]
 */
HRESULT WINAPI WsCreateServiceProxy( const WS_CHANNEL_TYPE type, const WS_CHANNEL_BINDING binding,
                                     const WS_SECURITY_DESCRIPTION *desc,
                                     const WS_PROXY_PROPERTY *proxy_props, ULONG proxy_props_count,
                                     const WS_CHANNEL_PROPERTY *channel_props,
                                     const ULONG channel_props_count, WS_SERVICE_PROXY **handle,
                                     WS_ERROR *error )
{
    struct channel *channel;
    HRESULT hr;

    TRACE( "%u %u %p %p %u %p %u %p %p\n", type, binding, desc, proxy_props, proxy_props_count,
           channel_props, channel_props_count, handle, error );
    if (error) FIXME( "ignoring error parameter\n" );
    if (desc) FIXME( "ignoring security description\n" );

    if (!handle) return E_INVALIDARG;

    if ((hr = create_channel( type, binding, channel_props, channel_props_count, &channel )) != S_OK)
        return hr;

    if ((hr = create_proxy( channel, proxy_props, proxy_props_count, handle )) != S_OK)
        free_channel( channel );

    return hr;
}
Ejemplo n.º 6
0
/**************************************************************************
 *          WsFreeChannel		[webservices.@]
 */
void WINAPI WsFreeChannel( WS_CHANNEL *handle )
{
    struct channel *channel = (struct channel *)handle;

    TRACE( "%p\n", handle );
    free_channel( channel );
}
Ejemplo n.º 7
0
static void return_channel(int channel, CSOUND *sound)
{
  CCHANNEL *ch = NULL;

  if (channel < 0 || channel >= channel_count)
  {
		if (sound)
			GB.Unref(POINTER(&sound));

		GB.ReturnNull();
    return;
  }

  ch = channel_cache[channel];
  if (!ch)
  {
    ch = GB.New(GB.FindClass("Channel"), NULL, NULL);
    channel_cache[channel] = ch;
    ch->channel = channel;
    GB.Ref(ch);
  }

	free_channel(ch);
  if (sound)
    ch->sound = sound;

  GB.ReturnObject(ch);
}
Ejemplo n.º 8
0
void CHANNEL_exit()
{
	int i;
	CCHANNEL *ch;

	Mix_HaltChannel(-1);

	for (i = 0; i < MAX_CHANNEL; i++)
	{
		ch = _cache[i];
		if (!ch)
			continue;

		free_channel(ch);
		GB.Unref(POINTER(&ch));
	}

	if (_pipe_usage)
	{
		GB.Watch(_pipe[0], GB_WATCH_NONE, NULL, 0);
		_pipe_usage = 0;
	}

	close(_pipe[0]);
	close(_pipe[1]);
}
Ejemplo n.º 9
0
static struct iio_channel * create_channel(struct iio_device *dev, xmlNode *n)
{
	xmlAttr *attr;
	struct iio_channel *chn = zalloc(sizeof(*chn));
	if (!chn)
		return NULL;

	chn->dev = dev;

	/* Set the default index value < 0 (== no index) */
	chn->index = -ENOENT;

	for (attr = n->properties; attr; attr = attr->next) {
		const char *name = (const char *) attr->name,
		      *content = (const char *) attr->children->content;
		if (!strcmp(name, "name")) {
			chn->name = iio_strdup(content);
		} else if (!strcmp(name, "id")) {
			chn->id = iio_strdup(content);
		} else if (!strcmp(name, "type")) {
			if (!strcmp(content, "output"))
				chn->is_output = true;
			else if (strcmp(content, "input"))
				WARNING("Unknown channel type %s\n", content);
		} else {
			WARNING("Unknown attribute \'%s\' in <channel>\n",
					name);
		}
	}

	if (!chn->id) {
		ERROR("Incomplete <attribute>\n");
		goto err_free_channel;
	}

	for (n = n->children; n; n = n->next) {
		if (!strcmp((char *) n->name, "attribute")) {
			if (add_attr_to_channel(chn, n) < 0)
				goto err_free_channel;
		} else if (!strcmp((char *) n->name, "scan-element")) {
			chn->is_scan_element = true;
			setup_scan_element(chn, n);
		} else if (strcmp((char *) n->name, "text")) {
			WARNING("Unknown children \'%s\' in <channel>\n",
					n->name);
			continue;
		}
	}

	iio_channel_init_finalize(chn);

	return chn;

err_free_channel:
	free_channel(chn);
	return NULL;
}
Ejemplo n.º 10
0
void			free_client(t_client *client)
{
  close(client->fd);
  free(client->nick);
  free(client->user);
  free(client->real_name);
  free_channel(client->channel);
  free(client);
}
Ejemplo n.º 11
0
/**************************************************************************
 *          WsCreateServiceProxyFromTemplate		[webservices.@]
 */
HRESULT WINAPI WsCreateServiceProxyFromTemplate( WS_CHANNEL_TYPE channel_type,
                                                 const WS_PROXY_PROPERTY *properties, const ULONG count,
                                                 WS_BINDING_TEMPLATE_TYPE type, void *value, ULONG size,
                                                 const void *desc, ULONG desc_size, WS_SERVICE_PROXY **handle,
                                                 WS_ERROR *error )
{
    const WS_CHANNEL_PROPERTY *channel_props = NULL;
    ULONG channel_props_count = 0;
    WS_CHANNEL_BINDING binding;
    struct channel *channel;
    HRESULT hr;

    TRACE( "%u %p %u %u %p %u %p %u %p %p\n", channel_type, properties, count, type, value, size, desc,
           desc_size, handle, error );
    if (error) FIXME( "ignoring error parameter\n" );

    if (!desc || !handle) return E_INVALIDARG;
    FIXME( "ignoring description\n" );

    switch (type)
    {
    case WS_HTTP_BINDING_TEMPLATE_TYPE:
    {
        WS_HTTP_BINDING_TEMPLATE *http = value;
        if (http)
        {
            channel_props = http->channelProperties.properties;
            channel_props_count = http->channelProperties.propertyCount;
        }
        binding = WS_HTTP_CHANNEL_BINDING;
        break;
    }
    case WS_HTTP_SSL_BINDING_TEMPLATE_TYPE:
    {
        WS_HTTP_SSL_BINDING_TEMPLATE *https = value;
        if (https)
        {
            channel_props = https->channelProperties.properties;
            channel_props_count = https->channelProperties.propertyCount;
        }
        binding = WS_HTTP_CHANNEL_BINDING;
        break;
    }
    default:
        FIXME( "template type %u not implemented\n", type );
        return E_NOTIMPL;
    }

    if ((hr = create_channel( channel_type, binding, channel_props, channel_props_count, &channel )) != S_OK)
        return hr;

    if ((hr = create_proxy( channel, properties, count, handle )) != S_OK)
        free_channel( channel );

    return hr;
}
Ejemplo n.º 12
0
static void
rmuser(struct user *usr, struct channel *chan)
{

        list_remove(usr, &chan->users);
        if (SLIST_EMPTY(&chan->users)) {
                table_del(channels, chan->name, chan->len);
                free_channel(chan);
        }
}
Ejemplo n.º 13
0
void al_stream_die()
{
	if ( source_handle == -1 )
	{
		return;
	}

	is_playing = qfalse;
	qalSourceStop( source );
	free_channel();
}
Ejemplo n.º 14
0
static void
free_server(server *s)
{
	channel *t, *c = s->channel;

	do {
		t = c;
		c = c->next;
		free_channel(t);
	} while (c != s->channel);

	free(s->host);
	free(s->port);
	free(s);
}
Ejemplo n.º 15
0
static void free_finished_channels(void)
{
	int i;
  CCHANNEL *ch;
	char foo;
	
	if (read(_ch_pipe[0], &foo, 1) != 1)
		return;
	
	for (i = 0; i < MAX_CHANNEL; i++)
	{
		ch = channel_cache[i];
		if (ch && ch->free)
			free_channel(ch);
	}
}
Ejemplo n.º 16
0
/*	HTChannel_deleteAll
**	-------------------
**	Destroys all channels. This is called by HTLibTerminate(0
*/
PUBLIC BOOL HTChannel_deleteAll (void)
{
    if (channels) {
        HTList * cur;
        int cnt;
        for (cnt=0; cnt<HT_M_HASH_SIZE; cnt++) {
            if ((cur = channels[cnt])) {
                HTChannel * pres;
                while ((pres = (HTChannel *) HTList_nextObject(cur)) != NULL)
                    free_channel(pres);
            }
            HTList_delete(channels[cnt]);
        }
        HT_FREE(channels);
    }
    return YES;
}
Ejemplo n.º 17
0
void free_device(struct iio_device *dev)
{
	unsigned int i;
	for (i = 0; i < dev->nb_attrs; i++)
		free(dev->attrs[i]);
	if (dev->nb_attrs)
		free(dev->attrs);
	for (i = 0; i < dev->nb_debug_attrs; i++)
		free(dev->debug_attrs[i]);
	if (dev->nb_debug_attrs)
		free(dev->debug_attrs);
	for (i = 0; i < dev->nb_channels; i++)
		free_channel(dev->channels[i]);
	if (dev->nb_channels)
		free(dev->channels);
	if (dev->mask)
		free(dev->mask);
	if (dev->name)
		free(dev->name);
	if (dev->id)
		free(dev->id);
	free(dev);
}
Ejemplo n.º 18
0
void free_image(motion_image image) {
  free_channel(image.red);
  free_channel(image.green);
  free_channel(image.blue);
  free_channel(image.average);
}
Ejemplo n.º 19
0
int xor_mv(unsigned int src_no, unsigned int bytes, void **bh_ptr)
{
	void *bptr = NULL;
	int i;
        u32      *srcAddr;
        int         chan;
        struct xor_channel_t *channel;

	if(src_no <= 1)
	{
		printk(KERN_ERR "%s: need more than 1 src for XOR\n",
			__func__);
		BUG();
                return bytes;
	}
        if (xor_engine_initialized == 0)
        {
            printk(KERN_WARNING" %s: xor engines not initialized yet\n", __func__);
            return bytes;
        }

        chan = allocate_channel();
        if ( chan == -1)
         {
                DPRINTK("XOR engines are busy, return\n");
                return bytes;
        }
	DPRINTK("setting up rest of descriptor for channel %d\n", chan);
        channel = &xor_channel[chan];
	// flush the cache to memory before XOR engine touches them
        srcAddr = &(channel->pDescriptor->srcAdd0);
	for(i = src_no-1; i >= 0; i--)
	{
		DPRINTK("flushing source %d\n", i);
		bptr = (bh_ptr[i]);
		/* Buffer 0 is also the destination */
		if(i==0)
			dmac_flush_range(bptr,
					 bptr + bytes);			
		else
			dmac_clean_range(bptr,
					 bptr + bytes);
                srcAddr[i] = virt_to_phys(bh_ptr[i]);
	}

	channel->pDescriptor->phyDestAdd = virt_to_phys(bh_ptr[0]);
        channel->pDescriptor->byteCnt = bytes;
        channel->pDescriptor->phyNextDescPtr = 0;
        channel->pDescriptor->descCommand = (1 << src_no) - 1;
        channel->pDescriptor->status = BIT31;
	channel->chan_active = 1;
        if( mvXorTransfer(chan, MV_XOR, channel->descPhyAddr) != MV_OK )
        {
            printk(KERN_ERR "%s: XOR operation on channel %d failed!\n", __func__, chan);
            print_xor_regs(chan);
            BUG();
            free_channel(channel);
            return bytes;
        }
#ifdef CONFIG_ENABLE_XOR_INTERRUPTS
        wait_event(channel->waitq, (( channel->pDescriptor->status & BIT31) == 0));/*TODO add timeout*/
#else
        xor_waiton_eng(chan);
#endif
	DPRINTK("XOR complete\n");
#if 0
	if (!(channel->pDescriptor->status & BIT30)) {
	    printk(KERN_ERR "%s: XOR operation completed with error!\n", __func__);
            print_xor_regs(chan);            
	    BUG();
            free_channel(channel);
	    return MV_REG_READ(XOR_BYTE_COUNT_REG(chan));
        }
#endif
	DPRINTK("invalidate result in cache\n");
#if 0
	// invalidate the cache region to destination
        bptr = (bh_ptr[0]);
	dmac_inv_range(bptr, bptr + bytes);
#endif
        free_channel(channel);
        xor_hit++;
        return 0;
}
Ejemplo n.º 20
0
/* load the predefined channels */
void load_channels(void)
{
    char    path[_POSIX_PATH_MAX], *name, *slimit, *slevel, *topic, *ptr;
    char    realname[256];
    int     fd;
    int     limit, level, line = 0;
    CHANNEL *chan;
    int     version = 0;

    snprintf(path, sizeof(path), "%s/channels", global.varDir);

    if((fd = open(path, O_RDONLY))==-1)
    {
        if(errno != ENOENT)
            logerr("load_channels", path);
        return;
    }
    if(fake_fgets(Buf, sizeof(Buf), fd) == NULL)
    {
        close(fd);
        return;
    }
    if(!strncmp(":version 1", Buf, 10))
        version = 1;
    else
        lseek(fd, 0, SEEK_SET);

    while (fake_fgets(Buf, sizeof(Buf), fd))
    {
        line++;
        ptr = Buf;
        while (ISSPACE(*ptr))
            ptr++;
        if(*ptr == 0 || (version == 0 && *ptr == '#'))
            continue;       /* blank or comment line */
        name = next_arg(&ptr);
        slimit = next_arg(&ptr);
        slevel = next_arg(&ptr);
        topic = next_arg(&ptr);
        if(!name || !slimit || !slevel || !topic)
        {
            log_message_level(LOG_LEVEL_ERROR, "load_channels: %s:%d: too few parameters", path, line);
            continue;
        }
        /* force new channel name restrictions */
        if(option(ON_IRC_CHANNELS) && *name != '#' && *name != '&')
        {
            snprintf(realname, sizeof(realname), "#%s", name);
            name = realname;
        }
        if(invalid_channel(name))
        {
            log_message_level(LOG_LEVEL_ERROR, "load_channels: %s:%d: %s: invalid channel name", name);
            continue;
        }
        level = get_level(slevel);
        if(level == -1)
        {
            log_message_level(LOG_LEVEL_ERROR, "load_channels: %s:%d: %s: invalid level", path, line, slevel);
            continue;
        }
        limit = atoi(slimit);
        if(limit < 0 || limit > 65535)
        {
            log_message_level(LOG_LEVEL_ERROR, "load_channels: %s:%d: %d: invalid limit", path, line, limit);
            continue;
        }
        chan = hash_lookup(global.channelHash, name);
        if(chan)
        {
            log_message_level(LOG_LEVEL_ERROR, "load_channels: %s:%d: %s is already defined", path, line, name);
            continue;
        }
        chan = new_channel();
        if(chan)
        {
            chan->name = STRDUP(name);
            chan->topic = STRDUP(topic);
            chan->limit = limit;
            chan->level = level;
            chan->flags = ON_CHANNEL_REGISTERED;
            chan->timestamp = global.current_time;
        }
        if(hash_add(global.channelHash, chan->name, chan))
            free_channel(chan);
    }
    close(fd);
}
Ejemplo n.º 21
0
/*=======================================================================*/
void *xor_memcpy(void *to, const void *from, __kernel_size_t n)
{
	u32 xor_dma_unaligned_to, xor_dma_unaligned_from;
	void *orig_to = to;
	u32 to_pa, from_pa;
        int ua = 0;
        int         chan;
        struct xor_channel_t *channel;

	DPRINTK("xor_memcpy(0x%x, 0x%x, %lu): entering\n", (u32) to, (u32) from,
		(unsigned long)n);

        if (xor_engine_initialized == 0)
        {
            DPRINTK(KERN_WARNING" %s: xor engines not initialized yet\n", __func__);
       	    xor_dma_miss++;
	    return asm_memmove(to, from, n);
        }
 	if (!(virt_addr_valid((u32) to) && virt_addr_valid((u32) from))) {
		DPRINTK("xor_memcpy(0x%x, 0x%x, %lu): falling back to memcpy\n",
			(u32) to, (u32) from, (unsigned long)n);
		xor_dma_miss++;
		return asm_memmove(to, from, n);
	}

	/*
	 * We can only handled completely cache-aligned transactions
	 * with the DMA engine.  Source and Dst must be cache-line
	 * aligned AND the length must be a multiple of the cache-line.
	 */

	to_pa = virt_to_phys(to);
	from_pa = virt_to_phys((void*)from);

	if (((to_pa + n > from_pa) && (to_pa < from_pa)) ||
	    ((from_pa < to_pa) && (from_pa + n > to_pa))) {
		DPRINTK("overlapping copy region (0x%x, 0x%x, %lu), falling back\n",
		     to_pa, from_pa, (unsigned long)n);
		xor_dma_miss++;
		return asm_memmove(to, from, n);
	}
	/*
	 * Ok, start addr is not cache line-aligned, so we need to make it so.
	 */
	xor_dma_unaligned_to = (u32) to & 31;
	xor_dma_unaligned_from = (u32) from & 31;;
	if (xor_dma_unaligned_to | xor_dma_unaligned_from) {
		ua++;
		if (xor_dma_unaligned_from > xor_dma_unaligned_to) {
			asm_memmove(to, from, 32 - xor_dma_unaligned_to);
			to = (void *)((u32)to + 32 - xor_dma_unaligned_to);
			from = (void *)((u32)from + 32 - xor_dma_unaligned_to);
			n -= 32 - xor_dma_unaligned_to;
		} else {
			asm_memmove(to, from, 32 - xor_dma_unaligned_from);
			to = (void *)((u32)to + 32 - xor_dma_unaligned_from);
			from = (void *)((u32)from + 32 - xor_dma_unaligned_from);
			n -= 32 - xor_dma_unaligned_from;
		}
	}

	/*
	 * Ok, we're aligned at the top, now let's check the end
	 * of the buffer and align that. After this we should have
	 * a block that is a multiple of cache line size.
	 */
	xor_dma_unaligned_to = ((u32) to + n) & 31;
	xor_dma_unaligned_from = ((u32) from + n) & 31;;
	if (xor_dma_unaligned_to | xor_dma_unaligned_from) {
		ua++;
		if (xor_dma_unaligned_to > xor_dma_unaligned_from) {
			u32 tmp_to = (u32) to + n - xor_dma_unaligned_to;
			u32 tmp_from = (u32) from + n - xor_dma_unaligned_to;

			asm_memmove((void *)tmp_to, (void *)tmp_from,
				   xor_dma_unaligned_to);

			n -= xor_dma_unaligned_to;
		} else {
			u32 tmp_to = (u32) to + n - xor_dma_unaligned_from;
			u32 tmp_from = (u32) from + n - xor_dma_unaligned_from;

			asm_memmove((void *)tmp_to, (void *)tmp_from,
				   xor_dma_unaligned_from);

			n -= xor_dma_unaligned_from;
		}
	}

	/*
	 * OK! We should now be fully aligned on both ends. 
	 */
        chan = allocate_channel();
        if ( chan == -1)
        {
                DPRINTK("XOR engines are busy, return\n");
       		xor_dma_miss++;
		return asm_memmove(to, from, n);
        }
	DPRINTK("setting up rest of descriptor for channel %d\n", chan);
        channel = &xor_channel[chan];
	
        /* Ensure that the cache is clean */
	dmac_clean_range(from, from + n);
	dmac_inv_range(to, to + n);

	DPRINTK("setting up rest of descriptor\n");
	// flush the cache to memory before XOR engine touches them
        channel->pDescriptor->srcAdd0 = virt_to_phys((void*)from);
	channel->pDescriptor->phyDestAdd = virt_to_phys(to);
        channel->pDescriptor->byteCnt = n;
        channel->pDescriptor->phyNextDescPtr = 0;
        channel->pDescriptor->status = BIT31;
	channel->chan_active = 1;

        if( mvXorTransfer(chan, MV_DMA, channel->descPhyAddr) != MV_OK)
        {
            printk(KERN_ERR "%s: DMA copy operation on channel %d failed!\n", __func__, chan);
            print_xor_regs(chan);
            BUG();
            free_channel(channel);
       	    return asm_memmove(to, from, n);
        }
        xor_waiton_eng(chan);


        DPRINTK("DMA copy complete\n");
	// check to see if failed
#if 0
	if (!(channel->pDescriptor->status & BIT30))
        {
            printk(KERN_ERR "%s: DMA copy operation completed with error!\n", __func__);
            printk(" srcAdd %x DestAddr %x, count %x\n", channel->pDescriptor->srcAdd0,
                                                channel->pDescriptor->phyDestAdd, n); 
            print_xor_regs(chan);            
	    BUG();
            free_channel(channel);
       	    return asm_memmove(to, from, n);
        }
#endif
        free_channel(channel);
 
	xor_dma_hit++;
	if (ua)
		xor_dma_unaligned++;

	return orig_to;
}
Ejemplo n.º 22
0
/*
 * n must be greater equal than 64.
 */
static unsigned long xor_dma_copy(void *to, const void *from, unsigned long n, unsigned int to_user)
{
	u32 chunk,i;
	u32 k_chunk = 0;
	u32 u_chunk = 0;
	u32 phys_from, phys_to;
	
        unsigned long flags;
	u32 unaligned_to;
	u32 index = 0;
        u32 temp;

        unsigned long uaddr, kaddr;
	int     chan1, chan2 = -1;
        int     current_channel;
        struct xor_channel_t *channel;
       
        DPRINTK("xor_dma_copy: entering\n");


        chan1 = allocate_channel();
        if (chan1 != -1)
        {
            chan2 = allocate_channel();
            if(chan2 == -1)
            {
                free_channel(&xor_channel[chan1]);
            }
        }
        if((chan1 == -1) || (chan2 == -1))
        {
            goto exit_dma;
        }
        current_channel = chan1;
	/* 
      	 * The unaligned is taken care seperatly since the dst might be part of a cache line that is changed 
	 * by other process -> we must not invalidate this cache lines and we can't also flush it, since other 
	 * process (or the exception handler) might fetch the cache line before we copied it. 
	 */

	/*
	 * Ok, start addr is not cache line-aligned, so we need to make it so.
	 */
	unaligned_to = (u32)to & 31;
	if(unaligned_to)
	{
		DPRINTK("Fixing up starting address %d bytes\n", 32 - unaligned_to);

		if(to_user)
		{
		    if(__arch_copy_to_user(to, from, 32 - unaligned_to)) 
			goto free_channels; 
		}
		else
		{
		    if(__arch_copy_from_user(to, from, 32 - unaligned_to)) 
			goto free_channels;
		}

		temp = (u32)to + (32 - unaligned_to);
		to = (void *)temp;
		temp = (u32)from + (32 - unaligned_to);
		from = (void *)temp;

                /*it's ok, n supposed to be greater than 32 bytes at this point*/
		n -= (32 - unaligned_to);
	}

	/*
	 * Ok, we're aligned at the top, now let's check the end
	 * of the buffer and align that. After this we should have
	 * a block that is a multiple of cache line size.
	 */
	unaligned_to = ((u32)to + n) & 31;
	if(unaligned_to)
	{	
		u32 tmp_to = (u32)to + (n - unaligned_to);
		u32 tmp_from = (u32)from + (n - unaligned_to);
		DPRINTK("Fixing ending alignment %d bytes\n", unaligned_to);

		if(to_user)
		{
		    if(__arch_copy_to_user((void *)tmp_to, (void *)tmp_from, unaligned_to))
			goto free_channels;
		}
		else
		{
		    if(__arch_copy_from_user((void *)tmp_to, (void *)tmp_from, unaligned_to))
			goto free_channels;
		}

                /*it's ok, n supposed to be greater than 32 bytes at this point*/
		n -= unaligned_to;
	}

        if(to_user)
        {
            uaddr = (unsigned long)to;  
            kaddr = (unsigned long)from;
        }
        else
        {
             uaddr = (unsigned long)from;
             kaddr = (unsigned long)to;
        }
        if(virt_addr_valid(kaddr))
        {
            k_chunk = n;
        }
	else
	{
		DPRINTK("kernel address is not linear, fall back\n");
		goto free_channels;		
	}
         
        spin_lock_irqsave(&current->mm->page_table_lock, flags);
     
        i = 0;
	while(n > 0)
	{
	    if(k_chunk == 0)
	    {
                /* virtual address */
	        k_chunk = page_remainder((u32)kaddr);
		DPRINTK("kaddr reminder %d \n",k_chunk);
	    }

	    if(u_chunk == 0)
	    {
                u_chunk = page_remainder((u32)uaddr);
                DPRINTK("uaddr reminder %d \n", u_chunk);
            }
        
            chunk = ((u_chunk < k_chunk) ? u_chunk : k_chunk);
            if(n < chunk)
	    {
		chunk = n;
	    }

	    if(chunk == 0)
	    {
	    	break;
	    }
            phys_from = physical_address((u32)from, 0);
            phys_to = physical_address((u32)to, 1);
	    DPRINTK("choose chunk %d \n",chunk);
	    /* if page doesn't exist go out */
	    if ((!phys_from) || (!phys_to))
	    {
		/* The requested page isn't available, fall back to */
		DPRINTK(" no physical address, fall back: from %p , to %p \n", from, to);
		goto unlock_dma;
   
	    }
	    /*
	     *  Prepare the IDMA.
	     */
            if (chunk < XOR_MIN_COPY_CHUNK)
            {
                int last_chan = chan1;   
        	DPRINTK(" chunk %d too small , use memcpy \n",chunk);
        	
        	if(current_channel == chan1)
                {   
                    last_chan = chan2;
                }
                /* the "to" address might cross cache line boundary, so part of the line*/  
                /* may be subject to DMA, so we need to wait to last DMA engine to finish */
                if(index > 0)
                    xor_waiton_eng(last_chan);

                if(to_user) 
		{
	       	    if(__arch_copy_to_user((void *)to, (void *)from, chunk)) {
			printk("ERROR: %s %d shouldn't happen\n",__FUNCTION__, __LINE__);	
			goto unlock_dma;
		    }
		}
	        else
		{
	            if(__arch_copy_from_user((void *)to, (void *)from, chunk)) {
			printk("ERROR: %s %d shouldn't happen\n",__FUNCTION__, __LINE__);	
			goto unlock_dma;	
		    }
		}
            }
            else
	    {
		
		    /* 
		    * Ensure that the cache is clean:
		    *      - from range must be cleaned
		    *      - to range must be invalidated
		    */
//		    mvOsCacheFlush(NULL, (void *)from, chunk);
		    dmac_flush_range(from, from + chunk);
		    //	    mvOsCacheInvalidate(NULL, (void *)to, chunk);
		    dmac_inv_range(to, to + chunk);
		    if(index > 0)
		    {
			xor_waiton_eng(current_channel);
		    }
		    channel = &xor_channel[current_channel];
  
		    /* Start DMA */
		    DPRINTK(" activate DMA: channel %d from %x to %x len %x\n",
                            current_channel, phys_from, phys_to, chunk);
		    channel->pDescriptor->srcAdd0 = phys_from;
		    channel->pDescriptor->phyDestAdd = phys_to;
		    channel->pDescriptor->byteCnt = chunk;
		    channel->pDescriptor->phyNextDescPtr = 0;
		    channel->pDescriptor->status = BIT31;
		    channel->chan_active = 1;

		    if( mvXorTransfer(current_channel, MV_DMA, channel->descPhyAddr) != MV_OK)
		    {
			printk(KERN_ERR "%s: DMA copy operation on channel %d failed!\n", __func__, current_channel);
			print_xor_regs(current_channel);
			BUG();
		    }
                
		    if(current_channel == chan1) 
		    {
			current_channel = chan2;
                    }
		    else
		    {
			current_channel = chan1;
		    }
#ifdef RT_DEBUG
			dma_activations++;
#endif
			index++;
		    
		}

		/* go to next chunk */
		from += chunk;
		to += chunk;
                kaddr += chunk;
                uaddr += chunk;
		n -= chunk;
		u_chunk -= chunk;
		k_chunk -= chunk;		
	}
unlock_dma:
        xor_waiton_eng(chan1);
        xor_waiton_eng(chan2);
        spin_unlock_irqrestore(&current->mm->page_table_lock, flags);
free_channels:
        free_channel(&xor_channel[chan1]);
        free_channel(&xor_channel[chan2]);

exit_dma:        
        DPRINTK("xor_dma_copy(0x%x, 0x%x, %lu): exiting\n", (u32) to,
                (u32) from, n);
       
        if(n != 0)
        {
       	    if(to_user)
                return __arch_copy_to_user((void *)to, (void *)from, n);
	            else
                return __arch_copy_from_user((void *)to, (void *)from, n);
        }
        return 0;
}
Ejemplo n.º 23
0
/*=======================================================================*/
void xor_memzero(void *to, __kernel_size_t n)
{
	u32 xor_dma_unaligned_to;
	u32 to_pa;
        int ua = 0;
        int         chan;
        struct xor_channel_t *channel;

	DPRINTK("xor_memzero(0x%x, %lu): entering\n", (u32) to, (unsigned long)n);

        if (xor_engine_initialized == 0)
        {
            DPRINTK(KERN_WARNING" %s: xor engines not initialized yet\n", __func__);
       	    xor_memzero_miss++;
	    return asm_memzero(to, n);
        }
 	if (!(virt_addr_valid((u32) to))) {
		DPRINTK("xor_memcpy(0x%x, %lu): falling back to memzero\n",
			(u32) to, (unsigned long)n);
		xor_memzero_miss++;
		return asm_memzero(to, n);
	}

	/*
	 * We can only handled completely cache-aligned transactions
	 * with the DMA engine.  Dst must be cache-line
	 * aligned AND the length must be a multiple of the cache-line.
	 */

	to_pa = virt_to_phys(to);

	/*
	 * Ok, start addr is not cache line-aligned, so we need to make it so.
	 */
	xor_dma_unaligned_to = (u32) to & 31;
	if (xor_dma_unaligned_to)
        {
            ua++;
	    asm_memzero(to, 32 - xor_dma_unaligned_to);
            to = (void *)((u32)to + 32 - xor_dma_unaligned_to);
	    n -= 32 - xor_dma_unaligned_to;
	}

	/*
	 * Ok, we're aligned at the top, now let's check the end
	 * of the buffer and align that. After this we should have
	 * a block that is a multiple of cache line size.
	 */
	xor_dma_unaligned_to = ((u32) to + n) & 31;
	if (xor_dma_unaligned_to) {
	    u32 tmp_to = (u32) to + n - xor_dma_unaligned_to;
	    asm_memzero((void *)tmp_to, xor_dma_unaligned_to);
            n -= xor_dma_unaligned_to;
	    ua++;
	}

	/*
	 * OK! We should now be fully aligned on both ends. 
	 */
        chan = allocate_channel();
        if ( chan == -1)
         {
                DPRINTK("XOR engines are busy, return\n");
       		xor_memzero_miss++;
		return asm_memzero(to, n);
        }
        if (down_trylock(&meminit_sema))
        {
            DPRINTK("meminit is used by one of the XOR engines\n");
            xor_memzero_miss++;
            free_channel(&xor_channel[chan]);
	    return asm_memzero(to, n);
        }

	DPRINTK("setting up rest of descriptor for channel %d\n", chan);
        channel = &xor_channel[chan];
	
        /* Ensure that the cache is clean */
	dmac_inv_range(to, to + n);

	channel->chan_active = 1;

	DPRINTK("setting up rest of descriptor\n");
        if( mvXorMemInit(chan, virt_to_phys(to), n, 0, 0) != MV_OK)
        {
            printk(KERN_ERR "%s: DMA memzero operation on channel %d failed. to %p len %d!\n", __func__, chan,
                to, n);
            free_channel(channel);
            up(&meminit_sema);
       	    return asm_memzero(to, n);
        }
        xor_waiton_eng(chan);


        DPRINTK("DMA memzero complete\n");
	// check to see if failed
        up(&meminit_sema);
        free_channel(channel);
	xor_memzero_hit++;
	if (ua)
		xor_memzero_unaligned++;

}
Ejemplo n.º 24
0
/**
 * Deferred service responder to process messages off the ISR
 * queue
 * If expanded to multiple instances, "ins" will be the index
 * of the device instance state block
 * @param ins
 */
void t23RMdeferredInterruptResponder(int inst)
{
    int32_t         i;
    T2ISRCtx       *thisEvent;
    T2CoreInstance *thisDev;
    RMexecMessage  *thisMsg, *nextMsg;
    u32             errorDesc;
    int32_t         channel, burstsize, burst;
    unsigned long   irqflags;
#ifdef RM_DBG_EXTENDED_ERROR
    int32_t         j;
    int16_t         errbits;
#endif

    thisDev = ifCtx[inst].devctx;


    /* Spin through "do" for as many events on the ISR event queue */
    /* This means that the tasklet might get invoked with nothing to */
    /* do on rare occasions, so be it... */

    do
    {
        /* Mask interrupts, and pull ISR contexts off the ISR queue */
        /* If level == 0, nothing to do */
        disable_irq(thisDev->doneIRQid);
        if (!thisDev->isrQlevel)
        {
            enable_irq(thisDev->doneIRQid);
            return;
        }

        /* Grab an IRQ event context, decrement queue level, and unmask */
        thisEvent = &thisDev->t2isrQ[thisDev->isrQhead];
        thisDev->isrQhead = (thisDev->isrQhead + 1) % ISRMSG_QUEUE_DEPTH;
        thisDev->isrQlevel--;
        enable_irq(thisDev->doneIRQid);

#ifdef RM_DBG_EXTENDED_ERROR
        printk("t23xrm:t23RMdeferredInterruptResponder() - new ISR event - done 0x%04x - error 0x%04x\n",
                thisEvent->channelsDone, thisEvent->channelsInError);

        if (thisEvent->channelsDone)
            printk("channels done: ");
        for (j = 0; j < thisDev->totalChannels; j++)
            if (thisEvent->channelsDone & (INT_ACTIVE_CH0 << j))
                printk("%d ", j + 1);
        if (thisEvent->channelsDone)
            printk("\n");

        if (thisEvent->channelsInError)
            printk("channels in error: ");
        for (j = 0; j < thisDev->totalChannels; j++)
            if (thisEvent->channelsInError & (INT_ACTIVE_CH0 << j))
                printk("%d ", j + 1);
        if (thisEvent->channelsInError)
            printk("\n");
#endif

        /* For any "done" interrupt, go through all interrupting channels */
        /* and invoke handlers as spec'ed in each message, then free the  */
        /* channel if there is no static reservation                      */
        if (thisEvent->channelsDone)
            for (i = 0; i < thisDev->totalChannels; i++)
                if (thisEvent->channelsDone & (INT_ACTIVE_CH0 << i))
                {
                    thisMsg = thisDev->channelActvMsg[i];
                    /* error information is zeroed */
                    thisMsg->errState[0] = 0;
                    thisMsg->errState[1] = 0;
                    thisMsg->errState[2] = 0;
                    thisMsg->errState[3] = 0;
                    thisMsg->errDesc     = NULL;

                    if (thisMsg->descriptorDoneHandler != NULL)
                        thisMsg->descriptorDoneHandler(0);

                    thisMsg->messageReleaseHandler(thisMsg->releaseArgument);
                    if (thisMsg->waitingTask != NULL)
                        wake_up(thisMsg->waitingTask);

                    free_channel(i);
                }

        /* For any "error" interrupt, go through all interrupting channels     */
        /* capture the error status and a pointer to the error-ing descriptor, */
        /* then go invoke handlers if they exist, and free the channel         */
        if (thisEvent->channelsInError)
            for (i = 0; i < thisDev->totalChannels; i++)
                if (thisEvent->channelsInError & (INT_ACTIVE_CH0 << i))
                {
                    thisMsg = thisDev->channelActvMsg[i];
                    /* write the CPSR/errdesc to exec message status */
                    thisMsg->errState[0] = thisEvent->channelState[i];
                    thisMsg->errState[1] = 0;
                    thisMsg->errState[2] = thisEvent->priEUstate[i];
                    thisMsg->errState[3] = thisEvent->secEUstate[i];

                    errorDesc = (thisEvent->currentDesc[i] & 0x00000000ffffffffull);
                    thisMsg->errDesc = (T2DPD *)errorDesc;

                    if (thisMsg->descriptorErrorHandler != NULL)
                        thisMsg->descriptorErrorHandler(0);

                    thisMsg->messageReleaseHandler(thisMsg->releaseArgument);
                    if (thisMsg->waitingTask != NULL)
                        wake_up(thisMsg->waitingTask);

                    free_channel(i);

#ifdef RM_DBG_EXTENDED_ERROR
                    printk("Extended error report for channel %d:\n", i + 1);

                    printk("CPSR ");
                    printk("get:0x%02llx ", (thisMsg->errState[0] & T3_CPSR_GET_STATE_MASK) >> T3_CPSR_GET_STATE_SHIFT);
                    printk("put:0x%02llx ", (thisMsg->errState[0] & T3_CPSR_PUT_STATE_MASK) >> T3_CPSR_PUT_STATE_SHIFT);
                    printk("main:0x%03llx ", (thisMsg->errState[0] & T3_CPSR_MAIN_STATE_MASK) >> T3_CPSR_MAIN_STATE_SHIFT);
                    printk("ff_lvl:0x%02llx ", (thisMsg->errState[0] & T3_CPSR_FF_LEVEL_MASK) >> T3_CPSR_FF_LEVEL_SHIFT);
                    if (thisMsg->errState[0] & T3_CPSR_PRD) printk("prd ");
                    if (thisMsg->errState[0] & T3_CPSR_SRD) printk("srd ");
                    if (thisMsg->errState[0] & T3_CPSR_PD)  printk("pd ");
                    if (thisMsg->errState[0] & T3_CPSR_SD)  printk("sd ");
                    printk("\n");

                    printk("CPSR error bits: ");
                    errbits = thisMsg->errState[0] & T2_CPSR_ERROR_MASK;
                    if (errbits & T2_CHN_ERROR_DOF)            printk("DOF ");
                    if (errbits & T2_CHN_ERROR_SOF)            printk("SOF ");
                    if (errbits & T2_CHN_ERROR_MDTE)           printk("MDTE ");
                    if (errbits & T2_CHN_ERROR_SG_ZERO_LEN)    printk("SGZERO ");
                    if (errbits & T2_CHN_ERROR_FP_ZERO)        printk("FPZERO ");
                    if (errbits & T2_CHN_ERROR_ILLEGAL_HEADER) printk("ILLHDR ");
                    if (errbits & T2_CHN_ERROR_INVALID_EU)     printk("INVEU ");
                    if (errbits & T2_CHN_ERROR_EU_ERROR)       printk("EUERR ");
                    if (errbits & T2_CHN_ERROR_G_BOUNDARY)     printk("GBDRY ");
                    if (errbits & T2_CHN_ERROR_G_LENGTH)       printk("GLEN ");
                    if (errbits & T2_CHN_ERROR_S_BOUNDARY)     printk("SBDRY ");
                    if (errbits & T2_CHN_ERROR_S_LENGTH)       printk("SLEN ");
                    printk("\n");

                    printk("fetched descriptor as read into channel:\n");
                    printk("header: 0x%08x\n", thisEvent->fetchedDesc[i].dpd.hdr);
                    for (j = 0; j < TOTAL_PAIRS; j++)
                    {
                        if (thisEvent->fetchedDesc[i].dpd.pair[j].eptr ||
                            thisEvent->fetchedDesc[i].dpd.pair[j].ptr  ||
                            thisEvent->fetchedDesc[i].dpd.pair[j].size ||
                            thisEvent->fetchedDesc[i].dpd.pair[j].extent)
                        {
                            printk("pair %d: 0x%02x%08x: %5d (ext:%3d)",
                                   j,
                                   thisEvent->fetchedDesc[i].dpd.pair[j].eptr,
                                   (u32)thisEvent->fetchedDesc[i].dpd.pair[j].ptr,
                                   thisEvent->fetchedDesc[i].dpd.pair[j].size,
                                   (thisEvent->fetchedDesc[i].dpd.pair[j].extent & EXTENT_MASK));
                            if (thisEvent->fetchedDesc[i].dpd.pair[j].extent & JUMPTABLE)
                                printk(", scattered\n");
                            else
                                printk("\n");
                        }
                    }

                    for (j = 0; j < 4; j++)
                    {
                        if (thisEvent->fetchedDesc[i].glt[j].segLen    ||
                            thisEvent->fetchedDesc[i].glt[j].chainCtrl ||
                            thisEvent->fetchedDesc[i].glt[j].extAddr   ||
                            thisEvent->fetchedDesc[i].glt[j].segAddr)
                        {
                            printk("gthr %d: 0x%02x%08x: %5d ",
                            j,
                            thisEvent->fetchedDesc[i].glt[j].extAddr,
                            (u32)thisEvent->fetchedDesc[i].glt[j].segAddr,
                            thisEvent->fetchedDesc[i].glt[j].segLen);

                            if (thisEvent->fetchedDesc[i].glt[j].chainCtrl & LAST_ENTRY)
                                printk("end ");
                            if (thisEvent->fetchedDesc[i].glt[j].chainCtrl & NEXT_ENTRY)
                                printk("next ");

                            printk("\n");
                        }
                    }

                    for (j = 0; j < 4; j++)
                    {
                        if (thisEvent->fetchedDesc[i].slt[j].segLen    ||
                            thisEvent->fetchedDesc[i].slt[j].chainCtrl ||
                            thisEvent->fetchedDesc[i].slt[j].extAddr   ||
                            thisEvent->fetchedDesc[i].slt[j].segAddr)
                        {
                            printk("sctr %d: 0x%02x%08x: %5d ",
                            j,
                            thisEvent->fetchedDesc[i].slt[j].extAddr,
                            (u32)thisEvent->fetchedDesc[i].slt[j].segAddr,
                            thisEvent->fetchedDesc[i].slt[j].segLen);

                            if (thisEvent->fetchedDesc[i].slt[j].chainCtrl & LAST_ENTRY)
                                printk("end ");
                            if (thisEvent->fetchedDesc[i].slt[j].chainCtrl & NEXT_ENTRY)
                                printk("next ");

                            printk("\n");
                        }
                    }

                    printk("channel %d pri EU intstatus = 0x%016llx\n",
                           i,
                           thisEvent->priEUstate[i]);

                    printk("channel %d sec EU intstatus = 0x%016llx\n",
                           i,
                           thisEvent->secEUstate[i]);
#endif
                }


        /* Once we get down here, we should have some free channels */
        /* If there's stuff on the exec queue, start as many        */
        /* entries off the queue as possible                        */
        spin_lock_irqsave(&thisDev->execQlock, irqflags);
        if ((thisDev->execQlevel) &&
            (thisDev->freeChannels))
        {

            /* OK, we have at least one in the request queue, and */
            /* at least one free channel. Channel allocation and  */
            /* the request queue are both locked. Based on this,  */
            /* how many can we launch?                            */
            if (thisDev->execQlevel < thisDev->freeChannels)
                burstsize = thisDev->execQlevel;
            else
                burstsize = thisDev->freeChannels;

            burst = burstsize;

            /* loop through each possible message in this launch burst */
            while (burstsize)
            {
                /* Don't know which channels are free, so find one */
                for (channel = 0; channel < thisDev->totalChannels; channel++)
                    if (thisDev->channelState[channel] == CHstateFree)
                    {
                        /* This one is free, reserve it */
                        thisDev->freeChannels--;
                        thisDev->channelState[channel] = CHstateBusy;
                        break;
                    }

                /* Got an allocated channel. Pop one entry */
                nextMsg = thisDev->execQ[thisDev->execQhead];
                thisDev->execQhead =
                    (thisDev->execQhead + 1) % EXEC_QUEUE_DEPTH;
                thisDev->execQlevel--;

                /* launch it */
                if ((uint32_t)nextMsg <= 0x00001000)
                    panic("t23xrm:t23RMdeferredInterruptResponder() new msg 0x%08x channel %d execQlevel %d head %d tail %d, isrQ %d, burst %d, pending 0x%04x\n",
                          (uint32_t)nextMsg, channel, thisDev->execQlevel, thisDev->execQhead, thisDev->execQtail, thisDev->isrQlevel, burst, thisEvent->channelsDone);
                rmStartDesc(thisDev, nextMsg, channel);

                burstsize--;
            }
        }
        spin_unlock_irqrestore(thisDev->execQlock, irqflags);

    } while (thisDev->isrQlevel);
Ejemplo n.º 25
0
static void free_proxy( struct proxy *proxy )
{
    free_channel( proxy->channel );
    heap_free( proxy );
}
Ejemplo n.º 26
0
struct response *evresp_itp(char *stalst, char *chalst, char *net_code,
                            char *locidlst, char *date_time, char *units,
                            char *file, double *freqs, int nfreqs,
                            char *rtype, char *verbose, int start_stage,
                            int stop_stage, int stdio_flag,
                            int listinterp_out_flag, int listinterp_in_flag,
                            double listinterp_tension, int useTotalSensitivityFlag)
{
  struct channel this_channel;
  struct scn *scn;
  struct string_array *sta_list, *chan_list;
  struct string_array *locid_list;
  int i, j, k, count = 0, which_matched, test = 1, mode, new_file;
  int  locid_pos;
  int  err_type;
  char  out_name[MAXLINELEN], locid[LOCIDLEN+1];
  char *locid_ptr, *end_locid_ptr;
  struct matched_files *flst_head = (struct matched_files *)NULL;
  struct matched_files *flst_ptr = NULL, *output_files = NULL;
  struct file_list *lst_ptr = NULL, *tmp_ptr = NULL, *out_file = NULL, *tmp_file = NULL;
  struct response *resp = NULL, *next_ptr = NULL;
  struct response *prev_ptr = (struct response *)NULL;
  struct response *first_resp = (struct response *)NULL;
  struct complex *output = NULL;
  struct scn_list *scns = NULL;
  FILE *fptr = NULL;
  double *freqs_orig = NULL;  /* for saving the original frequencies */
  int nfreqs_orig;

 /* Let's save the original frequencies requested by a user since they can be overwritten */
 /* if we process blockette 55 IGD for version 3.2.17 of evalresp*/

   nfreqs_orig = nfreqs;
   freqs_orig = (double *) malloc(sizeof(double) * nfreqs_orig);
   memcpy (freqs_orig, freqs, sizeof(double) * nfreqs_orig);

  /* set 'GblChanPtr' to point to 'this_channel' */

  GblChanPtr = &this_channel;

  /* clear out the FirstLine buffer */

  memset(FirstLine, 0, sizeof(FirstLine));


  /* if the verbose flag is set, then print some diagnostic output (other than
     errors) */

  if(verbose && !strcmp(verbose,"-v")) {
    fprintf(stderr, "<< EVALRESP RESPONSE OUTPUT V%s >>\n", REVNUM);
    fflush(stderr);
  }

  /* first, determine the values of Pi and twoPi for use in evaluating
     the instrument responses later */

  Pi = acos(-1.0);
  twoPi = 2.0 * Pi;

  /* set the values of first_units and last_units to null strings */

  strncpy(this_channel.staname,"",STALEN);
  strncpy(this_channel.network,"",NETLEN);
  strncpy(this_channel.locid,"",LOCIDLEN);
  strncpy(this_channel.chaname,"",CHALEN);
  strncpy(this_channel.beg_t,"",DATIMLEN);
  strncpy(this_channel.end_t,"",DATIMLEN);
  strncpy(this_channel.first_units,"",MAXLINELEN);
  strncpy(this_channel.last_units,"",MAXLINELEN);

  /* and initialize the linked list of pointers to filters */

  this_channel.first_stage = (struct stage *)NULL;

  /* parse the "stalst" string to form a list of stations */

  for(i = 0; i < (int)strlen(stalst); i++) {
    if(stalst[i] == ',')
      stalst[i] = ' ';
  }
  sta_list = ev_parse_line(stalst);

  /* remove any blank spaces from the beginning and end of the string */

  locid_ptr = locidlst; locid_pos = 0;
  strncpy(locid, "", LOCIDLEN);
  while(*locid_ptr && *locid_ptr == ' ') locid_ptr++;
  end_locid_ptr = locid_ptr + strlen(locid_ptr) - 1;
  while(end_locid_ptr > locid_ptr && *end_locid_ptr == ' ') end_locid_ptr--;
  strncpy(locid, locid_ptr, (end_locid_ptr - locid_ptr + 1));

  /* parse the "locidlst" string to form a list of channels  */

  locid_list = parse_delim_line(locid,",");

  /* parse the "chalst" string to form a list of channels */

  for(i = 0; i < (int)strlen(chalst); i++) {
    if(chalst[i] == ',')
      chalst[i] = ' ';
  }
  chan_list = ev_parse_line(chalst);

  /* then form a set of network-station-locid-channel tuples to search for */

  scns = alloc_scn_list(chan_list->nstrings*sta_list->nstrings*locid_list->nstrings);
  for(i = 0; i < sta_list->nstrings; i++) {
    for(j = 0; j < locid_list->nstrings; j++) {
      for(k = 0; k < chan_list->nstrings; k++, count++) {
	scn = scns->scn_vec[count];
	strncpy(scn->station, sta_list->strings[i], STALEN);
	if(strlen(locid_list->strings[j]) == strspn(locid_list->strings[j], " "))
	  memset(scn->locid, 0, LOCIDLEN);
	else
	  strncpy(scn->locid, locid_list->strings[j], LOCIDLEN);
	strncpy(scn->channel, chan_list->strings[k], CHALEN);
	strncpy(scn->network, net_code, NETLEN);
      }
    }
  }
#ifdef LOG_LABEL
  sprintf(myLabel, "[%s.%s.%s.%s]", scn->network, scn->station, scn->locid, scn->channel);
#else
  myLabel[0] = '\0';
#endif
  /* if input is from stdin, set fptr to stdin, else find whatever matching
     files there are */

  if(stdio_flag) {
    fptr = stdin;
    mode = 0;
  }
  else {
    flst_head = find_files(file, scns, &mode);
    flst_ptr = flst_head;
  }

  /* find the responses for each of the station channel pairs as they
     occur in the file */

  if(!mode && !stdio_flag) {
    curr_file = file;
    if((fptr = fopen(file,"r")) == (FILE *)NULL)  {
#ifdef LIB_MODE
      fprintf(stderr, "%s failed to open file %s\n", myLabel, file);
      return NULL;
#else
      error_exit(OPEN_FILE_ERROR,"failed to open file %s", file);
#endif
    }
  }

  /* allocate space for the first response */

  resp = alloc_response(nfreqs);

  for(i = 0; i < scns->nscn && (mode || test); i++) {

    /* allocate space for 'matched_files' pointer used to determine if a
       file has already been read */

    if(!stdio_flag)
      output_files = alloc_matched_files();

    /* then check the mode to determine if are parsing one file or a list
       of files (note: if input is from stdin, is one file) */

    if(!mode) {
      which_matched = 0;
      while(test && which_matched >= 0) {
        if(!(err_type = setjmp(jump_buffer))) {
          new_file = 0;
          which_matched = find_resp(fptr, scns, date_time, &this_channel);
#ifdef LIB_MODE /* IGD 25-Sep-2007 Looks like we do not need this: function returns anyway */
//        if(which_matched < 0) {
//        if(!stdio_flag)            /* if not input from console then */
//          fclose(fptr);            /* close input file
//        return NULL;
//       }
#endif

          /* found a station-channel-network that matched.  First construct
             an output filename and compare to other output files. If this
             filename doesn't match any of them, (or if it is the first
             file found) parse the channel's response information.
             Otherwise skip it (since a match has already been found) */

          sprintf(out_name,"%s.%s.%s.%s",this_channel.network,
                  this_channel.staname,this_channel.locid,
                  this_channel.chaname);
#ifdef LOG_LABEL
          sprintf(myLabel, "[%s]", out_name);
#else
          myLabel[0] = '\0';
#endif
	  if(!stdio_flag) {
	    tmp_file = output_files->first_list;
	    for(k = 0; k < output_files->nfiles; k++) {
	      out_file = tmp_file;
	      if(!strcmp(out_file->name,out_name))
		break;
	      tmp_file = out_file->next_file;
	    }
	  }
          if((stdio_flag && !new_file) || !output_files->nfiles) {
	    if(!stdio_flag) {
	      output_files->nfiles++;
	      out_file = alloc_file_list();
	      output_files->first_list = out_file;
	      out_file->name = alloc_char(strlen(out_name)+1);
	      strcpy(out_file->name,out_name);
	    }
            new_file = 1;
          }
          else if((stdio_flag && !new_file) || k == output_files->nfiles) {
	    if(!stdio_flag) {
	      output_files->nfiles++;
	      out_file->next_file = alloc_file_list();
	      tmp_file = out_file->next_file;
	      out_file = tmp_file;
	      out_file->name = alloc_char(strlen(out_name)+1);
	      strcpy(out_file->name,out_name);
	    }
            new_file = 1;
          }
          else
            new_file = 0;

          if(new_file && which_matched >= 0) {

            /* fill in station-channel-net information for the response */

            strncpy(resp->station,this_channel.staname,STALEN);
            strncpy(resp->locid,this_channel.locid,LOCIDLEN);
            strncpy(resp->channel,this_channel.chaname,CHALEN);
            strncpy(resp->network,this_channel.network,NETLEN);
            output = resp->rvec;

            /* found a station channel pair that matched a response, so parse
               the response into a channel/filter list */

            test = parse_channel(fptr, &this_channel);

            if(listinterp_in_flag &&
                         this_channel.first_stage->first_blkt->type == LIST)
            {      /* flag set for interpolation and stage type is "List" */
              interpolate_list_blockette(
                &(this_channel.first_stage->first_blkt->blkt_info.list.freq),
                &(this_channel.first_stage->first_blkt->blkt_info.list.amp),
                &(this_channel.first_stage->first_blkt->blkt_info.list.phase),
                &(this_channel.first_stage->first_blkt->blkt_info.list.nresp),
                freqs,nfreqs,listinterp_tension);
            }

           /* check the filter sequence that was just read */
            check_channel(&this_channel);

		/* If we process blockette 55, we should recompute resp->rvec */
		/* because the number of output responses is generally different from */
		/* what is the user requested */
		/*if we don't use blockette 55, we should set the frequencies to the original */
		/* user defined position if we did mess up with frequencies in -possible - blockette 55*/
		/* containing previous file. Modifications by I.Dricker IGD*/


	    free(resp->rvec);
/* 'freqs' array is passed in and should not be freed -- 10/18/2005 -- [ET] */
/*	    free(freqs); */

	    if (this_channel.first_stage->first_blkt != NULL && this_channel.first_stage->first_blkt->type == LIST)
	    {
	      /*to prevent segmentation in case of bogus input files */
	      nfreqs = this_channel.first_stage->first_blkt->blkt_info.list.nresp;
	      freqs = (double *) malloc(sizeof(double) * nfreqs); /* malloc a new vector */
    	      memcpy (freqs, this_channel.first_stage->first_blkt->blkt_info.list.freq, sizeof(double) * nfreqs); /*cp*/
			resp->rvec = alloc_complex(nfreqs);
	      output=resp->rvec;
	      resp->nfreqs = nfreqs;
	      resp->freqs = (double *) malloc(sizeof(double) * nfreqs); /* malloc a new vector */
	      memcpy (resp->freqs, this_channel.first_stage->first_blkt->blkt_info.list.freq, sizeof(double) * nfreqs); /*cp*/
	   }
	  else
	  {
	    nfreqs = nfreqs_orig;
	    freqs = (double *) malloc(sizeof(double) * nfreqs); /* malloc a new vector */
    	    memcpy (freqs, freqs_orig, sizeof(double) * nfreqs); /*cp*/
	    resp->rvec = alloc_complex(nfreqs);
	    output=resp->rvec;
	    resp->nfreqs = nfreqs;
	    resp->freqs = (double *) malloc(sizeof(double) * nfreqs); /* malloc a new vector */
    	    memcpy (resp->freqs, freqs_orig, sizeof(double) * nfreqs); /*cp*/
	  }


            /* normalize the response of the filter sequence */

            norm_resp(&this_channel, start_stage, stop_stage);

            /* calculate the response at the requested frequencies */

            calc_resp(&this_channel, freqs, nfreqs, output, units,
                      start_stage, stop_stage, useTotalSensitivityFlag);

            /* diagnostic output, if the user requested it */

            if(verbose && !strcmp(verbose,"-v")) {
              print_chan(&this_channel, start_stage, stop_stage,
                       stdio_flag, listinterp_out_flag, listinterp_in_flag, useTotalSensitivityFlag);
            }

            free(freqs);          /* free array that was allocated above */

            /* and, finally, free the memory associated with this channel/filter
               list and continue searching for the next match */

            free_channel(&this_channel);
            if(first_resp == (struct response *)NULL) {
              first_resp = resp;
            }
            next_ptr = alloc_response(nfreqs);
            resp->next = next_ptr;
            prev_ptr = resp;
            resp = next_ptr;
          }
          else {
            strncpy(FirstLine,"",MAXLINELEN);
            test = next_resp(fptr);
          }
        }
        else {
          if(new_file)
            output_files->nfiles--;
          free_channel(&this_channel);
          /* catch errors that cause parsing to fail midstream */
          if(err_type == PARSE_ERROR || err_type == UNRECOG_FILTYPE ||
             err_type == UNDEF_SEPSTR || err_type == IMPROP_DATA_TYPE ||
             err_type == RE_COMP_FAILED || err_type == UNRECOG_UNITS) {
            strncpy(FirstLine,"",MAXLINELEN);
            test = next_resp(fptr);
          }
          else if(err_type == UNDEF_PREFIX) {
            test = 0;
          }
        }
      }
      if(!stdio_flag)
	free_matched_files(output_files);     /* added 3/28/2006 -- [ET] */

      /* allocated one too many responses */

      free_response(resp);
      if(prev_ptr != (struct response *)NULL)
        prev_ptr->next = (struct response *)NULL;
      break;

    }
    else if(mode) {
      lst_ptr = flst_ptr->first_list;
      scn = scns->scn_vec[i];
    next_scn:
      for(j = 0; j < flst_ptr->nfiles; j++) {
        if(!stdio_flag) {
          fptr = fopen(lst_ptr->name,"r");
        }
        if(fptr != (FILE *)NULL) {
          curr_file = lst_ptr->name;
    look_again:
          if(!(err_type = setjmp(jump_buffer))) {
            new_file = 0;
            which_matched = get_resp(fptr, scn, date_time, &this_channel);
#ifdef LIB_MODE /* IGD 25-Sep-2007 Looks like we do not need this: function returns anyway */
//           if(which_matched < 1) {
//             if(!stdio_flag)           /* if not input from console then */
//               fclose(fptr);           /* close input file */
//             return NULL;
//          }
#endif
            if(which_matched >= 0) {

              /* found a station-channel-network that matched.  First construct
                 an output filename and compare to other output files. If this
                 filename doesn't match any of them, (or if it is the first
                 file found) parse the channel's response information.
                 Otherwise skip it (since a match has already been found) */

              sprintf(out_name,"%s.%s.%s.%s",this_channel.network,
                      this_channel.staname,this_channel.locid,
                      this_channel.chaname);
#ifdef LOG_LABEL
              sprintf (myLabel, "[%s]", out_name);
#else
              myLabel[0] = '\0';
#endif
              tmp_file = output_files->first_list;
              for(k = 0; k < output_files->nfiles; k++) {
                out_file = tmp_file;
                if(!strcmp(out_file->name,out_name))
                  break;
                tmp_file = out_file->next_file;
              }
              if(!output_files->nfiles) {
                output_files->nfiles++;
                out_file = alloc_file_list();
                output_files->first_list = out_file;
                out_file->name = alloc_char(strlen(out_name)+1);
                strcpy(out_file->name,out_name);
                new_file = 1;
              }
              else if(k == output_files->nfiles) {
                output_files->nfiles++;
                out_file->next_file = alloc_file_list();
                tmp_file = out_file->next_file;
                out_file = tmp_file;
                out_file->name = alloc_char(strlen(out_name)+1);
                strcpy(out_file->name,out_name);
                new_file = 1;
              }
              else
                new_file = 0;

              if(new_file) {

                /* fill in station-channel-net information for the response */

                strncpy(resp->station,this_channel.staname,STALEN);
                strncpy(resp->locid,this_channel.locid,LOCIDLEN);
                strncpy(resp->channel,this_channel.chaname,CHALEN);
                strncpy(resp->network,this_channel.network,NETLEN);
                output = resp->rvec;

                /* parse the response into a channel/filter list */

                test = parse_channel(fptr, &this_channel);

                /* IGD 01/04/01 Add code preventing a user from defining output units as DIS and ACC if
                the input units are PRESSURE after */
                if (strncmp (this_channel.first_units, "PA -",4) == 0)  {
                  if (strcmp(units, "VEL") != 0)	{
                    if(strcmp(units, "DEF") != 0)  {
                      fprintf(stderr, "%s WARNING: OUTPUT %s does not make sense if INPUT is PRESSURE\n",
                                      myLabel, units);
                      strcpy (units, "VEL");
                      fprintf(stderr, "%s      OUTPUT units are reset and interpreted as PRESSURE\n", myLabel);
                    }
                  }
                }
                /* IGD 08/21/06 Add code preventing a user from defining output units as DIS and ACC if
                the input units are TESLA */
                if (strncmp (this_channel.first_units, "T -", 3) == 0)  {
                  if (strcmp(units, "VEL") != 0)  {
                    if(strcmp(units, "DEF") != 0)  {
                      fprintf(stderr, "%s WARNING: OUTPUT %s does not make sense if INPUT is MAGNETIC FLUX\n",
                                                        myLabel, units);
                      strcpy (units, "VEL");
                      fprintf(stderr, "%s      OUTPUT units are reset and interpreted as TESLA\n", myLabel);
                   }
                  }
                }

                if(listinterp_in_flag &&
                         this_channel.first_stage->first_blkt->type == LIST)  {
                        /* flag set for interpolation and stage type is "List" */
                  interpolate_list_blockette(
                   &(this_channel.first_stage->first_blkt->blkt_info.list.freq),
                   &(this_channel.first_stage->first_blkt->blkt_info.list.amp),
                   &(this_channel.first_stage->first_blkt->blkt_info.list.phase),
                   &(this_channel.first_stage->first_blkt->blkt_info.list.nresp),
                   freqs,nfreqs,listinterp_tension);
                }

                /* check the filter sequence that was just read */
                check_channel(&this_channel);

		/* If we process blockette 55, we should recompute resp->rvec */
		/* because the number of output responses is generally different from */
		/* what is the user requested */
		/*if we don't use blockette 55, we should set the frequencies to the original */
		/* user defined position if we did mess up with frequencies in -possible - blockette 55*/
		/* containing previous file. Modifications by I.Dricker / IGD */

		free(resp->rvec);
/* 'freqs' array is passed in and should not be freed -- 10/18/2005 -- [ET] */
/*		free(freqs); */
		if (this_channel.first_stage->first_blkt != NULL && this_channel.first_stage->first_blkt->type == LIST) {
			/* This is to prevent segmentation if the response input is bogus responses */
			nfreqs = this_channel.first_stage->first_blkt->blkt_info.list.nresp;
			freqs = (double *) malloc(sizeof(double) * nfreqs); /* malloc a new vector */
    			memcpy (freqs, this_channel.first_stage->first_blkt->blkt_info.list.freq, sizeof(double) * nfreqs); /*cp*/
			resp->rvec = alloc_complex(nfreqs);
			output=resp->rvec;
			resp->nfreqs = nfreqs;
			resp->freqs = (double *) malloc(sizeof(double) * nfreqs); /* malloc a new vector */
    			memcpy (resp->freqs, this_channel.first_stage->first_blkt->blkt_info.list.freq, sizeof(double) * nfreqs); /*cp*/
		}
		else	{
			nfreqs = nfreqs_orig;
			freqs = (double *) malloc(sizeof(double) * nfreqs); /* malloc a new vector */
    			memcpy (freqs, freqs_orig, sizeof(double) * nfreqs); /*cp*/
			resp->rvec = alloc_complex(nfreqs);
			output=resp->rvec;
			resp->nfreqs = nfreqs;
			resp->freqs = (double *) malloc(sizeof(double) * nfreqs); /* malloc a new vector */
    			memcpy (resp->freqs, freqs_orig, sizeof(double) * nfreqs); /*cp*/
		}

                /* normalize the response of the filter sequence */

                norm_resp(&this_channel, start_stage, stop_stage);

                /* calculate the response at the requested frequencies */

                calc_resp(&this_channel, freqs, nfreqs, output, units,
                          start_stage, stop_stage, useTotalSensitivityFlag);

                /* diagnostic output, if the user requested it */

                if(verbose && !strcmp(verbose,"-v")) {
                  print_chan(&this_channel, start_stage, stop_stage,
                       stdio_flag, listinterp_out_flag, listinterp_in_flag, useTotalSensitivityFlag);
                }

                free(freqs);      /* free array that was allocated above */

                /* and, finally, free the memory associated with this
                   channel/filter list and continue searching for the
                   next match */

                free_channel(&this_channel);
                if(first_resp == (struct response *)NULL) {
                  first_resp = resp;
                }
                next_ptr = alloc_response(nfreqs);
                resp->next = next_ptr;
                prev_ptr = resp;
                resp = next_ptr;
              }
              FirstField = 0;
              strncpy(FirstLine,"",MAXLINELEN);
              if(!stdio_flag) {
                fclose(fptr);
              }
            }
            else {
              strncpy(FirstLine,"",MAXLINELEN);
              test = next_resp(fptr);
	      if (!test) {
		if(!stdio_flag) {
		  fclose(fptr);
		}
	      }
            }

            /* if not the last file in the list, move on to the next one */

            if(lst_ptr->next_file != (struct file_list *)NULL) {
              tmp_ptr = lst_ptr->next_file;
              lst_ptr = tmp_ptr;
            }
          }
          else {
            if (new_file)
              output_files->nfiles--;
            /* catch errors that cause parsing to fail midstream */
            if(err_type == PARSE_ERROR || err_type == UNRECOG_FILTYPE ||
               err_type == UNDEF_SEPSTR || err_type == IMPROP_DATA_TYPE ||
               err_type == RE_COMP_FAILED || err_type == UNRECOG_UNITS) {
              strncpy(FirstLine,"",MAXLINELEN);
              test = next_resp(fptr);
            }
            else if(err_type == UNDEF_PREFIX) {
              test = 0;
            }
            free_channel(&this_channel);
            if (!test) {
              FirstField = 0;
              strncpy(FirstLine,"",MAXLINELEN);
              if(!stdio_flag) {
                fclose(fptr);
              }
            }
            else
              goto look_again;

            /* if not the last file in the list, move on to the next one */

            if(lst_ptr->next_file != (struct file_list *)NULL) {
               tmp_ptr = lst_ptr->next_file;
               lst_ptr = tmp_ptr;
            }

          }
        }
      }
      /* if not the last station-channel-network in the list,
         move on to the next one */
      if(i < (scns->nscn-1)) {
        flst_ptr = flst_ptr->ptr_next;
        lst_ptr = flst_ptr->first_list;
        i++;
        scn = scns->scn_vec[i];
        goto next_scn;
      }
      if(!stdio_flag)
	free_matched_files(output_files);

      /* allocated one too many responses */

      free_response(resp);
      if(prev_ptr != (struct response *)NULL)
        prev_ptr->next = (struct response *)NULL;

    } /* end else if mode */

  }  /* end for loop */

         /* added file close if single input file -- 2/13/2006 -- [ET]: */
  if(!mode && !stdio_flag)        /* if single file was opened then */
    fclose(fptr);                 /* close input file */

  /* and print a list of WARNINGS about the station-channel pairs that were not
     found in the input RESP files */

  for(i = 0; i < scns->nscn; i++) {
    scn = scns->scn_vec[i];
    if(!scn->found) {
      fprintf(stderr,"%s WARNING: no response found for NET=%s,STA=%s,LOCID=%s,CHAN=%s,DATE=%s\n",
              myLabel, scn->network, scn->station, scn->locid, scn->channel, date_time);
      fflush(stderr);
    }
  }
  free_scn_list(scns);
  if(flst_head != (struct matched_files *)NULL)
    free_matched_files(flst_head);
  free_string_array(chan_list);
  free_string_array(locid_list);
  free_string_array(sta_list);

  free(freqs_orig);               /* added 3/28/2006 -- [ET] */

  return(first_resp);

}