Example #1
0
File: pc2.c Project: huaguang/OS_CD
void *consume(void *arg)
{
    int i;
    int item;

    for (i = 0; i < ITEM_COUNT; i++) {
        sema_wait(&full_buffer2_sema);
		sema_wait(&buffer2_mutex_sema);
        item = get_item(&conOut,buffer2); 
		sema_signal(&buffer2_mutex_sema);
        sema_signal(&empty_buffer2_sema);
        printf("          consume item: %c\n", item);
    }
}
Example #2
0
File: pc2.c Project: huaguang/OS_CD
void *produce(void*args)
{
    int i;
    int item;
    for (i = 0; i < ITEM_COUNT; i++) {
        sema_wait(&empty_buffer1_sema);
        sema_wait(&buffer1_mutex_sema);
        item = i + 'a';
        put_item(item,&pIn,buffer1);
        sema_signal(&buffer1_mutex_sema);
        sema_signal(&full_buffer1_sema);
        printf("produce item: %c\n", item);
    }
}
Example #3
0
File: mttest.c Project: dhaley/dcp
void
resolve_symbols()
{
	void *foo;
	global_cond_flag = TRUE;
#ifdef SOLARIS
	mutex_lock(&queue_lock);
	mutex_trylock(&queue_lock);
	mutex_unlock(&queue_lock);
	foo = (void *)&cond_signal;
	foo = (void *)&cond_wait;
	foo = (void *)&cond_timedwait;
	sema_post(&global_sema_lock);
	sema_wait(&global_sema_lock); 
	rw_rdlock(&global_rw_lock);
	rw_unlock(&global_rw_lock);
	rw_wrlock(&global_rw_lock);
	rw_unlock(&global_rw_lock);
#endif
#ifdef POSIX
	pthread_mutex_lock(&queue_lock);
	pthread_mutex_trylock(&queue_lock);
	pthread_mutex_unlock(&queue_lock);
	foo = (void *)&pthread_cond_signal;
	foo = (void *)&pthread_cond_wait;
	foo = (void *)&pthread_cond_timedwait;
	sem_post(&global_sema_lock);
	sem_wait(&global_sema_lock); 
#endif
}
Example #4
0
File: mttest.c Project: dhaley/dcp
/* sema_global: use a global semaphore to process array's data */
void
sema_global(Workblk *array, struct scripttab *k)
{
#ifdef SOLARIS
	sema_wait(&global_sema_lock); 
#endif
#ifdef POSIX
	sem_wait(&global_sema_lock); 
#endif

	array->ready = gethrtime();
	array->vready = gethrvtime();

	array->compute_ready = array->ready;
	array->compute_vready = array->vready;

	/* do some work on the current array */
	(k->called_func)(&array->list[0]);

	array->compute_done = gethrtime();
	array->compute_vdone = gethrvtime();

#ifdef SOLARIS
	sema_post(&global_sema_lock);
#endif
#ifdef POSIX
	sem_post(&global_sema_lock);
#endif

	/* make another call to preclude tail-call optimization on the unlock */
	(void) gethrtime();
}
Example #5
0
int
barrier_wait(barrier_t *bar)
{
	pthread_mutex_lock(&bar->bar_lock);

	if (++bar->bar_numin < bar->bar_nthr) {
		pthread_mutex_unlock(&bar->bar_lock);
#if defined(sun)
		sema_wait(&bar->bar_sem);
#else
		sem_wait(&bar->bar_sem);
#endif

		return (0);

	} else {
		int i;

		/* reset for next use */
		bar->bar_numin = 0;
		for (i = 1; i < bar->bar_nthr; i++)
#if defined(sun)
			sema_post(&bar->bar_sem);
#else
			sem_post(&bar->bar_sem);
#endif
		pthread_mutex_unlock(&bar->bar_lock);

		return (1);
	}
}
Example #6
0
/*
 * Attempt to negotiate the caller-specified NVSP version
 *
 * For NVSP v2, Server 2008 R2 does not set
 * init_pkt->msgs.init_msgs.init_compl.negotiated_prot_vers
 * to the negotiated version, so we cannot rely on that.
 */
static int
hv_nv_negotiate_nvsp_protocol(struct hv_device *device, netvsc_dev *net_dev,
    uint32_t nvsp_ver)
{
	nvsp_msg *init_pkt;
	int ret;

	init_pkt = &net_dev->channel_init_packet;
	memset(init_pkt, 0, sizeof(nvsp_msg));
	init_pkt->hdr.msg_type = nvsp_msg_type_init;

	/*
	 * Specify parameter as the only acceptable protocol version
	 */
	init_pkt->msgs.init_msgs.init.p1.protocol_version = nvsp_ver;
	init_pkt->msgs.init_msgs.init.protocol_version_2 = nvsp_ver;

	/* Send the init request */
	ret = hv_vmbus_channel_send_packet(device->channel, init_pkt,
	    sizeof(nvsp_msg), (uint64_t)(uintptr_t)init_pkt,
	    HV_VMBUS_PACKET_TYPE_DATA_IN_BAND,
	    HV_VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED);
	if (ret != 0)
		return (-1);

	sema_wait(&net_dev->channel_init_sema);

	if (init_pkt->msgs.init_msgs.init_compl.status != nvsp_status_success)
		return (EINVAL);

	return (0);
}
FINLINE int _sema_wait(
	sema_t *			pSem)
{
	int	iErr = 0;

	for( ;;)
	{
		if( (iErr = sema_wait( pSem)) != 0)
		{
			if( iErr == EINTR)
			{
				iErr = 0;
				continue;
			}
			else
			{
				f_assert( 0);
				goto Exit;
			}
		}

		break;
	}

Exit:

	return( iErr);
}
u32 _rtw_down_sema(_sema *sema)
{

#ifdef PLATFORM_LINUX
	
	if (down_interruptible(sema))
		return _FAIL;
	else
		return _SUCCESS;

#endif    	
#ifdef PLATFORM_FREEBSD
	sema_wait(sema);
	return  _SUCCESS;
#endif
#ifdef PLATFORM_OS_XP

	if(STATUS_SUCCESS == KeWaitForSingleObject(sema, Executive, KernelMode, TRUE, NULL))
		return  _SUCCESS;
	else
		return _FAIL;
#endif

#ifdef PLATFORM_OS_CE
	if(WAIT_OBJECT_0 == WaitForSingleObject(*sema, INFINITE ))
		return _SUCCESS; 
	else
		return _FAIL;
#endif
}
Example #9
0
/*
 * Attempt to negotiate the caller-specified NVSP version
 *
 * For NVSP v2, Server 2008 R2 does not set
 * init_pkt->msgs.init_msgs.init_compl.negotiated_prot_vers
 * to the negotiated version, so we cannot rely on that.
 */
static int
hv_nv_negotiate_nvsp_protocol(struct hn_softc *sc, netvsc_dev *net_dev,
    uint32_t nvsp_ver)
{
	nvsp_msg *init_pkt;
	int ret;

	init_pkt = &net_dev->channel_init_packet;
	memset(init_pkt, 0, sizeof(nvsp_msg));
	init_pkt->hdr.msg_type = nvsp_msg_type_init;

	/*
	 * Specify parameter as the only acceptable protocol version
	 */
	init_pkt->msgs.init_msgs.init.p1.protocol_version = nvsp_ver;
	init_pkt->msgs.init_msgs.init.protocol_version_2 = nvsp_ver;

	/* Send the init request */
	ret = vmbus_chan_send(sc->hn_prichan,
	    VMBUS_CHANPKT_TYPE_INBAND, VMBUS_CHANPKT_FLAG_RC,
	    init_pkt, sizeof(nvsp_msg), (uint64_t)(uintptr_t)init_pkt);
	if (ret != 0)
		return (-1);

	sema_wait(&net_dev->channel_init_sema);

	if (init_pkt->msgs.init_msgs.init_compl.status != nvsp_status_success)
		return (EINVAL);

	return (0);
}
Example #10
0
hot_err_t hot_sema_Dec(hot_sema_t sema) {
  assert(sema) ;
  
  if (sema_wait(&sema->sema))
    return hot_err_Create(0, "hot_sema_Inc: sema_wait");
  
  return HOT_OK;
}
Example #11
0
void* ring(void*arg){
	int *id;
	int content;
	id=(int*)arg;
	char flag=0;// is my mail?
	int circle=circleCount;
	while(circle>0){
		sema_wait(&read_sema);
		if(readCount==0)
			sema_wait(&write_sema);
		readCount++;
		sema_signal(&read_sema);
		if(*id==((mailBox[0]-1)%N+1)){
			flag=1;
			content=mailBox[1];
		}
		sema_wait(&read_sema);
		readCount--;
		if(readCount==0) 
			sema_signal(&write_sema);
		sema_signal(&read_sema);
		if(flag==1){
			sema_wait(&write_sema);
			mailBox[0]=*id+1;
			mailBox[1]=content+1;
			sema_signal(&write_sema);
			int i;
		/*	for(i=0;i<*id-1;i++)
				printf("\t");
			printf("this is thread_%d:Receive:%d;Send:%d\n",*id,content,content+1);

		*/
			assert(*id==content%N+1);

			flag=0;
			circle--;
		//	if(circle%10==0)
		//		printf("%d\n",circle);
		}
		else{
			usleep(sleepTime);
		}
	}
}
Example #12
0
File: pc2.c Project: huaguang/OS_CD
void *calculate(void *arg)
{
    int i;
    int item;
    for (i = 0; i < ITEM_COUNT; i++) {
        sema_wait(&full_buffer1_sema);
        sema_wait(&buffer1_mutex_sema);
        item = get_item(&calOut,buffer1); 
        sema_signal(&buffer1_mutex_sema);
        sema_signal(&empty_buffer1_sema);
		item=item+'A'-'a';
        sema_wait(&empty_buffer2_sema);
        sema_wait(&buffer2_mutex_sema);
        put_item(item,&calIn,buffer2); 
        sema_signal(&buffer2_mutex_sema);
        sema_signal(&full_buffer2_sema);
        printf("    calculate item: %c\n", item);
    }
}
Example #13
0
/*
 * RNDIS filter init device
 */
static int
hv_rf_init_device(rndis_device *device)
{
	rndis_request *request;
	rndis_initialize_request *init;
	rndis_initialize_complete *init_complete;
	uint32_t status;
	int ret;

	request = hv_rndis_request(device, REMOTE_NDIS_INITIALIZE_MSG,
	    RNDIS_MESSAGE_SIZE(rndis_initialize_request));
	if (!request) {
		ret = -1;
		goto cleanup;
	}

	/* Set up the rndis set */
	init = &request->request_msg.msg.init_request;
	init->major_version = RNDIS_MAJOR_VERSION;
	init->minor_version = RNDIS_MINOR_VERSION;
	/*
	 * Per the RNDIS document, this should be set to the max MTU
	 * plus the header size.  However, 2048 works fine, so leaving
	 * it as is.
	 */
	init->max_xfer_size = 2048;
	
	device->state = RNDIS_DEV_INITIALIZING;

	ret = hv_rf_send_request(device, request, REMOTE_NDIS_INITIALIZE_MSG);
	if (ret != 0) {
		device->state = RNDIS_DEV_UNINITIALIZED;
		goto cleanup;
	}

	sema_wait(&request->wait_sema);

	init_complete = &request->response_msg.msg.init_complete;
	status = init_complete->status;
	if (status == RNDIS_STATUS_SUCCESS) {
		device->state = RNDIS_DEV_INITIALIZED;
		ret = 0;
	} else {
		device->state = RNDIS_DEV_UNINITIALIZED; 
		ret = -1;
	}

cleanup:
	if (request) {
		hv_put_rndis_request(device, request);
	}

	return (ret);
}
Example #14
0
/*
 * RNDIS filter query device
 */
static int
hv_rf_query_device(rndis_device *device, uint32_t oid, void *result,
		   uint32_t *result_size)
{
	rndis_request *request;
	uint32_t in_result_size = *result_size;
	rndis_query_request *query;
	rndis_query_complete *query_complete;
	int ret = 0;

	*result_size = 0;
	request = hv_rndis_request(device, REMOTE_NDIS_QUERY_MSG,
	    RNDIS_MESSAGE_SIZE(rndis_query_request));
	if (request == NULL) {
		ret = -1;
		goto cleanup;
	}

	/* Set up the rndis query */
	query = &request->request_msg.msg.query_request;
	query->oid = oid;
	query->info_buffer_offset = sizeof(rndis_query_request); 
	query->info_buffer_length = 0;
	query->device_vc_handle = 0;

	ret = hv_rf_send_request(device, request, REMOTE_NDIS_QUERY_MSG);
	if (ret != 0) {
		/* Fixme:  printf added */
		printf("RNDISFILTER request failed to Send!\n");
		goto cleanup;
	}

	sema_wait(&request->wait_sema);

	/* Copy the response back */
	query_complete = &request->response_msg.msg.query_complete;
	
	if (query_complete->info_buffer_length > in_result_size) {
		ret = EINVAL;
		goto cleanup;
	}

	memcpy(result, (void *)((unsigned long)query_complete +
	    query_complete->info_buffer_offset),
	    query_complete->info_buffer_length);

	*result_size = query_complete->info_buffer_length;

cleanup:
	if (request != NULL)
		hv_put_rndis_request(device, request);

	return (ret);
}
Example #15
0
int
sem_wait(sem_t *sem)
{
	int	error;

	if (sem_invalid(sem))
		return (-1);
	if ((error = sema_wait((sema_t *)sem)) != 0) {
		errno = error;
		return (-1);
	}
	return (0);
}
Example #16
0
File: dma.c Project: koson/mchck-os
void
main(void)
{
        adc_init();
        dma_init();
        enter_thread_mode();

        sema_wait(&adc_start_sema);

        struct dma_ctx *ctx;
        ctx = dma_setup(DMAMUX_ADC0, &ADC_R_REG(ADC0, 0), dstbuf, 2, sizeof(dstbuf)/2, DMA_SRC_STICKY | DMA_DOUBLEBUF | DMA_LOOP, dma_done, NULL);

        adc_sample_prepare(ADC_MODE_CONTINUOUS);
        bf_set_reg(ADC_SC2_REG(ADC0), ADC_SC2_DMAEN, 1);
        ADC_SC1_REG(ADC0, 0) = ADC_SC1_ADCH(0) | ADC_SC1_DIFF_MASK;

        wait(main);
}
/* Below is a pair of functions for making sure data is safely
 * on disk by flushing the adapter's cache. */
static int ips_send_flush_cache_cmd(ips_command_t *command)
{
	ips_softc_t *sc = command->sc;
	ips_generic_cmd *command_struct;

	PRINTF(10,"ips test: got a command, building flush command\n");
	command->callback = ips_wakeup_callback;
	command_struct = (ips_generic_cmd *)command->command_buffer;
	command_struct->command = IPS_CACHE_FLUSH_CMD;
	command_struct->id = command->id;
	bus_dmamap_sync(sc->command_dmatag, command->command_dmamap, 
			BUS_DMASYNC_PREWRITE);
	sc->ips_issue_cmd(command);
	if (COMMAND_ERROR(command) == 0)
		sema_wait(&sc->cmd_sema);
	ips_insert_free_cmd(sc, command);
	return 0;
}
static int ips_send_ffdc_reset_cmd(ips_command_t *command)
{
	ips_softc_t *sc = command->sc;
	ips_adapter_ffdc_cmd *command_struct;

	PRINTF(10,"ips test: got a command, building ffdc reset command\n");
	command->callback = ips_wakeup_callback;
	command_struct = (ips_adapter_ffdc_cmd *)command->command_buffer;
	command_struct->command = IPS_FFDC_CMD;
	command_struct->id = command->id;
	command_struct->reset_count = sc->ffdc_resetcount;
	command_struct->reset_type  = 0x0;
	ips_ffdc_settime(command_struct, sc->ffdc_resettime.tv_sec);

	bus_dmamap_sync(sc->command_dmatag, command->command_dmamap,
			BUS_DMASYNC_PREWRITE);
	sc->ips_issue_cmd(command);
	if (COMMAND_ERROR(command) == 0)
		sema_wait(&sc->cmd_sema);
	ips_insert_free_cmd(sc, command);
	return 0;
}
Example #19
0
int main(int argc, char *argv[])
{
    /* find the argument to -c then strip the talon related front section */

    char *recipe = NULL;
    int talon_returncode = 0;

    /* Now take settings from the environment (having potentially modified it) */
    if (talon_getenv("TALON_DEBUG"))
        loglevel=LOGDEBUG;


    int enverrors = 0;

    char *buildid = talon_getenv("TALON_BUILDID");
    if (!buildid)
    {
        error("error: %s", "TALON_BUILDID not set in environment\n");
        enverrors++;
    }

    talon_sem.name = buildid;
    talon_sem.timeout = 999999990;




    int x;
    debug("debug: %s", "WAITING ON SEMAPHORE\n");
    x = sema_wait(&talon_sem);
    if (x == 0)
    {
        debug("debug: %s", "SEMAPHORE OBTAINED\n");
        getchar();
        sema_release(&talon_sem);
        debug("debug: %s", "SEMAPHORE RELEASED\n");
    }
}
/*************************************************
  vision-serverの本体
    Cameraデータの取得、画像処理、ソケット通信待ち受けを行う
************************************************/
int main (int argc, char **argv){
  CvSize size;
  int step;
  CvCapture *cap;
  IplImage *capture_image;
  IplImage *frame_image;
  IplImage *processed_image;
  IplImage *grayImage; 
  IplImage *binaryImage;
  unsigned char* binarydata;

  CvFont font;
  char text[50];
  char hostname[30];
  int s, i, port = 9000;
  pthread_t tid;

  /*** socket通信のための処理(ここから) ***/
  for (i=1;i<argc;i++){
    if (strcmp("-port", argv[i]) == 0) {
      port=atoi(argv[++i]);
    }}
  gethostname(hostname, sizeof(hostname));
  s = init_socket_server(hostname, &port);
  fprintf(stderr, "hostname %s\n", hostname);
  for (i=0; i< MAX_SOCKET ; i++) sockets[i].type=0;
  //threadで待ちうけ
  fprintf(stderr, "Waiting connection...\n");
  pthread_create(&tid, NULL, acceptor, (void *)s);
  /*** socket通信のための処理(ここまで) ***/

  /** semaphoreの準備 ***/
  raw_semaphore = semget((key_t)1111, 1, 0666|IPC_CREAT);
  if(raw_semaphore == -1){
    perror("semget failure");
    exit(EXIT_FAILURE);
  }
  process_semaphore = semget((key_t)1111, 1, 0666|IPC_CREAT);
  if(process_semaphore == -1){
    perror("semget failure");
    exit(EXIT_FAILURE);
  }
  union semun semunion;
  semunion.val = 0;  //semaphoreの初期値
  if(semctl(raw_semaphore, 0, SETVAL, semunion) == -1){
    perror("semctl(init) failure");
    exit(EXIT_FAILURE);
  }
  if(semctl(process_semaphore, 0, SETVAL, semunion) == -1){
    perror("semctl(init) failure");
    exit(EXIT_FAILURE);
  }
  /** semaphoreの準備(ここまで) ***/

  /** cameraや画像取得の用意(ここから) ***/
  //camera initialization 
  if((cap = cvCreateCameraCapture(-1))==NULL){
    printf("Couldn't find any camera.\n");
    return -1;
  }
  capture_image = cvQueryFrame(cap);
  width = capture_image->width;
  height = capture_image->height;
  fprintf(stderr, "height %d, width %d\n", height, width);
  fprintf(stderr, "process height %d, process width %d\n", process_height, process_width);
  /** cameraや画像取得の用意(ここまで) ***/

  /** 画像処理(赤色抽出)の準備 ***/
  //fontの設定(しないとSegfaultで落ちる)
  float hscale = 1.0f;
  float vscale = 1.0f;
  float italicscale = 0.0f;
  int thickness = 3;
  cvInitFont(&font, CV_FONT_HERSHEY_COMPLEX, hscale, vscale, italicscale, thickness, CV_AA);
  //font設定ここまで
  // Set threshold
  rgb_thre[0] = R_MIN_THRE;
  rgb_thre[1] = R_MAX_THRE;
  rgb_thre[2] = G_MIN_THRE;
  rgb_thre[3] = G_MAX_THRE;
  rgb_thre[4] = B_MIN_THRE;
  rgb_thre[5] = B_MAX_THRE;


  //画像処理するイメージ領域を確保
  frame_image = cvCreateImage(cvSize(process_width, process_height), IPL_DEPTH_8U, 3);
  processed_image = cvCreateImage(cvSize(process_width, process_height), IPL_DEPTH_8U, 3);
  /** 画像処理(赤色抽出)の準備(ここまで) ***/

  
  /**** 面積を出すための2値化 ***/
  grayImage = cvCreateImage(cvGetSize(frame_image), IPL_DEPTH_8U, 1);
  binaryImage = cvCreateImage(cvGetSize(frame_image), IPL_DEPTH_8U, 1);
  
  //Labeling init
  label_buf = (int*)malloc(sizeof(int)*frame_image->width*frame_image->height);

  /**** main loop(本体) ****/
  while(1){
    CvPoint centroid;
    //カメラ画像をcaptureする
    capture_image = cvQueryFrame(cap);
    if (capture_image==NULL) {
      fprintf(stderr, "capture_image is %p\n", capture_image);
      continue;
    }
    cvResize(capture_image, frame_image, CV_INTER_LINEAR);

    //カメラ画像を処理する
    maskRGB(frame_image, processed_image, rgb_thre);          //赤色抽出
    // Binarize
    myBinarize(processed_image, grayImage, binaryImage);
    cvDilate(binaryImage, grayImage, NULL, 10); //ぼうちょう
    cvErode(grayImage, binaryImage, NULL, 15);  //収縮
    // Labeling
    cvGetRawData(binaryImage, &binarydata, &step, &size);
    labeling(binarydata, frame_image->height, frame_image->width, label_buf, step);
    label_num = labeling_result(&linfo, label_buf, frame_image->height, frame_image->width);
    //処理結果を書き込む
    {
      int i,n;
      n=25;
      //fprintf(stderr, "num is %d\n", label_num);
      for(i=0; i<label_num; i++){
        //fprintf(stderr, "area %d, x %d y %d\n", linfo[i].area, (int)linfo[i].xpos, (int)linfo[i].ypos);
        centroid.x = (int) linfo[i].xpos;
        centroid.y = (int) linfo[i].ypos;
        drawCross(processed_image, &centroid, CV_RGB(0, 255, 0));                                 //×印をいれる
        sprintf(text, "X: %d Y: %d AREA: %d", centroid.x, centroid.y, linfo[i].area);             //値をかく
        cvPutText(processed_image, text, cvPoint(n, (height-n*(i+1))), &font, CV_RGB(0, 255, 0)); //
      }
    }
    // image -> rawdata
    sema_wait(raw_semaphore);
    cvGetRawData(frame_image, &rawdata, &step, &size);
    
    // process image -> process data
    sema_wait(process_semaphore);
    cvGetRawData(processed_image, &processdata, &step, &size);

    //sleep
    usleep(30000);
  }
  //release the capture object
  cvReleaseCapture(&cap);
  return 0;
}
Example #21
0
int main(int argc, char *argv[])
{
	/* find the argument to -c then strip the talon related front section */

	char *recipe = NULL;
	int talon_returncode = 0;

#ifdef HAS_WINSOCK2
	WSADATA wsaData;

	WSAStartup(MAKEWORD(2,2), &wsaData);

	/* We ignore the result as we are only doing this to use gethostname
	   and if that fails then leaving the host attribute blank is perfectly
	   acceptable.
	*/

#endif

#ifdef HAS_GETCOMMANDLINE
	char *commandline= GetCommandLine();
	/*
	 * The command line should be either,
	 * talon -c "some shell commands"
	 * or
	 * talon shell_script_file
	 *
	 * talon could be an absolute path and may have a .exe extension.
	 */

	
	recipe = chompCommand(commandline);
	if (recipe)
	{
		/* there was a -c so extract the quoted commands */

		int recipelen = strlen(recipe);
		if (recipelen > 0 && recipe[recipelen - 1] == '"')
			recipe[recipelen - 1] = '\0'; /* remove trailing quote */
	}
	else
	{
		/* there was no -c so extract the argument as a filename */

		recipe = strstr(commandline, "talon");
		if (recipe)
		{
			/* find the first space */
			while (!isspace(*recipe) && *recipe != '\0')
				recipe++;
			/* skip past the spaces */
			while (isspace(*recipe))
				recipe++;

			recipe = read_recipe_from_file(recipe);

			if (!recipe)
			{
			    error("talon: error: bad script file in shell call '%s'\n", commandline);
				return 1;
			}
		}
		else
		{
			error("talon: error: no 'talon' in shell call '%s'\n", commandline);
			return 1;
		}
	}
#else
	/*
	 * The command line should be either,
	 * talon -c "some shell commands"
	 * or
	 * talon shell_script_file
	 *
	 * talon could be an absolute path and may have a .exe extension.
	 */
	switch (argc)
	{
		case 2:
			recipe = read_recipe_from_file(argv[1]);
			break;
		case 3:
			if (strcmp("-c", argv[1]) != 0)
			{
				error("talon: error: %s\n", "usage is 'talon -c command' or 'talon script_filename'");
				return 1;
			}
			recipe = argv[2];
			break;
		default:
			error("talon: error: %s\n", "usage is 'talon -c command' or 'talon script_filename'");
			return 1;
	}
#endif

	/* did we get a recipe at all? */
	if (!recipe)
	{
		error("talon: error: %s", "no recipe supplied to the shell.\n");
		return 1;
	}

	/* remove any leading white space on the recipe */
	while (isspace(*recipe))
		recipe++;

	/* turn debugging on? */
	char *debugstr=talon_getenv("TALON_DEBUG");

	if (debugstr)
	{
		loglevel=LOGDEBUG;
		free(debugstr); debugstr=NULL;
	}

	DEBUG(("talon: recipe: %s\n", recipe));

	/* Make sure that the agent's hostname can be put into the host attribute */
	char hostname[HOSTNAME_MAX];
	int hostresult=0;
	
	hostresult = gethostname(hostname, HOSTNAME_MAX-1);
	if (0 != hostresult)
	{
		DEBUG(("talon: failed to get hostname: %d\n", hostresult));
		hostname[0] = '\0';
	}

	talon_setenv("HOSTNAME", hostname);
	DEBUG(("talon: setenv: hostname: %s\n", hostname));

	
	char varname[VARNAMEMAX];
	char varval[VARVALMAX];
	int dotagging = 0; 
	int force_descramble_off = 0;

	char  *rp = recipe;
	if (*rp == TALONDELIMITER) {
		dotagging = 1; 

		/* there are some talon-specific settings 
		 * in the command which must be stripped */
		rp++;
		char *out = varname;
		char *stopout = varname + VARNAMEMAX - 1;
		DEBUG(("talon: parameters found\n"));
		while (*rp != '\0')
		{
			
			switch (*rp) {
				case  '=':
					*out = '\0';
					DEBUG(("talon: varname: %s\n",varname));
					out = varval;
					stopout = varval + VARVALMAX - 1;
					break;
				case ';':
					*out = '\0';
					DEBUG(("talon: varval: %s\n",varval));
					talon_setenv(varname, varval);
					out = varname;
					stopout = varname + VARNAMEMAX - 1;
					break;
				default:	
					*out = *rp;
					if (out < stopout)
						out++;
					break;
			}

			if (*rp == TALONDELIMITER)
			{
				rp++;
				break;
			}
			
			rp++;
		}
	} else {
		/* This is probably a $(shell) statement 
 		 * in make so no descrambling needed and 
 		 * tags are definitely not wanted as they 
 		 * would corrupt the expected output*/
		force_descramble_off = 1; 
	}


	/* Now take settings from the environment (having potentially modified it) */	
	if (talon_getenv("TALON_DEBUG"))
		loglevel=LOGDEBUG;
	

	int enverrors = 0;

	char *shell = talon_getenv("TALON_SHELL");
	if (!shell)
	{
		error("error: %s", "TALON_SHELL not set in environment\n");
		enverrors++;	
	}

	int timeout = -1;
	char *timeout_str = talon_getenv("TALON_TIMEOUT");
	if (timeout_str)
	{
		timeout = atoi(timeout_str);
		free(timeout_str); timeout_str = NULL;
	}

	char *buildid = talon_getenv("TALON_BUILDID");
	if (!buildid)
	{
		error("error: %s", "TALON_BUILDID not set in environment\n");
		enverrors++;	
	}

	char *attributes = talon_getenv("TALON_RECIPEATTRIBUTES");
	if (!attributes)
	{
		error("error: %s", "TALON_RECIPEATTRIBUTES not set in environment\n");
		enverrors++;
	}


	int max_retries = 0;
	char *retries_str = talon_getenv("TALON_RETRIES");
	if (retries_str)
	{
		max_retries = atoi(retries_str);
		free(retries_str); retries_str = NULL;
	}	


	int descramble = 0;
	if (! force_descramble_off )
	{
		char *descramblestr = talon_getenv("TALON_DESCRAMBLE");
		if (descramblestr)
		{
			if (*descramblestr == '0')
				descramble = 0;
			else
				descramble = 1;
		
			free(descramblestr); descramblestr = NULL;
		}
	}

	/* check command line lengths if a maximum is supplied */
	int shell_cl_max = 0;
	char *shell_cl_max_str = talon_getenv("TALON_SHELL_CL_MAX");
	if (shell_cl_max_str)
	{
		shell_cl_max = atoi(shell_cl_max_str);
		free(shell_cl_max_str); shell_cl_max_str = NULL;
	}


	/* Talon can look in a flags variable to alter its behaviour */
	int force_success = 0;
	char *flags_str = talon_getenv("TALON_FLAGS");
	if (flags_str)
	{
		int c;
		for (c=0; flags_str[c] !=0; c++)
			flags_str[c] = tolower(flags_str[c]);

		if (strstr(flags_str, "forcesuccess"))
			force_success = 1;

		/* don't put <recipe> or <CDATA<[[ tags around the output. e.g. if it's XML already*/
		if (strstr(flags_str, "rawoutput"))
		{
			dotagging = 0;
		}

		free(flags_str); flags_str = NULL;
	}	

	/* Talon subprocesses need to have the "correct" shell variable set. */
	talon_setenv("SHELL", shell); 

	/* we have allowed some errors to build up so that the user
	 * can see all of them before we stop and force the user 
	 * to fix them
	 */
	if (enverrors)
	{
		return 1;
	}

	
	/* Run the recipe repeatedly until the retry count expires or
	 * it succeeds.
	 */
	int attempt = 0, retries = max_retries;
	proc *p = NULL;

	char *args[5];

	char *qrp=rp;

#ifdef HAS_GETCOMMANDLINE
	/* re-quote the argument to -c since this helps windows deal with it */
	int qrpsize = strlen(rp) + 3;
	qrp = malloc(qrpsize);
	qrp[0] = '"';
	strcpy(&qrp[1], rp);
	qrp[qrpsize-2] = '"';
	qrp[qrpsize-1] = '\0';
#endif

	int index = 0;
	args[index++] = shell;

	if (dotagging)  /* don't do bash -x for non-tagged commands e.g. $(shell output) */
		args[index++] = "-x";

	args[index++] = "-c";
	args[index++] = qrp;
	args[index++] = NULL;

	/* get the semaphore ready */
	talon_sem.name = buildid;
	talon_sem.timeout = timeout;
	do
	{
		char talon_attempt[TALON_ATTEMPT_STRMAX];
		double start_time = getseconds();
		
		attempt++;
		
		snprintf(talon_attempt, TALON_ATTEMPT_STRMAX-1, "%d", attempt);
		talon_attempt[TALON_ATTEMPT_STRMAX - 1] = '\0';

		talon_setenv("TALON_ATTEMPT", talon_attempt);
		
		p = process_run(shell, args, timeout);

		double end_time = getseconds();
		
		if (p) 
		{
			talon_returncode = p->returncode;

			if (dotagging) 
			{
				char status[STATUS_STRMAX];
				char timestat[STATUS_STRMAX];
				char warning[WARNING_STRMAX];
				warning[0] = '\0';

				if (shell_cl_max)
				{
					int cl_actual = strlen(qrp);
					if (cl_actual > shell_cl_max)
						{
						snprintf(warning, WARNING_STRMAX-1, \
							"\n<warning>Command line length '%d' exceeds the shell limit on this system of '%d'.  " \
							"If this recipe is a compile, try using the '.use_compilation_command_file' variant to reduce overall command line length.</warning>", \
							cl_actual, shell_cl_max);
						warning[WARNING_STRMAX-1] = '\0';
						}
				}

				char *flagsstr = force_success == 0 ? "" : " flags='FORCESUCCESS'";
				char *reasonstr = "" ;

				if (p->causeofdeath == PROC_TIMEOUTDEATH)
					reasonstr = " reason='timeout'";

				if (p->returncode != 0)
				{
					char *exitstr = (force_success || retries <= 0) ? "failed" : "retry";
					snprintf(status, STATUS_STRMAX - 1, "\n<status exit='%s' code='%d' attempt='%d'%s%s />", exitstr, p->returncode, attempt, flagsstr, reasonstr );
				} else {
					snprintf(status, STATUS_STRMAX - 1, "\n<status exit='ok' attempt='%d'%s%s />", attempt, flagsstr, reasonstr );
				}
				status[STATUS_STRMAX-1] = '\0';
	
				snprintf(timestat, STATUS_STRMAX - 1, "<time start='%.5f' elapsed='%.3f' />",start_time, end_time-start_time );
				timestat[STATUS_STRMAX-1] = '\0';

				prependattributes(p->output, attributes);
			
				buffer_append(p->output, "\n]]>", 4);
				buffer_append(p->output, timestat, strlen(timestat));
				buffer_append(p->output, status, strlen(status));
				buffer_append(p->output, warning, strlen(warning));
				buffer_append(p->output, "\n</recipe>\n", 11);
			}
		
			unsigned int iterator = 0;
			unsigned int written = 0;
			byteblock *bb;
			char sub[7] = "&#x00;";
			
			if (descramble)	
				sema_wait(&talon_sem);
			while ((bb = buffer_getbytes(p->output, &iterator)))
			{
				if (bb->fill < 1)
					continue;		/* empty buffer */
					
				if (dotagging)
				{
					/* the output is XML so we must replace any non-printable characters */
					char *ptr = &bb->byte0;
					char *end = ptr + bb->fill;

					char *start = ptr;
					
					while (ptr < end)
					{
						if ((*ptr < 32 || *ptr > 126) && *ptr != 9 && *ptr != 10 && *ptr != 13)
						{
							/* output any unwritten characters before this non-printable */
							if (ptr > start)
								write(STDOUT_FILENO, start, ptr - start);
							
							/* 0->&#x00; 1->&#x01; ... 255->&#xff; */
							sprintf(sub, "&#x%02x;", (unsigned char)*ptr);
							
							/* output the modified non-printable character */
							write(STDOUT_FILENO, sub, 6);
							start = ptr + 1;
						}
						ptr++;
					}
					if (ptr > start)
						write(STDOUT_FILENO, start, ptr - start);
				}
				else
				{
					/* the output isn't XML so write out the whole buffer as-is */
					
					written = write(STDOUT_FILENO, &bb->byte0, bb->fill);

					DEBUG(("talon: wrote %d bytes out of %d\n", written, bb->fill));
				}
			}
			if (descramble)	
				sema_release(&talon_sem);
		
		
			if (p->returncode == 0 || force_success)
			{
				process_free(&p);
				break;
			}

			process_free(&p);
		} else {
			error("error: failed to run shell: %s: check the SHELL environment variable.\n", args[0]);
			return 1;
		}

		retries--;
	}
	while (retries >= 0);

	if (buildid) free(buildid); buildid = NULL;
	if (attributes) free(attributes); attributes = NULL;
	if (shell) free(shell); shell = NULL;

	if (force_success)
		return 0;
	else 
		return talon_returncode;
}
int my_sema_wait(void *semptr) {
  if (semptr != NULL)
    return (sema_wait((sema_t *)semptr));
  else
    return (-1);
}
Example #23
0
/*
 * Net VSC initialize receive buffer with net VSP
 * 
 * Net VSP:  Network virtual services client, also known as the
 *     Hyper-V extensible switch and the synthetic data path.
 */
static int 
hv_nv_init_rx_buffer_with_net_vsp(struct hn_softc *sc)
{
	netvsc_dev *net_dev;
	nvsp_msg *init_pkt;
	int ret = 0;

	net_dev = hv_nv_get_outbound_net_device(sc);
	if (!net_dev) {
		return (ENODEV);
	}

	net_dev->rx_buf = hyperv_dmamem_alloc(bus_get_dma_tag(sc->hn_dev),
	    PAGE_SIZE, 0, net_dev->rx_buf_size, &net_dev->rxbuf_dma,
	    BUS_DMA_WAITOK | BUS_DMA_ZERO);
	if (net_dev->rx_buf == NULL) {
		device_printf(sc->hn_dev, "allocate rxbuf failed\n");
		return ENOMEM;
	}

	/*
	 * Connect the RXBUF GPADL to the primary channel.
	 *
	 * NOTE:
	 * Only primary channel has RXBUF connected to it.  Sub-channels
	 * just share this RXBUF.
	 */
	ret = vmbus_chan_gpadl_connect(sc->hn_prichan,
	    net_dev->rxbuf_dma.hv_paddr, net_dev->rx_buf_size,
	    &net_dev->rx_buf_gpadl_handle);
	if (ret != 0) {
		device_printf(sc->hn_dev, "rxbuf gpadl connect failed: %d\n",
		    ret);
		goto cleanup;
	}
	
	/* sema_wait(&ext->channel_init_sema); KYS CHECK */

	/* Notify the NetVsp of the gpadl handle */
	init_pkt = &net_dev->channel_init_packet;

	memset(init_pkt, 0, sizeof(nvsp_msg));

	init_pkt->hdr.msg_type = nvsp_msg_1_type_send_rx_buf;
	init_pkt->msgs.vers_1_msgs.send_rx_buf.gpadl_handle =
	    net_dev->rx_buf_gpadl_handle;
	init_pkt->msgs.vers_1_msgs.send_rx_buf.id =
	    NETVSC_RECEIVE_BUFFER_ID;

	/* Send the gpadl notification request */

	ret = vmbus_chan_send(sc->hn_prichan,
	    VMBUS_CHANPKT_TYPE_INBAND, VMBUS_CHANPKT_FLAG_RC,
	    init_pkt, sizeof(nvsp_msg), (uint64_t)(uintptr_t)init_pkt);
	if (ret != 0) {
		goto cleanup;
	}

	sema_wait(&net_dev->channel_init_sema);

	/* Check the response */
	if (init_pkt->msgs.vers_1_msgs.send_rx_buf_complete.status
	    != nvsp_status_success) {
		ret = EINVAL;
		goto cleanup;
	}

	net_dev->rx_section_count =
	    init_pkt->msgs.vers_1_msgs.send_rx_buf_complete.num_sections;

	net_dev->rx_sections = malloc(net_dev->rx_section_count *
	    sizeof(nvsp_1_rx_buf_section), M_NETVSC, M_WAITOK);
	memcpy(net_dev->rx_sections, 
	    init_pkt->msgs.vers_1_msgs.send_rx_buf_complete.sections,
	    net_dev->rx_section_count * sizeof(nvsp_1_rx_buf_section));


	/*
	 * For first release, there should only be 1 section that represents
	 * the entire receive buffer
	 */
	if (net_dev->rx_section_count != 1
	    || net_dev->rx_sections->offset != 0) {
		ret = EINVAL;
		goto cleanup;
	}

	goto exit;

cleanup:
	hv_nv_destroy_rx_buffer(net_dev);
	
exit:
	return (ret);
}
Example #24
0
/*
 * Net VSC initialize send buffer with net VSP
 */
static int 
hv_nv_init_send_buffer_with_net_vsp(struct hn_softc *sc)
{
	netvsc_dev *net_dev;
	nvsp_msg *init_pkt;
	int ret = 0;

	net_dev = hv_nv_get_outbound_net_device(sc);
	if (!net_dev) {
		return (ENODEV);
	}

	net_dev->send_buf = hyperv_dmamem_alloc(bus_get_dma_tag(sc->hn_dev),
	    PAGE_SIZE, 0, net_dev->send_buf_size, &net_dev->txbuf_dma,
	    BUS_DMA_WAITOK | BUS_DMA_ZERO);
	if (net_dev->send_buf == NULL) {
		device_printf(sc->hn_dev, "allocate chimney txbuf failed\n");
		return ENOMEM;
	}

	/*
	 * Connect chimney sending buffer GPADL to the primary channel.
	 *
	 * NOTE:
	 * Only primary channel has chimney sending buffer connected to it.
	 * Sub-channels just share this chimney sending buffer.
	 */
	ret = vmbus_chan_gpadl_connect(sc->hn_prichan,
  	    net_dev->txbuf_dma.hv_paddr, net_dev->send_buf_size,
	    &net_dev->send_buf_gpadl_handle);
	if (ret != 0) {
		device_printf(sc->hn_dev, "chimney sending buffer gpadl "
		    "connect failed: %d\n", ret);
		goto cleanup;
	}

	/* Notify the NetVsp of the gpadl handle */

	init_pkt = &net_dev->channel_init_packet;

	memset(init_pkt, 0, sizeof(nvsp_msg));

	init_pkt->hdr.msg_type = nvsp_msg_1_type_send_send_buf;
	init_pkt->msgs.vers_1_msgs.send_rx_buf.gpadl_handle =
	    net_dev->send_buf_gpadl_handle;
	init_pkt->msgs.vers_1_msgs.send_rx_buf.id =
	    NETVSC_SEND_BUFFER_ID;

	/* Send the gpadl notification request */

	ret = vmbus_chan_send(sc->hn_prichan,
	    VMBUS_CHANPKT_TYPE_INBAND, VMBUS_CHANPKT_FLAG_RC,
  	    init_pkt, sizeof(nvsp_msg), (uint64_t)init_pkt);
	if (ret != 0) {
		goto cleanup;
	}

	sema_wait(&net_dev->channel_init_sema);

	/* Check the response */
	if (init_pkt->msgs.vers_1_msgs.send_send_buf_complete.status
	    != nvsp_status_success) {
		ret = EINVAL;
		goto cleanup;
	}

	net_dev->send_section_size =
	    init_pkt->msgs.vers_1_msgs.send_send_buf_complete.section_size;
	net_dev->send_section_count =
	    net_dev->send_buf_size / net_dev->send_section_size;
	net_dev->bitsmap_words = howmany(net_dev->send_section_count,
	    BITS_PER_LONG);
	net_dev->send_section_bitsmap =
	    malloc(net_dev->bitsmap_words * sizeof(long), M_NETVSC,
	    M_WAITOK | M_ZERO);

	goto exit;

cleanup:
	hv_nv_destroy_send_buffer(net_dev);
	
exit:
	return (ret);
}
Example #25
0
static int
create_pagelist(char *buf, size_t count, unsigned short type,
	struct proc *p, PAGELIST_T ** ppagelist)
{
	PAGELIST_T *pagelist;
	vm_page_t *pages;
	vm_page_t page;
	unsigned long *addrs;
	unsigned int num_pages, offset, i;
	int pagelist_size;
	char *addr, *base_addr, *next_addr;
	int run, addridx, actual_pages;

	offset = (unsigned int)buf & (PAGE_SIZE - 1);
	num_pages = (count + offset + PAGE_SIZE - 1) / PAGE_SIZE;

	*ppagelist = NULL;

	/* Allocate enough storage to hold the page pointers and the page list */
	pagelist_size = sizeof(PAGELIST_T) +
		(num_pages * sizeof(unsigned long)) +
		(num_pages * sizeof(vm_page_t));
	pagelist = malloc(pagelist_size, M_VCPAGELIST, M_WAITOK | M_ZERO);

	vcos_log_trace("create_pagelist - %x", (unsigned int)pagelist);
	if (!pagelist)
		return ENOMEM;

	addrs = pagelist->addrs;
	pages = (vm_page_t*)(addrs + num_pages);

	actual_pages = vm_fault_quick_hold_pages(&p->p_vmspace->vm_map,
	    (vm_offset_t)buf, count,
	    (type == PAGELIST_READ ? VM_PROT_WRITE : 0 ) | VM_PROT_READ, pages, num_pages);

        if (actual_pages != num_pages)
	{
		vm_page_unhold_pages(pages, actual_pages);
		free(pagelist, M_VCPAGELIST);
		return EINVAL;
	}

	pagelist->length = count;
	pagelist->type = type;
	pagelist->offset = offset;

	/* Group the pages into runs of contiguous pages */

	base_addr = (void *)PHYS_TO_VCBUS(VM_PAGE_TO_PHYS(pages[0]));
	next_addr = base_addr + PAGE_SIZE;
	addridx = 0;
	run = 0;

	for (i = 1; i < num_pages; i++) {
		addr = (void *)PHYS_TO_VCBUS(VM_PAGE_TO_PHYS(pages[i]));
		if ((addr == next_addr) && (run < (PAGE_SIZE - 1))) {
			next_addr += PAGE_SIZE;
			run++;
		} else {
			addrs[addridx] = (unsigned long)base_addr + run;
			addridx++;
			base_addr = addr;
			next_addr = addr + PAGE_SIZE;
			run = 0;
		}
	}

	addrs[addridx] = (unsigned long)base_addr + run;
	addridx++;

	/* Partial cache lines (fragments) require special measures */
	if ((type == PAGELIST_READ) &&
		((pagelist->offset & (CACHE_LINE_SIZE - 1)) ||
		((pagelist->offset + pagelist->length) & (CACHE_LINE_SIZE - 1)))) {
		FRAGMENTS_T *fragments;

		/* XXXBSD: interruptible? */
		sema_wait(&g_free_fragments_sema);

		vcos_assert(g_free_fragments != NULL);

		mtx_lock(&g_free_fragments_mutex);
		fragments = (FRAGMENTS_T *) g_free_fragments;
		vcos_assert(fragments != NULL);
		g_free_fragments = *(FRAGMENTS_T **) g_free_fragments;
		mtx_unlock(&g_free_fragments_mutex);
		pagelist->type =
			 PAGELIST_READ_WITH_FRAGMENTS + (fragments -
							 g_fragments_base);
	}

