/* 绘制屏幕上的内容。 * 注意程序在绘图之前调用了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(); /* 绘制缓冲区 */ }
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); } }
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); }
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(); }
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); }
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; }
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(); }
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; }
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); }
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, "[1;33;44m"); if (chkmail()) strcat(buf, "¡¾[5;32mÐÅ[m[1;33;44m¡¿"); else strcat(buf, "¡¾ ¡¿"); strcat(buf, "ÐÅÏä [[32m°´[31mCtrl-Q[32mÇó¾È[33m] "); sprintf( buf2, "[[32m%s[33m][[32m%4.4d[33m,[32m%3.3d[33m][[32m%d[33m] [[32m%2s[33m]", 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; }
void image_flush() { display_buffer(image); }
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; }
/* * 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; }
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 */ } }
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; }
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; }
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 = "[1;34;47m螢幕大小已改變, 按(Ctrl-G)回到頁首![m"; 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; }
/* * 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; }
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; }