⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cyclades.c

📁 这是一个SIGMA方案的PMP播放器的UCLINUX程序,可播放DVD,VCD,CD MP3...有很好的参考价值.
💻 C
📖 第 1 页 / 共 5 页
字号:
				cy_readb(base_addr+(CySRER<<index)) & 					~CyTxRdy);                            goto txdone;			}			if (info->tty->stopped || info->tty->hw_stopped){                            cy_writeb((u_long)base_addr+(CySRER<<index),				cy_readb(base_addr+(CySRER<<index)) & 					~CyTxRdy);                            goto txdone;			}                        /* Because the Embedded Transmit Commands have                           been enabled, we must check to see if the			   escape character, NULL, is being sent.  If it			   is, we must ensure that there is room for it			   to be doubled in the output stream.  Therefore			   we no longer advance the pointer when the			   character is fetched, but rather wait until			   after the check for a NULL output character.			   This is necessary because there may not be			   room for the two chars needed to send a NULL.)                         */                        outch = info->xmit_buf[info->xmit_tail];                        if( outch ){                            info->xmit_cnt--;                            info->xmit_tail = (info->xmit_tail + 1)                                                      & (SERIAL_XMIT_SIZE - 1);                            cy_writeb((u_long)base_addr+(CyTDR<<index), outch);			    info->icount.tx++;                        }else{                            if(char_count > 1){                                info->xmit_cnt--;                                info->xmit_tail = (info->xmit_tail + 1)						      & (SERIAL_XMIT_SIZE - 1);                                cy_writeb((u_long)base_addr+(CyTDR<<index), 					  outch);                                cy_writeb((u_long)base_addr+(CyTDR<<index), 0);				info->icount.tx++;                                char_count--;                            }else{                            }                        }                    }        txdone:                    if (info->xmit_cnt < WAKEUP_CHARS) {                        cy_sched_event(info, Cy_EVENT_WRITE_WAKEUP);                    }        txend:                    /* end of service */                    cy_writeb((u_long)base_addr+(CyTIR<<index), 			      (save_xir & 0x3f));                    cy_writeb((u_long)base_addr+(CyCAR<<index), (save_car));		    spin_unlock(&cinfo->card_lock);                }                if (status & CySRModem) {        /* modem interrupt */                    /* determine the channel & change to that context */		    spin_lock(&cinfo->card_lock);                    save_xir = (u_char) cy_readb(base_addr+(CyMIR<<index));                    channel = (u_short ) (save_xir & CyIRChannel);                    info = &cy_port[channel + chip * 4		                           + cinfo->first_line];                    info->last_active = jiffies;                    save_car = cy_readb(base_addr+(CyCAR<<index));                    cy_writeb((u_long)base_addr+(CyCAR<<index), save_xir);                    mdm_change = cy_readb(base_addr+(CyMISR<<index));                    mdm_status = cy_readb(base_addr+(CyMSVR1<<index));                    if(info->tty == 0){/* no place for data, ignore it*/                        ;                    }else{			if (mdm_change & CyANY_DELTA) {			    /* For statistics only */			    if (mdm_change & CyDCD)	info->icount.dcd++;			    if (mdm_change & CyCTS)	info->icount.cts++;			    if (mdm_change & CyDSR)	info->icount.dsr++;			    if (mdm_change & CyRI)	info->icount.rng++;			    cy_sched_event(info, Cy_EVENT_DELTA_WAKEUP);			}                        if((mdm_change & CyDCD)                        && (info->flags & ASYNC_CHECK_CD)){                            if(mdm_status & CyDCD){                                cy_sched_event(info,				    Cy_EVENT_OPEN_WAKEUP);                            }else if(!((info->flags			                & ASYNC_CALLOUT_ACTIVE)				 &&(info->flags				    & ASYNC_CALLOUT_NOHUP))){                                cy_sched_event(info,				    Cy_EVENT_HANGUP);                            }                        }                        if((mdm_change & CyCTS)                        && (info->flags & ASYNC_CTS_FLOW)){                            if(info->tty->hw_stopped){                                if(mdm_status & CyCTS){                                    /* cy_start isn't used				         because... !!! */                                    info->tty->hw_stopped = 0;                                  cy_writeb((u_long)base_addr+(CySRER<<index),                                       cy_readb(base_addr+(CySRER<<index)) |                                        CyTxRdy);                                    cy_sched_event(info,				        Cy_EVENT_WRITE_WAKEUP);                                }                            }else{                                if(!(mdm_status & CyCTS)){                                    /* cy_stop isn't used				         because ... !!! */                                    info->tty->hw_stopped = 1;                                  cy_writeb((u_long)base_addr+(CySRER<<index),                                       cy_readb(base_addr+(CySRER<<index)) &                                        ~CyTxRdy);                                }                            }                        }                        if(mdm_change & CyDSR){                        }                        if(mdm_change & CyRI){                        }                    }                    /* end of service */                    cy_writeb((u_long)base_addr+(CyMIR<<index), 			      (save_xir & 0x3f));                    cy_writeb((u_long)base_addr+(CyCAR<<index), save_car);		    spin_unlock(&cinfo->card_lock);                }            }          /* end while status != 0 */        }            /* end loop for chips... */    } while(had_work);   /* clear interrupts */   spin_lock(&cinfo->card_lock);   cy_writeb((u_long)card_base_addr + (Cy_ClrIntr<<index), 0);                                /* Cy_ClrIntr is 0x1800 */   spin_unlock(&cinfo->card_lock);} /* cyy_interrupt *//***********************************************************//********* End of block of Cyclom-Y specific code **********//******** Start of block of Cyclades-Z specific code *********//***********************************************************/static intcyz_fetch_msg( struct cyclades_card *cinfo,	    uclong *channel, ucchar *cmd, uclong *param){  struct FIRM_ID *firm_id;  struct ZFW_CTRL *zfw_ctrl;  struct BOARD_CTRL *board_ctrl;  unsigned long loc_doorbell;    firm_id = (struct FIRM_ID *)(cinfo->base_addr + ID_ADDRESS);    if (!ISZLOADED(*cinfo)){	return (-1);    }    zfw_ctrl = (struct ZFW_CTRL *)		(cinfo->base_addr + 		 (cy_readl(&firm_id->zfwctrl_addr) & 0xfffff));    board_ctrl = &zfw_ctrl->board_ctrl;    loc_doorbell = cy_readl(&((struct RUNTIME_9060 *)                     (cinfo->ctl_addr))->loc_doorbell);    if (loc_doorbell){	*cmd = (char)(0xff & loc_doorbell);	*channel = cy_readl(&board_ctrl->fwcmd_channel);	*param = (uclong)cy_readl(&board_ctrl->fwcmd_param);	cy_writel(&((struct RUNTIME_9060 *)(cinfo->ctl_addr))->loc_doorbell,                  0xffffffff);	return 1;    }    return 0;} /* cyz_fetch_msg */static intcyz_issue_cmd( struct cyclades_card *cinfo,	    uclong channel, ucchar cmd, uclong param){  struct FIRM_ID *firm_id;  struct ZFW_CTRL *zfw_ctrl;  struct BOARD_CTRL *board_ctrl;  volatile uclong *pci_doorbell;  int index;    firm_id = (struct FIRM_ID *)(cinfo->base_addr + ID_ADDRESS);    if (!ISZLOADED(*cinfo)){	return (-1);    }    zfw_ctrl = (struct ZFW_CTRL *)		(cinfo->base_addr + 		 (cy_readl(&firm_id->zfwctrl_addr) & 0xfffff));    board_ctrl = &zfw_ctrl->board_ctrl;    index = 0;    pci_doorbell = (uclong *)(&((struct RUNTIME_9060 *)                               (cinfo->ctl_addr))->pci_doorbell);    while( (cy_readl(pci_doorbell) & 0xff) != 0){        if (index++ == 1000){	    return((int)(cy_readl(pci_doorbell) & 0xff));        }	udelay(50L);    }    cy_writel((u_long)&board_ctrl->hcmd_channel, channel);    cy_writel((u_long)&board_ctrl->hcmd_param , param);    cy_writel((u_long)pci_doorbell, (long)cmd);    return(0);} /* cyz_issue_cmd */static voidcyz_handle_rx(struct cyclades_port *info, volatile struct CH_CTRL *ch_ctrl,	      volatile struct BUF_CTRL *buf_ctrl){  struct cyclades_card *cinfo = &cy_card[info->card];  struct tty_struct *tty = info->tty;  volatile int char_count;#ifdef BLOCKMOVE  int small_count;#else  char data;#endif  volatile uclong rx_put, rx_get, new_rx_get, rx_bufsize, rx_bufaddr;    rx_get = new_rx_get = cy_readl(&buf_ctrl->rx_get);    rx_put = cy_readl(&buf_ctrl->rx_put);    rx_bufsize = cy_readl(&buf_ctrl->rx_bufsize);    rx_bufaddr = cy_readl(&buf_ctrl->rx_bufaddr);    if (rx_put >= rx_get)	char_count = rx_put - rx_get;    else	char_count = rx_put - rx_get + rx_bufsize;    if ( char_count ) {	info->last_active = jiffies;	info->jiffies[1] = jiffies;#ifdef CY_ENABLE_MONITORING	info->mon.int_count++;	info->mon.char_count += char_count;	if (char_count > info->mon.char_max)	    info->mon.char_max = char_count;	info->mon.char_last = char_count;#endif	if(tty == 0){	    /* flush received characters */	    new_rx_get = (new_rx_get + char_count) & (rx_bufsize - 1);	    info->rflush_count++;	}else{#ifdef BLOCKMOVE	    /* we'd like to use memcpy(t, f, n) and memset(s, c, count)	       for performance, but because of buffer boundaries, there	       may be several steps to the operation */	    while(0 < (small_count = 		       min_t(unsigned int, (rx_bufsize - new_rx_get),		       min_t(unsigned int, (TTY_FLIPBUF_SIZE - tty->flip.count), char_count))		 )) {		memcpy_fromio(tty->flip.char_buf_ptr,			      (char *)(cinfo->base_addr				       + rx_bufaddr + new_rx_get),			      small_count);		tty->flip.char_buf_ptr += small_count;		memset(tty->flip.flag_buf_ptr, TTY_NORMAL, small_count);		tty->flip.flag_buf_ptr += small_count;		new_rx_get = (new_rx_get + small_count) & (rx_bufsize - 1);		char_count -= small_count;		info->icount.rx += small_count;		info->idle_stats.recv_bytes += small_count;		tty->flip.count += small_count;	    }#else	    while(char_count--){		if (tty->flip.count >= TTY_FLIPBUF_SIZE){		    break;		}		data = cy_readb(cinfo->base_addr + rx_bufaddr + new_rx_get);		new_rx_get = (new_rx_get + 1) & (rx_bufsize - 1);		tty->flip.count++;		*tty->flip.flag_buf_ptr++ = TTY_NORMAL;		*tty->flip.char_buf_ptr++ = data;		info->idle_stats.recv_bytes++;		info->icount.rx++;	    }#endif#ifdef CONFIG_CYZ_INTR	    /* Recalculate the number of chars in the RX buffer and issue	       a cmd in case it's higher than the RX high water mark */	    rx_put = cy_readl(&buf_ctrl->rx_put);	    if (rx_put >= rx_get)		char_count = rx_put - rx_get;	    else		char_count = rx_put - rx_get + rx_bufsize;	    if(char_count >= cy_readl(&buf_ctrl->rx_threshold)) {		cy_sched_event(info, Cy_EVENT_Z_RX_FULL);	    }#endif	    info->idle_stats.recv_idle = jiffies;	    queue_task(&tty->flip.tqueue, &tq_timer);	}	/* Update rx_get */	cy_writel(&buf_ctrl->rx_get, new_rx_get);    }}static voidcyz_handle_tx(struct cyclades_port *info, volatile struct CH_CTRL *ch_ctrl,	      volatile struct BUF_CTRL *buf_ctrl){  struct cyclades_card *cinfo = &cy_card[info->card];  struct tty_struct *tty = info->tty;  char data;  volatile int char_count;#ifdef BLOCKMOVE  int small_count;#endif  volatile uclong tx_put, tx_get, tx_bufsize, tx_bufaddr;    if (info->xmit_cnt <= 0)	/* Nothing to transmit */	return;    tx_get = cy_readl(&buf_ctrl->tx_get);    tx_put = cy_readl(&buf_ctrl->tx_put);    tx_bufsize = cy_readl(&buf_ctrl->tx_bufsize);    tx_bufaddr = cy_readl(&buf_ctrl->tx_bufaddr);    if (tx_put >= tx_get)	char_count = tx_get - tx_put - 1 + tx_bufsize;    else	char_count = tx_get - tx_put - 1;    if ( char_count ) {	if( tty == 0 ){	    goto ztxdone;	}	if(info->x_char) { /* send special char */	    data = info->x_char;	    cy_writeb((cinfo->base_addr + tx_bufaddr + tx_put), d

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -