Exemple #1
0
/* 绘制屏幕上的内容。
 * 注意程序在绘图之前调用了prepare_buffer,结束前调用了display_buffer。
 * prepare_buffer会准备一个空白的绘图缓冲区,display_buffer则会将缓冲区绘制到屏幕上,
 * draw_pixel或draw_string绘制的内容将保存在缓冲区内(暂时不会显示在屏幕上),调用
 * display_buffer后才会显示。
*/
void
redraw_screen() {
	fly_t it;
	const char *hit, *miss;
	
	prepare_buffer(); /* 准备缓冲区 */

	/* 绘制每个字符 */
	for (it = characters(); it != NULL; it = it->_next) {
		static char buf[2];
		buf[0] = it->text + 'A'; buf[1] = 0;
		draw_string(buf, F2int(it->x), it->y, 15);
	}

	/* 绘制命中数、miss数、最后一次按键扫描码和fps */
	draw_string(itoa(last_key_code()), SCR_HEIGHT - 8, 0, 48);
	hit = itoa(get_hit());
	draw_string(hit, 0, SCR_WIDTH - strlen(hit) * 8, 10);
	miss = itoa(get_miss());
	draw_string(miss, SCR_HEIGHT - 8, SCR_WIDTH - strlen(miss) * 8, 12);
	draw_string(itoa(get_fps()), 0, 0, 14);
	draw_string("FPS", 0, strlen(itoa(get_fps())) * 8, 14);

	display_buffer(); /* 绘制缓冲区 */
}
Exemple #2
0
void display_file(const char *fname, boolean complain)
{
	dlb *fp;
	char *buf;
	int fsize;

	fp = dlb_fopen(fname, "r");
	if (!fp) {
	    if (complain) {
		pline("Cannot open \"%s\".", fname);
	    } else if (program_state.something_worth_saving) doredraw();
	} else {
	    dlb_fseek(fp, 0, SEEK_END);
	    fsize = dlb_ftell(fp);
	    dlb_fseek(fp, 0, SEEK_SET);
	    
	    buf = malloc(fsize);
	    dlb_fread(buf, fsize, 1, fp);
	    
	    dlb_fclose(fp);
	    
	    display_buffer(buf, complain);
	    
	    free(buf);
	}
}
Exemple #3
0
static void append_char(char c)
{
	if(!bb->lines) {bb->lines++; cursor_pos=0;}
	if(bb->text[bb->lines - 1]==NULL)
	{
		bb->text[bb->lines - 1]=malloc(CC_MAX_LINE_LENGTH);
		memset(bb->text[bb->lines - 1],0,CC_MAX_LINE_LENGTH);
		cursor_pos=0;
	}

	if(c=='\n')
	{
		if(cursor_pos>0 && bb->lines < SUB_MAX_TEXT)
		{
			bb->lines++;cursor_pos=0;
			if(cc_mode==CC_ROLLUP){ //Carriage return - scroll buffer one line up
				bb->text[bb->lines - 1]=calloc(1, CC_MAX_LINE_LENGTH);
				scroll_buffer(bb);
			}
		}
	}
	else
	{
		if(cursor_pos==CC_MAX_LINE_LENGTH-1)
		{
			fprintf(stderr,"CC: append_char() reached CC_MAX_LINE_LENGTH!\n");
			return;
		}
		bb->text[bb->lines - 1][cursor_pos++]=c;
	}
	//In CC roll-up mode data should be shown immediately
	if(cc_mode==CC_ROLLUP) display_buffer(bb);
}
Exemple #4
0
static void
blue_screen(const char *file, int line) {
	static char buf[256] = BLUE_SCREEN_TEXT;
	char *p = buf + sizeof(BLUE_SCREEN_TEXT) - 1;

	append(&p, file);
	append(&p, ":");
	append(&p, itoa(line));

	memset(vmem, 1, SCR_SIZE);
	draw_string(buf, 0, 0, 15);
	display_buffer();
}
Exemple #5
0
void tail_before_pos(int fd, unsigned int pos, int ntail) {

    char * buffer;
    int read_bytes, index, nb_lines_read, lastByte;

    buffer = malloc(SIZE_MAX_BUFFER+1);

    /** On test pour voir si le buffer n'est pas vide **/
    if (buffer == NULL) {
        printf("Le buffer est vide.");
        exit(EXIT_FAILURE);
    }

    if (lseek(fd,-(int)pos,SEEK_CUR) == -1) {
        /** On place la tête de lecture au début du fichier
        et on indique où se trouve
        le dernier byte à lire dans lastByte **/
        lseek(fd,0,SEEK_SET);
        lastByte = lseek(fd,0,SEEK_END);
        read_bytes = read(fd,buffer,lastByte);
    }
    else {
        lastByte = lseek(fd,0,SEEK_CUR);
        read_bytes = read(fd,buffer,SIZE_MAX_BUFFER);
    }
    /** On cherche l'index des ntail derniere lignes, et si == -1 on replace la position,
    puis on fait un appel récursif à tail_before_pos**/
    index = index_tail_buffer(buffer,read_bytes,ntail,&nb_lines_read);

    if (index == -1) {
        tail_before_pos(fd,SIZE_MAX_BUFFER+read_bytes,ntail-nb_lines_read);
        display_buffer(buffer,0,read_bytes);
    }
    else {
        display_buffer(buffer,index,read_bytes-index);
    }
    /** On libère l'espace alloué pour le buffer **/
    free(buffer);
}
Exemple #6
0
int
Dprintf(const char *format, ...)
{
  char buf[512];
  va_list args;
  int res;

  va_start(args, format);
  res = vsnprintf(buf, sizeof(buf), format, args);
  if (res >= 0) {
    display_buffer(buf);
  }
  return res;
}
Exemple #7
0
void ascii_art(AVFrame *pFrame) {
  if(!initialized) {
    printf("warning: screen not initilized\n");
    init_screen(TERM_W,TERM_H);
  }
  int y;
  uint8_t *lineptr;
  memset(sc_buf,32,buf_size);
  /* convert line by line */
  for(y=0; y<h; y++) {
    lineptr = pFrame->data[0]+y*pFrame->linesize[0];
    convert2ascii(sc_buf+w*y,lineptr,w);
  }
  display_buffer();
}
Exemple #8
0
int game_main(){
		init_game();
	while(1){
		printg("game_main\n");
	//	printk("hello");
		clear_letter_pressed();
		printg("init_game");
		black_screen();
		prepare_buffer();
		draw_border();
		display_buffer();
		//system_enable_interrupt();
		init_block();
		printg("gamestart");
		game_loop();
		sleep(2);
	}
	return 0;
}
Exemple #9
0
void
play(void) { //主循环
	const char *text = "http://cslab.nju.edu.cn/opsystem";
	static char buf[2];
	int text_len = 32;
	int w = SCR_WIDTH / 8;
	int color = 0, start_pos = 0, clk = 0;

	for (; ; clk = (clk + 1) % 5) { // 主循环是一个死循环
		int i;
		prepare_buffer(); // 在绘图之前,先需要准备缓冲区

		if (clk == 0) {
			start_pos = (start_pos + 1) % w;
		}
		color = (color + 1) % 72;
		for (i = 0; i < text_len; i ++) { // 计算每个字符的位置 然后显示在屏幕上
			int j = (i + start_pos) % w;
			int d = 50 * sin(2 * PI * j / w);
			buf[0] = text[i];
			draw_string(buf, 8 * j, SCR_HEIGHT / 2 - 4 + d, 32 + color);
		}
		
		// 在左下角显示键盘扫描码
		draw_string(itoa(last_key), 0, SCR_HEIGHT - 8, live > 0 ? 10: 7);
		if (live > 0) live --;

		i = HZ / 60;	
		while (i) {
			wait_for_interrupt();
			disable_interrupt(); // 关闭中断是为了防止数据竞争(data race)。
			if (timers > 0) {
				timers --;
				i --;
			}
			enable_interrupt();
		}

		display_buffer(); // 绘图结束后,调用这个函数将绘制的图像显示到屏幕上
	}
}
static void
deliver_by_window(struct qtmsg *qt_msg)
{
    char in_line[81];
    boolean new_para = TRUE;
    const char *msg = "";
    int size;

    /* Don't show this in replay mode, because it would require a keystroke to
       dismiss. (The other uses of display_buffer are #verhistory and #license,
       both of which are zero-time; thus, this is the only way to produce an
       /uninteractible/ buffer, which is something we want to avoid.) */
    if (program_state.followmode == FM_REPLAY)
        return;

    for (size = 0; size < qt_msg->size; size += (long)strlen(in_line)) {
        dlb_fgets(in_line, 80, msg_file);
        const char *out_line = convert_line(in_line);

        /* We want to strip lone newlines, but leave sequences intact, or
           special formatting.

           TODO: This is a huge kluge. Be better at this. */
        if (!*out_line) {
            if (!new_para)
                msg = msgcat(msg, "\n \n");
            new_para = TRUE;
        } else {
            if (out_line[0] == ' ' && !new_para)
                msg = msgkitten(msg, '\n');
            else if (!new_para)
                msg = msgkitten(msg, ' ');
            new_para = FALSE;
        }

        msg = msgcat(msg, out_line);
    }

    display_buffer(msg, TRUE);
}
Exemple #11
0
void msgline() {
	char buf[256], buf2[STRLEN * 2];
	void display_buffer();
	extern int talkrequest;
	int tmpshow;
	time_t now;

	if (ismsgline <= 0)
		return;
	now = time(0);
	tmpshow = showansi;
	showansi = 1;
	if (talkrequest) {
		talkreply();
		clear();
		showansi = 0;
		display_buffer();
		showansi = 1;
	}
	strcpy(buf, "");
	if (chkmail())
		strcat(buf, "¡¾ÐÅ¡¿");
	else
		strcat(buf, "¡¾  ¡¿");
	strcat(buf, "ÐÅÏä [°´Ctrl-QÇó¾È] ");
	sprintf(
			buf2,
			"[%s][%4.4d,%3.3d][%d] [%2s]",
			insert_character ? "²åÈë" : "¸Äд", currln + 1, currpnt + 1,
			linelen-1, enabledbchar ? "Ë«" : "µ¥");
	strcat(buf, buf2);
	sprintf(buf2, "\033[1;33m¡¾\033[1;32m%.23s\033[33m¡¿\033[m",
			getdatestring(now, DATE_ZH) + 6);
	strcat(buf, buf2);
	move(t_lines - 1, 0);
	clrtoeol();
	prints("%s", buf);
	showansi = tmpshow;
}
int
islpci_eth_transmit(struct sk_buff *skb, struct net_device *ndev)
{
	islpci_private *priv = netdev_priv(ndev);
	isl38xx_control_block *cb = priv->control_block;
	u32 index;
	dma_addr_t pci_map_address;
	int frame_size;
	isl38xx_fragment *fragment;
	int offset;
	struct sk_buff *newskb;
	int newskb_offset;
	unsigned long flags;
	unsigned char wds_mac[6];
	u32 curr_frag;
	int err = 0;

#if VERBOSE > SHOW_ERROR_MESSAGES
	DEBUG(SHOW_FUNCTION_CALLS, "islpci_eth_transmit \n");
#endif

	/* lock the driver code */
	spin_lock_irqsave(&priv->slock, flags);

	/* check whether the destination queue has enough fragments for the frame */
	curr_frag = le32_to_cpu(cb->driver_curr_frag[ISL38XX_CB_TX_DATA_LQ]);
	if (unlikely(curr_frag - priv->free_data_tx >= ISL38XX_CB_TX_QSIZE)) {
		printk(KERN_ERR "%s: transmit device queue full when awake\n",
		       ndev->name);
		netif_stop_queue(ndev);

		/* trigger the device */
		isl38xx_w32_flush(priv->device_base, ISL38XX_DEV_INT_UPDATE,
				  ISL38XX_DEV_INT_REG);
		udelay(ISL38XX_WRITEIO_DELAY);

		err = -EBUSY;
		goto drop_free;
	}
	/* Check alignment and WDS frame formatting. The start of the packet should
	 * be aligned on a 4-byte boundary. If WDS is enabled add another 6 bytes
	 * and add WDS address information */
	if (likely(((long) skb->data & 0x03) | init_wds)) {
		/* get the number of bytes to add and re-allign */
		offset = (4 - (long) skb->data) & 0x03;
		offset += init_wds ? 6 : 0;

		/* check whether the current skb can be used  */
		if (!skb_cloned(skb) && (skb_tailroom(skb) >= offset)) {
			unsigned char *src = skb->data;

#if VERBOSE > SHOW_ERROR_MESSAGES
			DEBUG(SHOW_TRACING, "skb offset %i wds %i\n", offset,
			      init_wds);
#endif

			/* align the buffer on 4-byte boundary */
			skb_reserve(skb, (4 - (long) skb->data) & 0x03);
			if (init_wds) {
				/* wds requires an additional address field of 6 bytes */
				skb_put(skb, 6);
#ifdef ISLPCI_ETH_DEBUG
				printk("islpci_eth_transmit:wds_mac\n");
#endif
				memmove(skb->data + 6, src, skb->len);
				memcpy(skb->data, wds_mac, 6);
			} else {
				memmove(skb->data, src, skb->len);
			}

#if VERBOSE > SHOW_ERROR_MESSAGES
			DEBUG(SHOW_TRACING, "memmove %p %p %i \n", skb->data,
			      src, skb->len);
#endif
		} else {
			newskb =
			    dev_alloc_skb(init_wds ? skb->len + 6 : skb->len);
			if (unlikely(newskb == NULL)) {
				printk(KERN_ERR "%s: Cannot allocate skb\n",
				       ndev->name);
				err = -ENOMEM;
				goto drop_free;
			}
			newskb_offset = (4 - (long) newskb->data) & 0x03;

			/* Check if newskb->data is aligned */
			if (newskb_offset)
				skb_reserve(newskb, newskb_offset);

			skb_put(newskb, init_wds ? skb->len + 6 : skb->len);
			if (init_wds) {
				memcpy(newskb->data + 6, skb->data, skb->len);
				memcpy(newskb->data, wds_mac, 6);
#ifdef ISLPCI_ETH_DEBUG
				printk("islpci_eth_transmit:wds_mac\n");
#endif
			} else
				memcpy(newskb->data, skb->data, skb->len);

#if VERBOSE > SHOW_ERROR_MESSAGES
			DEBUG(SHOW_TRACING, "memcpy %p %p %i wds %i\n",
			      newskb->data, skb->data, skb->len, init_wds);
#endif

			newskb->dev = skb->dev;
			dev_kfree_skb_irq(skb);
			skb = newskb;
		}
	}
	/* display the buffer contents for debugging */
#if VERBOSE > SHOW_ERROR_MESSAGES
	DEBUG(SHOW_BUFFER_CONTENTS, "\ntx %p ", skb->data);
	display_buffer((char *) skb->data, skb->len);
#endif

	/* map the skb buffer to pci memory for DMA operation */
	pci_map_address = pci_map_single(priv->pdev,
					 (void *) skb->data, skb->len,
					 PCI_DMA_TODEVICE);
	if (unlikely(pci_map_address == 0)) {
		printk(KERN_WARNING "%s: cannot map buffer to PCI\n",
		       ndev->name);

		err = -EIO;
		goto drop_free;
	}
	/* Place the fragment in the control block structure. */
	index = curr_frag % ISL38XX_CB_TX_QSIZE;
	fragment = &cb->tx_data_low[index];

	priv->pci_map_tx_address[index] = pci_map_address;
	/* store the skb address for future freeing  */
	priv->data_low_tx[index] = skb;
	/* set the proper fragment start address and size information */
	frame_size = skb->len;
	fragment->size = cpu_to_le16(frame_size);
	fragment->flags = cpu_to_le16(0);	/* set to 1 if more fragments */
	fragment->address = cpu_to_le32(pci_map_address);
	curr_frag++;

	/* The fragment address in the control block must have been
	 * written before announcing the frame buffer to device. */
	wmb();
	cb->driver_curr_frag[ISL38XX_CB_TX_DATA_LQ] = cpu_to_le32(curr_frag);

	if (curr_frag - priv->free_data_tx + ISL38XX_MIN_QTHRESHOLD
	    > ISL38XX_CB_TX_QSIZE) {
		/* stop sends from upper layers */
		netif_stop_queue(ndev);

		/* set the full flag for the transmission queue */
		priv->data_low_tx_full = 1;
	}

	/* set the transmission time */
	ndev->trans_start = jiffies;
	priv->statistics.tx_packets++;
	priv->statistics.tx_bytes += skb->len;

	/* trigger the device */
	islpci_trigger(priv);

	/* unlock the driver code */
	spin_unlock_irqrestore(&priv->slock, flags);

	return 0;

      drop_free:
	priv->statistics.tx_dropped++;
	spin_unlock_irqrestore(&priv->slock, flags);
	dev_kfree_skb(skb);
	return err;
}
int
islpci_eth_receive(islpci_private *priv)
{
	struct net_device *ndev = priv->ndev;
	isl38xx_control_block *control_block = priv->control_block;
	struct sk_buff *skb;
	u16 size;
	u32 index, offset;
	unsigned char *src;
	int discard = 0;

#if VERBOSE > SHOW_ERROR_MESSAGES
	DEBUG(SHOW_FUNCTION_CALLS, "islpci_eth_receive \n");
#endif

	/* the device has written an Ethernet frame in the data area
	 * of the sk_buff without updating the structure, do it now */
	index = priv->free_data_rx % ISL38XX_CB_RX_QSIZE;
	size = le16_to_cpu(control_block->rx_data_low[index].size);
	skb = priv->data_low_rx[index];
	offset = ((unsigned long)
		  le32_to_cpu(control_block->rx_data_low[index].address) -
		  (unsigned long) skb->data) & 3;

#if VERBOSE > SHOW_ERROR_MESSAGES
	DEBUG(SHOW_TRACING,
	      "frq->addr %x skb->data %p skb->len %u offset %u truesize %u\n ",
	      control_block->rx_data_low[priv->free_data_rx].address, skb->data,
	      skb->len, offset, skb->truesize);
#endif

	/* delete the streaming DMA mapping before processing the skb */
	pci_unmap_single(priv->pdev,
			 priv->pci_map_rx_address[index],
			 MAX_FRAGMENT_SIZE_RX + 2, PCI_DMA_FROMDEVICE);

	/* update the skb structure and allign the buffer */
	skb_put(skb, size);
	if (offset) {
		/* shift the buffer allocation offset bytes to get the right frame */
		skb_pull(skb, 2);
		skb_put(skb, 2);
	}
#if VERBOSE > SHOW_ERROR_MESSAGES
	/* display the buffer contents for debugging */
	DEBUG(SHOW_BUFFER_CONTENTS, "\nrx %p ", skb->data);
	display_buffer((char *) skb->data, skb->len);
#endif

	/* check whether WDS is enabled and whether the data frame is a WDS frame */

	if (init_wds) {
		/* WDS enabled, check for the wds address on the first 6 bytes of the buffer */
		src = skb->data + 6;
		memmove(skb->data, src, skb->len - 6);
		skb_trim(skb, skb->len - 6);
	}
#if VERBOSE > SHOW_ERROR_MESSAGES
	DEBUG(SHOW_TRACING, "Fragment size %i in skb at %p\n", size, skb);
	DEBUG(SHOW_TRACING, "Skb data at %p, length %i\n", skb->data, skb->len);

	/* display the buffer contents for debugging */
	DEBUG(SHOW_BUFFER_CONTENTS, "\nrx %p ", skb->data);
	display_buffer((char *) skb->data, skb->len);
#endif
	/* take care of monitor mode and spy monitoring. */
	if (unlikely(priv->iw_mode == IW_MODE_MONITOR))
		discard = islpci_monitor_rx(priv, &skb);
	else {
		if (unlikely(skb->data[2 * ETH_ALEN] == 0)) {
			/* The packet has a rx_annex. Read it for spy monitoring, Then
			 * remove it, while keeping the 2 leading MAC addr.
			 */
			struct iw_quality wstats;
			struct rx_annex_header *annex =
			    (struct rx_annex_header *) skb->data;
			wstats.level = annex->rfmon.rssi;
			/* The noise value can be a bit outdated if nobody's
			 * reading wireless stats... */
			wstats.noise = priv->local_iwstatistics.qual.noise;
			wstats.qual = wstats.level - wstats.noise;
			wstats.updated = 0x07;
			/* Update spy records */
			wireless_spy_update(ndev, annex->addr2, &wstats);

			memcpy(skb->data + sizeof (struct rfmon_header),
			       skb->data, 2 * ETH_ALEN);
			skb_pull(skb, sizeof (struct rfmon_header));
		}
		skb->protocol = eth_type_trans(skb, ndev);
	}
	skb->ip_summed = CHECKSUM_NONE;
	priv->statistics.rx_packets++;
	priv->statistics.rx_bytes += size;

	/* deliver the skb to the network layer */
#ifdef ISLPCI_ETH_DEBUG
	printk
	    ("islpci_eth_receive:netif_rx %2.2X %2.2X %2.2X %2.2X %2.2X %2.2X\n",
	     skb->data[0], skb->data[1], skb->data[2], skb->data[3],
	     skb->data[4], skb->data[5]);
#endif
	if (unlikely(discard)) {
		dev_kfree_skb_irq(skb);
		skb = NULL;
	} else
		netif_rx(skb);

	/* increment the read index for the rx data low queue */
	priv->free_data_rx++;

	/* add one or more sk_buff structures */
	while (index =
	       le32_to_cpu(control_block->
			   driver_curr_frag[ISL38XX_CB_RX_DATA_LQ]),
	       index - priv->free_data_rx < ISL38XX_CB_RX_QSIZE) {
		/* allocate an sk_buff for received data frames storage
		 * include any required allignment operations */
		skb = dev_alloc_skb(MAX_FRAGMENT_SIZE_RX + 2);
		if (unlikely(skb == NULL)) {
			/* error allocating an sk_buff structure elements */
			DEBUG(SHOW_ERROR_MESSAGES, "Error allocating skb \n");
			break;
		}
		skb_reserve(skb, (4 - (long) skb->data) & 0x03);
		/* store the new skb structure pointer */
		index = index % ISL38XX_CB_RX_QSIZE;
		priv->data_low_rx[index] = skb;

#if VERBOSE > SHOW_ERROR_MESSAGES
		DEBUG(SHOW_TRACING,
		      "new alloc skb %p skb->data %p skb->len %u index %u truesize %u\n ",
		      skb, skb->data, skb->len, index, skb->truesize);
#endif

		/* set the streaming DMA mapping for proper PCI bus operation */
		priv->pci_map_rx_address[index] =
		    pci_map_single(priv->pdev, (void *) skb->data,
				   MAX_FRAGMENT_SIZE_RX + 2,
				   PCI_DMA_FROMDEVICE);
		if (unlikely(priv->pci_map_rx_address[index] == (dma_addr_t) NULL)) {
			/* error mapping the buffer to device accessable memory address */
			DEBUG(SHOW_ERROR_MESSAGES,
			      "Error mapping DMA address\n");

			/* free the skbuf structure before aborting */
			dev_kfree_skb_irq((struct sk_buff *) skb);
			skb = NULL;
			break;
		}
		/* update the fragment address */
		control_block->rx_data_low[index].address =
			cpu_to_le32((u32)priv->pci_map_rx_address[index]);
		wmb();

		/* increment the driver read pointer */
		add_le32p((u32 *) &control_block->
			  driver_curr_frag[ISL38XX_CB_RX_DATA_LQ], 1);
	}

	/* trigger the device */
	islpci_trigger(priv);

	return 0;
}
Exemple #14
0
void image_flush() {
    display_buffer(image);
}
Exemple #15
0
int
islpci_mgt_receive(struct net_device *ndev)
{
	islpci_private *priv = netdev_priv(ndev);
	isl38xx_control_block *cb =
	    (isl38xx_control_block *) priv->control_block;
	u32 curr_frag;

#if VERBOSE > SHOW_ERROR_MESSAGES
	DEBUG(SHOW_FUNCTION_CALLS, "islpci_mgt_receive \n");
#endif

	
	curr_frag = le32_to_cpu(cb->device_curr_frag[ISL38XX_CB_RX_MGMTQ]);
	barrier();

	for (; priv->index_mgmt_rx < curr_frag; priv->index_mgmt_rx++) {
		pimfor_header_t *header;
		u32 index = priv->index_mgmt_rx % ISL38XX_CB_MGMT_QSIZE;
		struct islpci_membuf *buf = &priv->mgmt_rx[index];
		u16 frag_len;
		int size;
		struct islpci_mgmtframe *frame;

		
		if (le16_to_cpu(cb->rx_data_mgmt[index].flags) != 0) {
			printk(KERN_WARNING "%s: unknown flags 0x%04x\n",
			       ndev->name,
			       le16_to_cpu(cb->rx_data_mgmt[index].flags));
			continue;
		}

		
		frag_len = le16_to_cpu(cb->rx_data_mgmt[index].size);

		
		if (frag_len > MGMT_FRAME_SIZE) {
			printk(KERN_WARNING
				"%s: Bogus packet size of %d (%#x).\n",
				ndev->name, frag_len, frag_len);
			frag_len = MGMT_FRAME_SIZE;
		}

		
		pci_dma_sync_single_for_cpu(priv->pdev, buf->pci_addr,
					    buf->size, PCI_DMA_FROMDEVICE);

		
		header = pimfor_decode_header(buf->mem, frag_len);
		if (!header) {
			printk(KERN_WARNING "%s: no PIMFOR header found\n",
			       ndev->name);
			continue;
		}

		
		header->device_id = priv->ndev->ifindex;

#if VERBOSE > SHOW_ERROR_MESSAGES
		DEBUG(SHOW_PIMFOR_FRAMES,
		      "PIMFOR: op %i, oid 0x%08x, device %i, flags 0x%x length 0x%x \n",
		      header->operation, header->oid, header->device_id,
		      header->flags, header->length);

		
		display_buffer((char *) header, PIMFOR_HEADER_SIZE);
		display_buffer((char *) header + PIMFOR_HEADER_SIZE,
			       header->length);
#endif

		
		if (header->flags & PIMFOR_FLAG_APPLIC_ORIGIN) {
			printk(KERN_DEBUG
			       "%s: errant PIMFOR application frame\n",
			       ndev->name);
			continue;
		}

		
		size = PIMFOR_HEADER_SIZE + header->length;
		frame = kmalloc(sizeof (struct islpci_mgmtframe) + size,
				GFP_ATOMIC);
		if (!frame) {
			printk(KERN_WARNING
			       "%s: Out of memory, cannot handle oid 0x%08x\n",
			       ndev->name, header->oid);
			continue;
		}
		frame->ndev = ndev;
		memcpy(&frame->buf, header, size);
		frame->header = (pimfor_header_t *) frame->buf;
		frame->data = frame->buf + PIMFOR_HEADER_SIZE;

#if VERBOSE > SHOW_ERROR_MESSAGES
		DEBUG(SHOW_PIMFOR_FRAMES,
		      "frame: header: %p, data: %p, size: %d\n",
		      frame->header, frame->data, size);
#endif

		if (header->operation == PIMFOR_OP_TRAP) {
#if VERBOSE > SHOW_ERROR_MESSAGES
			printk(KERN_DEBUG
			       "TRAP: oid 0x%x, device %i, flags 0x%x length %i\n",
			       header->oid, header->device_id, header->flags,
			       header->length);
#endif

			
			INIT_WORK(&frame->ws, prism54_process_trap);
			schedule_work(&frame->ws);

		} else {
			
			if ((frame = xchg(&priv->mgmt_received, frame)) != NULL) {
				printk(KERN_WARNING
				       "%s: mgmt response not collected\n",
				       ndev->name);
				kfree(frame);
			}
#if VERBOSE > SHOW_ERROR_MESSAGES
			DEBUG(SHOW_TRACING, "Wake up Mgmt Queue\n");
#endif
			wake_up(&priv->mgmt_wqueue);
		}

	}

	return 0;
}
Exemple #16
0
/*
 * Create and transmit a management frame using "operation" and "oid",
 * with arguments data/length.
 * We either return an error and free the frame, or we return 0 and
 * islpci_mgt_cleanup_transmit() frees the frame in the tx-done
 * interrupt.
 */
static int
islpci_mgt_transmit(struct net_device *ndev, int operation, unsigned long oid,
		    void *data, int length)
{
	islpci_private *priv = netdev_priv(ndev);
	isl38xx_control_block *cb =
	    (isl38xx_control_block *) priv->control_block;
	void *p;
	int err = -EINVAL;
	unsigned long flags;
	isl38xx_fragment *frag;
	struct islpci_membuf buf;
	u32 curr_frag;
	int index;
	int frag_len = length + PIMFOR_HEADER_SIZE;

#if VERBOSE > SHOW_ERROR_MESSAGES
	DEBUG(SHOW_FUNCTION_CALLS, "islpci_mgt_transmit\n");
#endif

	if (frag_len > MGMT_FRAME_SIZE) {
//		printk(KERN_DEBUG "%s: mgmt frame too large %d\n",
;
		goto error;
	}

	err = -ENOMEM;
	p = buf.mem = kmalloc(frag_len, GFP_KERNEL);
	if (!buf.mem) {
//		printk(KERN_DEBUG "%s: cannot allocate mgmt frame\n",
;
		goto error;
	}
	buf.size = frag_len;

	/* create the header directly in the fragment data area */
	pimfor_encode_header(operation, oid, length, (pimfor_header_t *) p);
	p += PIMFOR_HEADER_SIZE;

	if (data)
		memcpy(p, data, length);
	else
		memset(p, 0, length);

#if VERBOSE > SHOW_ERROR_MESSAGES
	{
		pimfor_header_t *h = buf.mem;
		DEBUG(SHOW_PIMFOR_FRAMES,
		      "PIMFOR: op %i, oid 0x%08lx, device %i, flags 0x%x length 0x%x\n",
		      h->operation, oid, h->device_id, h->flags, length);

		/* display the buffer contents for debugging */
		display_buffer((char *) h, sizeof (pimfor_header_t));
		display_buffer(p, length);
	}
#endif

	err = -ENOMEM;
	buf.pci_addr = pci_map_single(priv->pdev, buf.mem, frag_len,
				      PCI_DMA_TODEVICE);
	if (!buf.pci_addr) {
//		printk(KERN_WARNING "%s: cannot map PCI memory for mgmt\n",
;
		goto error_free;
	}

	/* Protect the control block modifications against interrupts. */
	spin_lock_irqsave(&priv->slock, flags);
	curr_frag = le32_to_cpu(cb->driver_curr_frag[ISL38XX_CB_TX_MGMTQ]);
	if (curr_frag - priv->index_mgmt_tx >= ISL38XX_CB_MGMT_QSIZE) {
//		printk(KERN_WARNING "%s: mgmt tx queue is still full\n",
;
		goto error_unlock;
	}

	/* commit the frame to the tx device queue */
	index = curr_frag % ISL38XX_CB_MGMT_QSIZE;
	priv->mgmt_tx[index] = buf;
	frag = &cb->tx_data_mgmt[index];
	frag->size = cpu_to_le16(frag_len);
	frag->flags = 0;	/* for any other than the last fragment, set to 1 */
	frag->address = cpu_to_le32(buf.pci_addr);

	/* The fragment address in the control block must have
	 * been written before announcing the frame buffer to
	 * device */
	wmb();
	cb->driver_curr_frag[ISL38XX_CB_TX_MGMTQ] = cpu_to_le32(curr_frag + 1);
	spin_unlock_irqrestore(&priv->slock, flags);

	/* trigger the device */
	islpci_trigger(priv);
	return 0;

      error_unlock:
	spin_unlock_irqrestore(&priv->slock, flags);
      error_free:
	kfree(buf.mem);
      error:
	return err;
}
Exemple #17
0
static void format_chunk(Fmt_Pt *fpp, short *pdp, Polh_Output_Type type )
{
	char *s;

	switch(type){
		case STATION:
			fpp->fp_station = *pdp;
			break;

		case DATE:
			s = ctime((time_t*)pdp);
			if( s[ strlen(s) - 1 ] == '\n' )
				s[ strlen(s) - 1 ] = 0;
			strcpy(fpp->fp_date_str,s);
			break;

		case SECONDS:
			fpp->fp_seconds = *((int32_t *)pdp);
			break;

		case MSECS:
			fpp->fp_usecs = *((int32_t *)pdp);
			break;

		case XYZ_INT:
#ifdef QUIP_DEBUG
if( debug & debug_polhemus ){
advise("raw buffer for XYZ_INT:");
display_buffer(pdp,3);
}
#endif /* QUIP_DEBUG */
			/* coordinates */
			if( polh_units == PH_CM_FMT ) {
				fpp->fp_x = RAW_TO_CM(pdp); pdp ++;
				fpp->fp_y = RAW_TO_CM(pdp); pdp ++;
				fpp->fp_z = RAW_TO_CM(pdp); pdp ++;
			} else if( polh_units == PH_INCHES_FMT ) {
				fpp->fp_x = RAW_TO_IN(pdp); pdp ++;
				fpp->fp_y = RAW_TO_IN(pdp); pdp ++;
				fpp->fp_z = RAW_TO_IN(pdp); pdp ++;
			}
#ifdef CAUTIOUS
			else {
				warn("CAUTIOUS:  format_chunk: not cm or inches!?");
				return;
			}
#endif /* CAUTIOUS */
			break;

		case XYZ_FLT:
			fpp->fp_x = *((float *)pdp); pdp+=2;
			fpp->fp_y = *((float *)pdp); pdp+=2;
			fpp->fp_z = *((float *)pdp); pdp+=2;
			break;

		case EULER_INT:
			fpp->fp_azim = RAW_TO_DEG(pdp); pdp ++;
			fpp->fp_elev = RAW_TO_DEG(pdp); pdp ++;
			fpp->fp_roll = RAW_TO_DEG(pdp); pdp ++;
			break;

		case X_DIR_INT:
			fpp->fp_xdc_x = INT_TO_COS(pdp); pdp++;
			fpp->fp_xdc_y = INT_TO_COS(pdp); pdp++;
			fpp->fp_xdc_z = INT_TO_COS(pdp); pdp++;
			break;

		case Y_DIR_INT:
			fpp->fp_ydc_x = INT_TO_COS(pdp); pdp++;
			fpp->fp_ydc_y = INT_TO_COS(pdp); pdp++;
			fpp->fp_ydc_z = INT_TO_COS(pdp); pdp++;
			break;

		case Z_DIR_INT:
			fpp->fp_zdc_x = INT_TO_COS(pdp); pdp++;
			fpp->fp_zdc_y = INT_TO_COS(pdp); pdp++;
			fpp->fp_zdc_z = INT_TO_COS(pdp); pdp++;
			break;

		case QUAT_INT:
			fpp->fp_q1 = INT_TO_COS(pdp); pdp++;
			fpp->fp_q2 = INT_TO_COS(pdp); pdp++;
			fpp->fp_q3 = INT_TO_COS(pdp); pdp++;
			fpp->fp_q4 = INT_TO_COS(pdp); pdp++;
			break;

		case QUAT_FLT:
			fpp->fp_q1 = *((float *)pdp); pdp+=2;
			fpp->fp_q2 = *((float *)pdp); pdp+=2;
			fpp->fp_q3 = *((float *)pdp); pdp+=2;
			fpp->fp_q4 = *((float *)pdp); pdp+=2;
			break;

		case X_DIR_FLT:
			fpp->fp_xdc_x = *((float *)pdp); pdp+=2;
			fpp->fp_xdc_y = *((float *)pdp); pdp+=2;
			fpp->fp_xdc_z = *((float *)pdp); pdp+=2;
			break;

		case Y_DIR_FLT:
			fpp->fp_ydc_x = *((float *)pdp); pdp+=2;
			fpp->fp_ydc_y = *((float *)pdp); pdp+=2;
			fpp->fp_ydc_z = *((float *)pdp); pdp+=2;
			break;

		case Z_DIR_FLT:
			fpp->fp_zdc_x = *((float *)pdp); pdp+=2;
			fpp->fp_zdc_y = *((float *)pdp); pdp+=2;
			fpp->fp_zdc_z = *((float *)pdp); pdp+=2;
			break;

#ifdef CAUTIOUS
		default:
			sprintf(ERROR_STRING,"CAUTIOUS:  format_chunk:  Oops, not programmed to format %s",
					od_tbl[type].od_name);
			warn(ERROR_STRING);
			break;
#endif /* CAUTIOUS */
	}
}
Exemple #18
0
int islpci_eth_transmit(struct sk_buff *skb, struct net_device *nwdev)
{
    islpci_private *private_config = nwdev->priv;
    isl38xx_control_block *control_block = private_config->control_block;
    isl38xx_fragment *fragment;
    u32 index, counter, pci_map_address;
    int fragments;
    int frame_size;
    int offset;
    struct sk_buff *newskb;
    int newskb_offset;
	unsigned long flags;
	unsigned char wds_mac[6];
#if VERBOSE > SHOW_ERROR_MESSAGES 
    DEBUG(SHOW_FUNCTION_CALLS, "islpci_eth_transmit \n");
#endif

    // lock the driver code
    driver_lock( &private_config->slock, &flags );

    // check whether the deviec is running
//      if( !netif_running( nwdev ) )
//      {
//              DEBUG( SHOW_ERROR_MESSAGES, "%s: Tx on stopped device!\n",
//                     nwdev->name);
//              return 1;
//      }

//      tx_timeout_check( nwdev, islpci_eth_tx_timeout );
//      skb_tx_check( nwdev, skb );

    // determine the amount of fragments needed to store the frame
    memset (wds_mac, 0, 6);
#ifdef WDS_LINKS
    check_skb_for_wds(skb, wds_mac);
#ifdef ISLPCI_ETH_DEBUG
    if ( wds_mac[0] || wds_mac[1] || wds_mac[2] || wds_mac[3] || wds_mac[4] || wds_mac[5] ) {
        printk("islpci_eth_transmit:check_skb_for_wds ! %2.2X %2.2X %2.2X %2.2X %2.2X %2.2X\n", 
               wds_mac[0], wds_mac[1], wds_mac[2], wds_mac[3], wds_mac[4], wds_mac[5] );
    } else {
        printk("islpci_eth_transmit:check_skb_for_wds %2.2X %2.2X %2.2X %2.2X %2.2X %2.2X\n", 
               wds_mac[0], wds_mac[1], wds_mac[2], wds_mac[3], wds_mac[4], wds_mac[5] );
    }
#endif
#endif
    
    frame_size = skb->len < ETH_ZLEN ? ETH_ZLEN : skb->len;
    if( init_wds ) frame_size += 6;
    fragments = frame_size / MAX_FRAGMENT_SIZE;
    fragments += frame_size % MAX_FRAGMENT_SIZE == 0 ? 0 : 1;


#if VERBOSE > SHOW_ERROR_MESSAGES 
    DEBUG(SHOW_TRACING, "Fragments needed for frame %i\n", fragments);
#endif

    // check whether the destination queue has enough fragments for the frame
    if (ISL38XX_CB_TX_QSIZE - isl38xx_in_queue( control_block, 
		ISL38XX_CB_TX_DATA_LQ ) < fragments )
    {
        // Error, cannot add the frame because the queue is full
        DEBUG(SHOW_ERROR_MESSAGES, "Error: Queue [%i] not enough room\n",
	        ISL38XX_CB_TX_DATA_LQ);

        // trigger the device by setting the Update bit in the Device Int reg
        writel(ISL38XX_DEV_INT_UPDATE, private_config->remapped_device_base + 
            ISL38XX_DEV_INT_REG);
        udelay(ISL38XX_WRITEIO_DELAY);

        // unlock the driver code
        driver_unlock( &private_config->slock, &flags );
        return -EBUSY;
    }

    // Check alignment and WDS frame formatting. The start of the packet should
    // be aligned on a 4-byte boundary. If WDS is enabled add another 6 bytes
    // and add WDS address information
    if( ((int) skb->data & 0x03) | init_wds )
    {
        // get the number of bytes to add and re-allign
        offset = (int) skb->data & 0x03;
		offset += init_wds ? 6 : 0;		

		// check whether the current skb can be used 
        if (!skb_cloned(skb) && (skb_tailroom(skb) >= offset))
        {
            unsigned char *src = skb->data;

#if VERBOSE > SHOW_ERROR_MESSAGES 
	        DEBUG(SHOW_TRACING, "skb offset %i wds %i\n", offset, init_wds );
#endif

			// allign the buffer on 4-byte boundary
            skb_reserve(skb, (int) skb->data & 0x03 );
            if( init_wds )
            {
            	// wds requires an additional address field of 6 bytes
				skb_put( skb, 6 ); 
#ifdef ISLPCI_ETH_DEBUG
                printk("islpci_eth_transmit:wds_mac\n" );
#endif			    
                memmove( skb->data+6, src, skb->len );
                memcpy( skb->data, wds_mac, 6 );
            }
            else
			{
                memmove( skb->data, src, skb->len );
			}
			
#if VERBOSE > SHOW_ERROR_MESSAGES 
            DEBUG(SHOW_TRACING, "memmove %p %p %i \n", skb->data, src,
                skb->len );
#endif
        }
        else
        {
            newskb = dev_alloc_skb( init_wds ? skb->len+6 : skb->len );
            newskb_offset = (int) newskb->data & 0x03;

            // Check if newskb->data is aligned
            if( newskb_offset )
                skb_reserve(newskb, newskb_offset);

            skb_put(newskb, init_wds ? skb->len+6 : skb->len );
            if( init_wds )
            {
                memcpy( newskb->data+6, skb->data, skb->len );
                memcpy( newskb->data, wds_mac, 6 );
#ifdef ISLPCI_ETH_DEBUG
                printk("islpci_eth_transmit:wds_mac\n" );
#endif
            }
            else
                memcpy( newskb->data, skb->data, skb->len );

#if VERBOSE > SHOW_ERROR_MESSAGES 
            DEBUG(SHOW_TRACING, "memcpy %p %p %i wds %i\n", newskb->data,
                skb->data, skb->len, init_wds );
#endif

            newskb->dev = skb->dev;
            dev_kfree_skb(skb);
            skb = newskb;
        }
    }

    // display the buffer contents for debugging
#if VERBOSE > SHOW_ERROR_MESSAGES 
    DEBUG( SHOW_BUFFER_CONTENTS, "\ntx %p ", skb->data );
    display_buffer((char *) skb->data, skb->len );
#endif

	// map the skb buffer to pci memory for DMA operation
	pci_map_address = pci_map_single( private_config->pci_device, 
		(void *) skb->data, skb->len, PCI_DMA_TODEVICE );
    if( pci_map_address == (dma_addr_t) NULL )
	{
    	// error mapping the buffer to device accessable memory address
	    DEBUG(SHOW_ERROR_MESSAGES, "Error map DMA addr, data lost\n" );

	    // free the skbuf structure before aborting
    	dev_kfree_skb(skb);

        // unlock the driver code
        driver_unlock( &private_config->slock, &flags );
	    return -EIO;
    }

	// place each fragment in the control block structure and store in the last
	// needed fragment entry of the pci_map_tx_address and data_low_tx arrays 
	// the skb frame information
    for (counter = 0; counter < fragments; counter++ )
	{
		// get a pointer to the target control block fragment
	    index = (counter + le32_to_cpu(
	        control_block->driver_curr_frag[ISL38XX_CB_TX_DATA_LQ])) %
    	    ISL38XX_CB_TX_QSIZE;			
	    fragment = &control_block->tx_data_low[index];
	
		// check whether this frame fragment is the last one
		if( counter == fragments-1 )
		{
			// the fragment is the last one, add the streaming DMA mapping for 
			// proper PCI bus operation
    		private_config->pci_map_tx_address[index] = 
                (dma_addr_t) pci_map_address;
			
			// store the skb address for future freeing 
			private_config->data_low_tx[index] = skb;
		}
		else
		{
			// the fragment will be followed by more fragments
			// clear the pci_map_tx_address and data_low_tx entries
		    private_config->pci_map_tx_address[index] = (dma_addr_t) NULL;
			private_config->data_low_tx[index] = NULL;
		}
			
		// set the proper fragment start address and size information
        fragment->address = cpu_to_le32( pci_map_address + 
			counter*MAX_FRAGMENT_SIZE );
        fragment->size = cpu_to_le16( frame_size > MAX_FRAGMENT_SIZE ?
            MAX_FRAGMENT_SIZE : frame_size );
        fragment->flags = cpu_to_le16( frame_size > MAX_FRAGMENT_SIZE ? 1 : 0 );
        frame_size -= MAX_FRAGMENT_SIZE;
	}

	// ready loading all fragements to the control block and setup pci mapping
	// update the control block interface information
    add_le32p(&control_block->driver_curr_frag[ISL38XX_CB_TX_DATA_LQ],
        fragments);

    // check whether the data tx queue is full now
    if( ISL38XX_CB_TX_QSIZE - isl38xx_in_queue( control_block, 
		ISL38XX_CB_TX_DATA_LQ ) < ISL38XX_MIN_QTHRESHOLD )
    {
        // stop the transmission of network frames to the driver
        netif_stop_queue(nwdev);

        // set the full flag for the data low transmission queue
        private_config->data_low_tx_full = 1;
    }

    // trigger the device
    isl38xx_trigger_device( &private_config->powerstate,
        private_config->remapped_device_base );

    // set the transmission time
    nwdev->trans_start = jiffies;
    private_config->statistics.tx_packets++;
    private_config->statistics.tx_bytes += skb->len;

    // cleanup the data low transmit queue
    islpci_eth_cleanup_transmit( private_config, private_config->control_block );

    // unlock the driver code
    driver_unlock( &private_config->slock, &flags );
    return 0;
}
Exemple #19
0
int islpci_eth_receive(islpci_private * private_config)
{
    struct net_device *nw_device = private_config->my_module;
    struct net_device *wds_dev = NULL;
    struct wds_net_local *wds_lp;
    isl38xx_control_block *control_block = private_config->control_block;
#ifdef WDS_LINKS
    struct wds_priv *wdsp = private_config->wdsp;
#endif    
    struct sk_buff *skb;
    u16 size;
    u32 index, offset;
    unsigned char *src;

#if VERBOSE > SHOW_ERROR_MESSAGES 
    DEBUG(SHOW_FUNCTION_CALLS, "islpci_eth_receive \n");
#endif

    // the device has written an Ethernet frame in the data area
    // of the sk_buff without updating the structure, do it now
	index = private_config->free_data_rx % ISL38XX_CB_RX_QSIZE;
    size = le16_to_cpu(control_block->rx_data_low[index].size);
	skb = private_config->data_low_rx[index];
    offset = ((u32) le32_to_cpu(control_block->rx_data_low[index].address) - 
        (u32) skb->data ) & 3;

#if VERBOSE > SHOW_ERROR_MESSAGES 
    DEBUG( SHOW_TRACING, "frq->addr %x skb->data %p skb->len %u offset %u truesize %u\n ", 
        control_block->rx_data_low[private_config->free_data_rx].address,
		skb->data, skb->len, offset, skb->truesize );
#endif

    // delete the streaming DMA mapping before processing the skb
    pci_unmap_single( private_config->pci_device, 
        private_config->pci_map_rx_address[index],
        MAX_FRAGMENT_SIZE+2, PCI_DMA_FROMDEVICE );

	// update the skb structure and allign the buffer
    skb_put( skb, size );
    if( offset )
    {
		// shift the buffer allocation offset bytes to get the right frame
        skb_pull( skb, 2 );
		skb_put( skb, 2 );
    }
    
#if VERBOSE > SHOW_ERROR_MESSAGES 
    // display the buffer contents for debugging
    DEBUG( SHOW_BUFFER_CONTENTS, "\nrx %p ", skb->data );
    display_buffer((char *) skb->data, skb->len );
#endif

    // check whether WDS is enabled and whether the data frame is a WDS frame

    if( init_wds )
    {
        // WDS enabled, check for the wds address on the first 6 bytes of the buffer
#ifdef WDS_LINKS
        wds_dev = wds_find_device( skb->data, wdsp ); 
#ifdef ISLPCI_ETH_DEBUG
        if ( wds_dev ) {
            printk("islpci_eth_receive:wds_find_device ! %2.2X %2.2X %2.2X %2.2X %2.2X %2.2X\n", 
                   skb->data[0], skb->data[1], skb->data[2], skb->data[3], skb->data[4], skb->data[5] );
        } else {
            printk("islpci_eth_receive:wds_find_device %2.2X %2.2X %2.2X %2.2X %2.2X %2.2X\n", 
                   skb->data[0], skb->data[1], skb->data[2], skb->data[3], skb->data[4], skb->data[5] );
        }
#endif
#endif
        src = skb->data+6;
        memmove( skb->data, src, skb->len-6 );
        skb_trim( skb, skb->len-6 );
    }

#if VERBOSE > SHOW_ERROR_MESSAGES 
    DEBUG(SHOW_TRACING, "Fragment size %i in skb at %p\n", size, skb);
    DEBUG(SHOW_TRACING, "Skb data at %p, length %i\n", skb->data, skb->len);

    // display the buffer contents for debugging
    DEBUG( SHOW_BUFFER_CONTENTS, "\nrx %p ", skb->data );
    display_buffer((char *) skb->data, skb->len );
#endif

    // do some additional sk_buff and network layer parameters
    skb->dev = nw_device;
    skb->protocol = eth_type_trans(skb, nw_device);
    skb->ip_summed = CHECKSUM_NONE;
    private_config->statistics.rx_packets++;
    private_config->statistics.rx_bytes += size;

#ifdef WDS_LINKS
        if ( wds_dev != NULL )
        {
            wds_lp = (struct wds_net_local *) wds_dev->priv;
            wds_lp->stats.rx_packets++;
            wds_lp->stats.rx_bytes += skb->len;            
            skb->dev = wds_dev;
        }
#endif
    // deliver the skb to the network layer
#ifdef ISLPCI_ETH_DEBUG
    printk("islpci_eth_receive:netif_rx %2.2X %2.2X %2.2X %2.2X %2.2X %2.2X\n", 
           skb->data[0], skb->data[1], skb->data[2], skb->data[3], skb->data[4], skb->data[5] );
#endif
    netif_rx(skb);

    // increment the read index for the rx data low queue
    private_config->free_data_rx++;

    // add one or more sk_buff structures
    while( index = le32_to_cpu( 
		control_block->driver_curr_frag[ISL38XX_CB_RX_DATA_LQ] ), 
		index - private_config->free_data_rx < ISL38XX_CB_RX_QSIZE )
    {
        // allocate an sk_buff for received data frames storage
	    // include any required allignment operations
        if (skb = dev_alloc_skb(MAX_FRAGMENT_SIZE+2), skb == NULL)
        {
            // error allocating an sk_buff structure elements
            DEBUG(SHOW_ERROR_MESSAGES, "Error allocating skb \n");
            break;
        }

		// store the new skb structure pointer
		index = index % ISL38XX_CB_RX_QSIZE;
		private_config->data_low_rx[index] = skb;

#if VERBOSE > SHOW_ERROR_MESSAGES 
        DEBUG( SHOW_TRACING, "new alloc skb %p skb->data %p skb->len %u index %u truesize %u\n ", 
            skb, skb->data, skb->len, index, skb->truesize );
#endif

        // set the streaming DMA mapping for proper PCI bus operation
		private_config->pci_map_rx_address[index] = pci_map_single(
			private_config->pci_device, (void *) skb->data, MAX_FRAGMENT_SIZE+2, 
			PCI_DMA_FROMDEVICE );
        if( private_config->pci_map_rx_address[index] == (dma_addr_t) NULL )
        {
            // error mapping the buffer to device accessable memory address
            DEBUG(SHOW_ERROR_MESSAGES, "Error mapping DMA address\n");

            // free the skbuf structure before aborting
            dev_kfree_skb((struct sk_buff *) skb );
            break;
        }

        // update the fragment address
        control_block->rx_data_low[index].address = cpu_to_le32( (u32)
		 	private_config->pci_map_rx_address[index] );

        // increment the driver read pointer
        add_le32p(&control_block->driver_curr_frag[ISL38XX_CB_RX_DATA_LQ], 1 );
    }

    // trigger the device
    isl38xx_trigger_device( &private_config->powerstate,
        private_config->remapped_device_base );

    return 0;
}
Exemple #20
0
int vedit(const char *filename, const char *saveheader, char *bname)
{
	int ch, foo;
	int lastcharindent = -1;
	BOOL firstkey = TRUE;
	char bakfile[PATHLEN];
	int old_rows = t_lines, old_columns = t_columns;

	sethomefile(bakfile, curuser.userid, UFNAME_EDIT);

	if ((saveheader || uinfo.mode == EDITPLAN || uinfo.mode == EDITBMWEL)
	    && isfile(bakfile)	/* lthuang */
#ifdef GUEST
	 && strcmp(curuser.userid, GUEST)
#endif
	 )
	{
		clear();
		outs(_msg_edit_8);
		if (getkey() != '2')
			mycp(bakfile, filename);
	}
	if (!isfile(filename))
		unlink(bakfile);
	if (saveheader)
		do_article_sig(filename);

	read_file(filename);

	top_of_win = firstline;
	currline = firstline;
	curr_window_line = 0;
	currpnt = 0;

	ansi_mode = FALSE;

	clear();
	display_buffer();

	move(curr_window_line, currpnt);
	while ((ch = getkey()) != EOF)
	{
		if (firstkey)
		{
			firstkey = FALSE;
			show_help_msg();
		}
		if (talkrequest)	/* lthuang */
		{
			backup_file(bakfile);
			talkreply();
			pressreturn();
			ch = CTRL('G');		/* redraw screen */
		}
		else if (msqrequest)	/* lthuang */
		{
			msqrequest = FALSE;
			msq_reply();
#if 0
			ch = CTRL('G');
#endif
		}
		if (old_rows != t_lines || old_columns != t_columns)
		{
			static const char *msg_resized = "螢幕大小已改變, 按(Ctrl-G)回到頁首!";

			old_rows = t_lines;
			old_columns = t_columns;

			top_of_win = firstline;
			currline = top_of_win;
			curr_window_line = 0;
			currpnt = 0;
			shift = 0;
			redraw_everything = TRUE;
			move(t_lines / 2, (t_columns - strlen(msg_resized)) / 2);
			outs(msg_resized);
			while (getkey() != CTRL('G'));
		}
		else if (ch < 0x100 && isprint2(ch))
		{
			insert_char(ch);
			lastcharindent = -1;
		}
		else
			switch (ch)
			{
			case KEY_UP:
				if (lastcharindent == -1)
					lastcharindent = currpnt;
				if (!currline->prev)
				{
					bell();
					break;
				}
				curr_window_line--;
				currline = currline->prev;
				currpnt = (currline->len > lastcharindent) ? lastcharindent : currline->len;
				break;
			case KEY_DOWN:
				if (lastcharindent == -1)
					lastcharindent = currpnt;
				if (!currline->next)
				{
					bell();
					break;
				}
				curr_window_line++;
				currline = currline->next;
				currpnt = (currline->len > lastcharindent) ? lastcharindent : currline->len;
				break;
			default:
				lastcharindent = -1;
				switch (ch)
				{
				case CTRL('T'):
					top_of_win = back_line(lastline, b_lines - 2);
					currline = lastline;
					curr_window_line = getlineno();
					currpnt = 0;
					redraw_everything = TRUE;
					break;
				case CTRL('S'):
					top_of_win = firstline;
					currline = top_of_win;
					curr_window_line = 0;
					currpnt = 0;
					redraw_everything = TRUE;
					break;
				case '\t':
					do
					{
						insert_char(' ');
					}
					while (currpnt & 0x7);
					break;
				case CTRL('U'):
				case CTRL('V'):
					insert_char(0x1b);
					break;
				case CTRL('C'):
					insert_char(0x1b);
					insert_char('[');
					insert_char('m');
					break;
				case KEY_RIGHT:
				case CTRL('F'):
					if (currline->len == currpnt)
					{
						if (!currline->next)
							bell();
						else
						{
							currpnt = 0;
							curr_window_line++;
							currline = currline->next;
						}
					}
					else
						currpnt++;
					break;
				case KEY_LEFT:
				case CTRL('B'):
					if (currpnt == 0)
					{
						if (!currline->prev)
							bell();
						else
						{
							currline = currline->prev;
							currpnt = currline->len;
							curr_window_line--;
						}
					}
					else
						currpnt--;
					break;
				case CTRL('G'):
					clear();
					redraw_everything = TRUE;
					break;
				case CTRL('Z'):
					vedit_help();
					break;
				case KEY_PGUP:
				case CTRL('P'):
					top_of_win = back_line(top_of_win, b_lines - 2);
					currline = top_of_win;
					currpnt = 0;
					curr_window_line = 0;
					redraw_everything = TRUE;
					break;
				case KEY_PGDN:
				case CTRL('N'):
					top_of_win = forward_line(top_of_win, b_lines - 2);
					currline = top_of_win;
					currpnt = 0;
					curr_window_line = 0;
					redraw_everything = TRUE;
					break;
				case KEY_HOME:
				case CTRL('A'):
					currpnt = 0;
					break;
				case KEY_END:
				case CTRL('E'):
					currpnt = currline->len;
					break;
				case CTRL('R'):
#if 0
					backup_file(bakfile);
#endif
					msq_reply();
#if 0
					redraw_everything = TRUE;	/* lthuang */
#endif
					break;
				case CTRL('Q'):
					ansi_mode = TRUE;
					display_buffer();
					pressreturn();
					ansi_mode = FALSE;
					display_buffer();
					break;
				case CTRL('X'):
				case CTRL('W'):
					backup_file(bakfile);
					clear();
					foo = write_file(filename, saveheader, bname);
					if (foo == BACKUP_EDITING)
						return foo;
					else if (foo != KEEP_EDITING)
					{
						unlink(bakfile);
						return foo;
					}
					redraw_everything = TRUE;	/* lthuang */
					break;
				case '\r':
				case '\n':
					split(currline, currpnt);
					/* lthuang: reduce the times of backup */
					if (total_num_of_line % 7 == 0)
						backup_file(bakfile);
					break;
				case '\177':
				case CTRL('H'):
					if (currpnt == 0)
					{
						if (!currline->prev)
						{
							bell();
							break;
						}
						curr_window_line--;
						currline = currline->prev;
						currpnt = currline->len;
						if (*killsp(currline->next->data) == '\0') {
							delete_line(currline->next);
							redraw_everything = TRUE;
						} else {
							join_currline();
						}
						if (curr_window_line == -1) {
							curr_window_line = 0;
							top_of_win = currline;
							rscroll();
						}
						break;
					}
					currpnt--;
					delete_char();
					break;
				case CTRL('D'):
					if (currline->len == currpnt)
						join_currline();
					else
						delete_char();
					break;
				case CTRL('Y'):
					currpnt = 0;
					currline->len = 0;
					delete_currline();
					break;
				case CTRL('K'):
					if (currline->len == 0)
						delete_currline();
					else if (currline->len == currpnt)
						join_currline();
					else
					{
						currline->len = currpnt;
						currline->data[currpnt] = '\0';
					}
					break;
				default:
					break;
				}
				break;
			}
		if (curr_window_line == -1)
		{
			curr_window_line = 0;
			if (!top_of_win->prev)
			{
				indigestion(6);
				bell();
			}
			else
			{
				top_of_win = top_of_win->prev;
				rscroll();
			}
		}
		if (curr_window_line == t_lines - 1)
		{
			curr_window_line = t_lines - 2;
			if (!top_of_win->next)
			{
				indigestion(7);
				bell();
			}
			else
			{
				top_of_win = top_of_win->next;
				scroll();
			}
		}

		/* lthuang: 99/07 */
		if (currpnt - shift >= t_columns - 1)
		{
			shift = (currpnt / (t_columns - 1)) * (t_columns - 1) - 1;
			redraw_everything = TRUE;
		}
		else if (currpnt - shift < 0)
		{
			shift = 0;
			redraw_everything = TRUE;
		}

		if (redraw_everything)
		{
			display_buffer();
			redraw_everything = FALSE;
		}
		else
		{
			move(curr_window_line, 0);
			clrtoeol();	/* lthuang */
			vedit_outs(currline->data);
		}

		move(curr_window_line, currpnt - shift);	/* lthuang: 99/07 */
	}
	if (uinfo.mode == POSTING || uinfo.mode == SMAIL)
		unlink(filename);
	return ABORT_EDITING;
}
Exemple #21
0
/*
 * Receive a management frame from the device.
 * This can be an arbitrary number of traps, and at most one response
 * frame for a previous request sent via islpci_mgt_transmit().
 */
int
islpci_mgt_receive(struct net_device *ndev)
{
	islpci_private *priv = netdev_priv(ndev);
	isl38xx_control_block *cb =
	    (isl38xx_control_block *) priv->control_block;
	u32 curr_frag;

#if VERBOSE > SHOW_ERROR_MESSAGES
	DEBUG(SHOW_FUNCTION_CALLS, "islpci_mgt_receive\n");
#endif

	/* Only once per interrupt, determine fragment range to
	 * process.  This avoids an endless loop (i.e. lockup) if
	 * frames come in faster than we can process them. */
	curr_frag = le32_to_cpu(cb->device_curr_frag[ISL38XX_CB_RX_MGMTQ]);
	barrier();

	for (; priv->index_mgmt_rx < curr_frag; priv->index_mgmt_rx++) {
		pimfor_header_t *header;
		u32 index = priv->index_mgmt_rx % ISL38XX_CB_MGMT_QSIZE;
		struct islpci_membuf *buf = &priv->mgmt_rx[index];
		u16 frag_len;
		int size;
		struct islpci_mgmtframe *frame;

		/* I have no idea (and no documentation) if flags != 0
		 * is possible.  Drop the frame, reuse the buffer. */
		if (le16_to_cpu(cb->rx_data_mgmt[index].flags) != 0) {
//			printk(KERN_WARNING "%s: unknown flags 0x%04x\n",
//			       ndev->name,
;
			continue;
		}

		/* The device only returns the size of the header(s) here. */
		frag_len = le16_to_cpu(cb->rx_data_mgmt[index].size);

		/*
		 * We appear to have no way to tell the device the
		 * size of a receive buffer.  Thus, if this check
		 * triggers, we likely have kernel heap corruption. */
		if (frag_len > MGMT_FRAME_SIZE) {
//			printk(KERN_WARNING
//				"%s: Bogus packet size of %d (%#x).\n",
;
			frag_len = MGMT_FRAME_SIZE;
		}

		/* Ensure the results of device DMA are visible to the CPU. */
		pci_dma_sync_single_for_cpu(priv->pdev, buf->pci_addr,
					    buf->size, PCI_DMA_FROMDEVICE);

		/* Perform endianess conversion for PIMFOR header in-place. */
		header = pimfor_decode_header(buf->mem, frag_len);
		if (!header) {
//			printk(KERN_WARNING "%s: no PIMFOR header found\n",
;
			continue;
		}

		/* The device ID from the PIMFOR packet received from
		 * the MVC is always 0.  We forward a sensible device_id.
		 * Not that anyone upstream would care... */
		header->device_id = priv->ndev->ifindex;

#if VERBOSE > SHOW_ERROR_MESSAGES
		DEBUG(SHOW_PIMFOR_FRAMES,
		      "PIMFOR: op %i, oid 0x%08x, device %i, flags 0x%x length 0x%x\n",
		      header->operation, header->oid, header->device_id,
		      header->flags, header->length);

		/* display the buffer contents for debugging */
		display_buffer((char *) header, PIMFOR_HEADER_SIZE);
		display_buffer((char *) header + PIMFOR_HEADER_SIZE,
			       header->length);
#endif

		/* nobody sends these */
		if (header->flags & PIMFOR_FLAG_APPLIC_ORIGIN) {
//			printk(KERN_DEBUG
//			       "%s: errant PIMFOR application frame\n",
;
			continue;
		}

		/* Determine frame size, skipping OID_INL_TUNNEL headers. */
		size = PIMFOR_HEADER_SIZE + header->length;
		frame = kmalloc(sizeof (struct islpci_mgmtframe) + size,
				GFP_ATOMIC);
		if (!frame) {
//			printk(KERN_WARNING
//			       "%s: Out of memory, cannot handle oid 0x%08x\n",
;
			continue;
		}
		frame->ndev = ndev;
		memcpy(&frame->buf, header, size);
		frame->header = (pimfor_header_t *) frame->buf;
		frame->data = frame->buf + PIMFOR_HEADER_SIZE;

#if VERBOSE > SHOW_ERROR_MESSAGES
		DEBUG(SHOW_PIMFOR_FRAMES,
		      "frame: header: %p, data: %p, size: %d\n",
		      frame->header, frame->data, size);
#endif

		if (header->operation == PIMFOR_OP_TRAP) {
#if VERBOSE > SHOW_ERROR_MESSAGES
//			printk(KERN_DEBUG
//			       "TRAP: oid 0x%x, device %i, flags 0x%x length %i\n",
//			       header->oid, header->device_id, header->flags,
;
#endif

			/* Create work to handle trap out of interrupt
			 * context. */
			INIT_WORK(&frame->ws, prism54_process_trap);
			schedule_work(&frame->ws);

		} else {
			/* Signal the one waiting process that a response
			 * has been received. */
			if ((frame = xchg(&priv->mgmt_received, frame)) != NULL) {
//				printk(KERN_WARNING
//				       "%s: mgmt response not collected\n",
;
				kfree(frame);
			}
#if VERBOSE > SHOW_ERROR_MESSAGES
			DEBUG(SHOW_TRACING, "Wake up Mgmt Queue\n");
#endif
			wake_up(&priv->mgmt_wqueue);
		}

	}

	return 0;
}
Exemple #22
0
static void cc_decode_EIA608(unsigned short int data)
{

  static unsigned short int lastcode=0x0000;
  unsigned char c1 = data & 0x7f;
  unsigned char c2 = (data >> 8) & 0x7f;

  if (c1 & 0x60) {		/* normal character, 0x20 <= c1 <= 0x7f */
	   append_char(chartbl[c1]);
	   if(c2 & 0x60)	/*c2 might not be a normal char even if c1 is*/
		   append_char(chartbl[c2]);
  }
  else if (c1 & 0x10)		// control code / special char
  {
//	  int channel= (c1 & 0x08) >> 3;
	  c1&=~0x08;
	  if(data!=lastcode)
	  {
	  	if(c2 & 0x40) {	/*PAC, Preamble Address Code */
			append_char('\n'); /*FIXME properly interpret PACs*/
		}
		else
			switch(c1)
			{
				case 0x10:	break; // ext attribute
				case 0x11:
					if((c2 & 0x30)==0x30)
					{
						//printf("[debug]:Special char (ignored)\n");
						/*cc_decode_special_char()*/;
					}
					else if (c2 & 0x20)
					{
						//printf("[debug]: midrow_attr (ignored)\n");
						/*cc_decode_midrow_attr()*/;
					}
					break;
				case 0x14:
					switch(c2)
					{
						case 0x00: //CC roll-on mode
							   cc_mode=CC_ROLLON;
							   break;
						case 0x25: //CC roll-up, 2 rows
						case 0x26: //CC roll-up, 3 rows
						case 0x27: //CC roll-up, 4 rows
							   cc_lines=c2-0x23;
							   cc_mode=CC_ROLLUP;
							   break;
						case 0x2C: display_buffer(NULL); //EDM
							   clear_buffer(fb); break;
						case 0x2d: append_char('\n');	//carriage return
							   break;
						case 0x2e: clear_buffer(bb);	//ENM
							   break;
						case 0x2f: swap_buffers();	//Swap buffers
							   display_buffer(fb);
							   clear_buffer(bb);
							   break;
					}
					break;
				case 0x17:
					if( c2>=0x21 && c2<=0x23) //TAB
					{
						break;
					}
			}
	  }
  }
  lastcode=data;
}