	cpu_dcache_wbinv_range((vm_offset_t)pagelist, pagelist_size);
	*ppagelist = pagelist;

	return 0;
}
Example #26
0
/*
 * Net VSC initialize receive buffer with net VSP
 * 
 * Net VSP:  Network virtual services client, also known as the
 *     Hyper-V extensible switch and the synthetic data path.
 */
static int 
hv_nv_init_rx_buffer_with_net_vsp(struct hv_device *device)
{
	netvsc_dev *net_dev;
	nvsp_msg *init_pkt;
	int ret = 0;

	net_dev = hv_nv_get_outbound_net_device(device);
	if (!net_dev) {
		return (ENODEV);
	}

	net_dev->rx_buf = contigmalloc(net_dev->rx_buf_size, M_NETVSC,
	    M_ZERO, 0UL, BUS_SPACE_MAXADDR, PAGE_SIZE, 0);

	/*
	 * Establish the GPADL handle for this buffer on this channel.
	 * Note:  This call uses the vmbus connection rather than the
	 * channel to establish the gpadl handle. 
	 * GPADL:  Guest physical address descriptor list.
	 */
	ret = hv_vmbus_channel_establish_gpadl(
		device->channel, net_dev->rx_buf,
		net_dev->rx_buf_size, &net_dev->rx_buf_gpadl_handle);
	if (ret != 0) {
		goto cleanup;
	}
	
	/* sema_wait(&ext->channel_init_sema); KYS CHECK */

	/* Notify the NetVsp of the gpadl handle */
	init_pkt = &net_dev->channel_init_packet;

	memset(init_pkt, 0, sizeof(nvsp_msg));

	init_pkt->hdr.msg_type = nvsp_msg_1_type_send_rx_buf;
	init_pkt->msgs.vers_1_msgs.send_rx_buf.gpadl_handle =
	    net_dev->rx_buf_gpadl_handle;
	init_pkt->msgs.vers_1_msgs.send_rx_buf.id =
	    NETVSC_RECEIVE_BUFFER_ID;

	/* Send the gpadl notification request */

	ret = hv_vmbus_channel_send_packet(device->channel, init_pkt,
	    sizeof(nvsp_msg), (uint64_t)(uintptr_t)init_pkt,
	    HV_VMBUS_PACKET_TYPE_DATA_IN_BAND,
	    HV_VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED);
	if (ret != 0) {
		goto cleanup;
	}

	sema_wait(&net_dev->channel_init_sema);

	/* Check the response */
	if (init_pkt->msgs.vers_1_msgs.send_rx_buf_complete.status
	    != nvsp_status_success) {
		ret = EINVAL;
		goto cleanup;
	}

	net_dev->rx_section_count =
	    init_pkt->msgs.vers_1_msgs.send_rx_buf_complete.num_sections;

	net_dev->rx_sections = malloc(net_dev->rx_section_count *
	    sizeof(nvsp_1_rx_buf_section), M_NETVSC, M_WAITOK);
	memcpy(net_dev->rx_sections, 
	    init_pkt->msgs.vers_1_msgs.send_rx_buf_complete.sections,
	    net_dev->rx_section_count * sizeof(nvsp_1_rx_buf_section));


	/*
	 * For first release, there should only be 1 section that represents
	 * the entire receive buffer
	 */
	if (net_dev->rx_section_count != 1
	    || net_dev->rx_sections->offset != 0) {
		ret = EINVAL;
		goto cleanup;
	}

	goto exit;

cleanup:
	hv_nv_destroy_rx_buffer(net_dev);
	
exit:
	return (ret);
}
Example #27
0
/*
 * Net VSC initialize send buffer with net VSP
 */
static int 
hv_nv_init_send_buffer_with_net_vsp(struct hv_device *device)
{
	netvsc_dev *net_dev;
	nvsp_msg *init_pkt;
	int ret = 0;

	net_dev = hv_nv_get_outbound_net_device(device);
	if (!net_dev) {
		return (ENODEV);
	}

	net_dev->send_buf  = contigmalloc(net_dev->send_buf_size, M_NETVSC,
	    M_ZERO, 0UL, BUS_SPACE_MAXADDR, PAGE_SIZE, 0);
	if (net_dev->send_buf == NULL) {
		ret = ENOMEM;
		goto cleanup;
	}

	/*
	 * Establish the gpadl handle for this buffer on this channel.
	 * Note:  This call uses the vmbus connection rather than the
	 * channel to establish the gpadl handle. 
	 */
	ret = hv_vmbus_channel_establish_gpadl(device->channel,
  	    net_dev->send_buf, net_dev->send_buf_size,
	    &net_dev->send_buf_gpadl_handle);
	if (ret != 0) {
		goto cleanup;
	}

	/* Notify the NetVsp of the gpadl handle */

	init_pkt = &net_dev->channel_init_packet;

	memset(init_pkt, 0, sizeof(nvsp_msg));

	init_pkt->hdr.msg_type = nvsp_msg_1_type_send_send_buf;
	init_pkt->msgs.vers_1_msgs.send_rx_buf.gpadl_handle =
	    net_dev->send_buf_gpadl_handle;
	init_pkt->msgs.vers_1_msgs.send_rx_buf.id =
	    NETVSC_SEND_BUFFER_ID;

	/* Send the gpadl notification request */

	ret = hv_vmbus_channel_send_packet(device->channel, init_pkt,
  	    sizeof(nvsp_msg), (uint64_t)init_pkt,
	    HV_VMBUS_PACKET_TYPE_DATA_IN_BAND,
	    HV_VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED);
	if (ret != 0) {
		goto cleanup;
	}

	sema_wait(&net_dev->channel_init_sema);

	/* Check the response */
	if (init_pkt->msgs.vers_1_msgs.send_send_buf_complete.status
	    != nvsp_status_success) {
		ret = EINVAL;
		goto cleanup;
	}

	net_dev->send_section_size =
	    init_pkt->msgs.vers_1_msgs.send_send_buf_complete.section_size;
	net_dev->send_section_count =
	    net_dev->send_buf_size / net_dev->send_section_size;
	net_dev->bitsmap_words = howmany(net_dev->send_section_count,
	    BITS_PER_LONG);
	net_dev->send_section_bitsmap =
	    malloc(net_dev->bitsmap_words * sizeof(long), M_NETVSC,
	    M_WAITOK | M_ZERO);

	goto exit;

cleanup:
	hv_nv_destroy_send_buffer(net_dev);
	
exit:
	return (ret);
}