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

📄 sx.c

📁 这是一个SIGMA方案的PMP播放器的UCLINUX程序,可播放DVD,VCD,CD MP3...有很好的参考价值.
💻 C
📖 第 1 页 / 共 5 页
字号:
	data_in_buffer = (sx_read_channel_byte (port, hi_txipos) - 	                  sx_read_channel_byte (port, hi_txopos)) & 0xff;	/* XXX Must be "HIGH_WATER" for SI card according to doc. */	if (data_in_buffer < LOW_WATER) 		port->gs.flags &= ~GS_TX_INTEN;	func_exit();}static void sx_disable_rx_interrupts (void * ptr) {	/*  struct sx_port *port = ptr; */	func_enter();	func_exit();}static void sx_enable_rx_interrupts (void * ptr) {	/*  struct sx_port *port = ptr; */	func_enter();	func_exit();}/* Jeez. Isn't this simple? */static int sx_get_CD (void * ptr) {	struct sx_port *port = ptr;	func_enter2();	func_exit();	return ((sx_read_channel_byte (port, hi_ip) & IP_DCD) != 0);}/* Jeez. Isn't this simple? */static int sx_chars_in_buffer (void * ptr) {	struct sx_port *port = ptr;	func_enter2();	func_exit();	return ((sx_read_channel_byte (port, hi_txipos) - 	         sx_read_channel_byte (port, hi_txopos)) & 0xff);}static void sx_shutdown_port (void * ptr) {	struct sx_port *port = ptr; 	func_enter();	port->gs.flags &= ~ GS_ACTIVE;	if (port->gs.tty && (port->gs.tty->termios->c_cflag & HUPCL)) {		sx_setsignals (port, 0, 0);		sx_reconfigure_port(port);	}	func_exit();}/* ********************************************************************** * *                Here are the routines that actually                     * *               interface with the rest of the system                    * * ********************************************************************** */static int sx_open  (struct tty_struct * tty, struct file * filp){	struct sx_port *port;	int retval, line;	func_enter();	if (!sx_initialized) {		return -EIO;	}	line = MINOR(tty->device);	sx_dprintk (SX_DEBUG_OPEN, "%d: opening line %d. tty=%p ctty=%p, np=%d)\n", 	            current->pid, line, tty, current->tty, sx_nports);	if ((line < 0) || (line >= SX_NPORTS) || (line >= sx_nports))		return -ENODEV;	port = & sx_ports[line];	port->c_dcd = 0; /* Make sure that the first interrupt doesn't detect a	                    1 -> 0 transition. */	sx_dprintk (SX_DEBUG_OPEN, "port = %p c_dcd = %d\n", port, port->c_dcd);	tty->driver_data = port;	port->gs.tty = tty;	if (!port->gs.count)		MOD_INC_USE_COUNT;	port->gs.count++;	sx_dprintk (SX_DEBUG_OPEN, "starting port\n");	/*	 * Start up serial port	 */	retval = gs_init_port(&port->gs);	sx_dprintk (SX_DEBUG_OPEN, "done gs_init\n");	if (retval) {		port->gs.count--;		if (port->gs.count) MOD_DEC_USE_COUNT;		return retval;	}	port->gs.flags |= GS_ACTIVE;	sx_setsignals (port, 1,1);#if 0	if (sx_debug & SX_DEBUG_OPEN)		my_hd ((unsigned char *)port, sizeof (*port));#else	if (sx_debug & SX_DEBUG_OPEN)		my_hd ((unsigned char *)port->board->base + port->ch_base, 		       sizeof (*port));#endif	if (sx_send_command (port, HS_LOPEN, -1, HS_IDLE_OPEN) != 1) {		printk (KERN_ERR "sx: Card didn't respond to LOPEN command.\n");		port->gs.count--;		if (!port->gs.count) MOD_DEC_USE_COUNT;		return -EIO;	}	retval = gs_block_til_ready(port, filp);	sx_dprintk (SX_DEBUG_OPEN, "Block til ready returned %d. Count=%d\n", 	            retval, port->gs.count);	if (retval) {		/* 		 * Don't lower gs.count here because sx_close() will be called later		 */ 		return retval;	}	/* tty->low_latency = 1; */	if ((port->gs.count == 1) && (port->gs.flags & ASYNC_SPLIT_TERMIOS)) {		if (tty->driver.subtype == SERIAL_TYPE_NORMAL)			*tty->termios = port->gs.normal_termios;		else 			*tty->termios = port->gs.callout_termios;		sx_set_real_termios (port);	}	port->gs.session = current->session;	port->gs.pgrp = current->pgrp;	port->c_dcd = sx_get_CD (port);	sx_dprintk (SX_DEBUG_OPEN, "at open: cd=%d\n", port->c_dcd);	func_exit();	return 0;}/* I haven't the foggiest why the decrement use count has to happen   here. The whole linux serial drivers stuff needs to be redesigned.   My guess is that this is a hack to minimize the impact of a bug   elsewhere. Thinking about it some more. (try it sometime) Try   running minicom on a serial port that is driven by a modularized   driver. Have the modem hangup. Then remove the driver module. Then   exit minicom.  I expect an "oops".  -- REW */static void sx_hungup (void *ptr){  /*	struct sx_port *port = ptr;   */	func_enter ();	/* Don't force the SX card to close. mgetty doesn't like it !!!!!! -- pvdl */	/* For some reson we added this code. Don't know why anymore ;-( -- pvdl */	/*	sx_setsignals (port, 0, 0);	sx_reconfigure_port(port);		sx_send_command (port, HS_CLOSE, 0, 0);	if (sx_read_channel_byte (port, hi_hstat) != HS_IDLE_CLOSED) {		if (sx_send_command (port, HS_FORCE_CLOSED, -1, HS_IDLE_CLOSED) != 1) {			printk (KERN_ERR 			        "sx: sent the force_close command, but card didn't react\n");		} else			sx_dprintk (SX_DEBUG_CLOSE, "sent the force_close command.\n");	}	*/	MOD_DEC_USE_COUNT;	func_exit ();}static void sx_close (void *ptr){	struct sx_port *port = ptr; 	/* Give the port 5 seconds to close down. */	int to = 5 * HZ; 	func_enter ();	sx_setsignals (port, 0, 0);	sx_reconfigure_port(port);		sx_send_command (port, HS_CLOSE, 0, 0);	while (to-- && (sx_read_channel_byte (port, hi_hstat) != HS_IDLE_CLOSED)) {		current->state = TASK_INTERRUPTIBLE;		schedule_timeout (1);		if (signal_pending (current))				break;	}	current->state = TASK_RUNNING;	if (sx_read_channel_byte (port, hi_hstat) != HS_IDLE_CLOSED) {		if (sx_send_command (port, HS_FORCE_CLOSED, -1, HS_IDLE_CLOSED) != 1) {			printk (KERN_ERR 			        "sx: sent the force_close command, but card didn't react\n");		} else			sx_dprintk (SX_DEBUG_CLOSE, "sent the force_close command.\n");	}	sx_dprintk (SX_DEBUG_CLOSE, "waited %d jiffies for close. count=%d\n", 	            5 * HZ - to - 1, port->gs.count);	if(port->gs.count) {		sx_dprintk(SX_DEBUG_CLOSE, "WARNING port count:%d\n", port->gs.count);		port->gs.count = 0;	}	MOD_DEC_USE_COUNT;	func_exit ();}/* This is relatively thorough. But then again it is only 20 lines. */#define MARCHUP    for (i=min;i<max;i++) #define MARCHDOWN  for (i=max-1;i>=min;i--)#define W0         write_sx_byte (board, i, 0x55)#define W1         write_sx_byte (board, i, 0xaa)#define R0         if (read_sx_byte (board, i) != 0x55) return 1#define R1         if (read_sx_byte (board, i) != 0xaa) return 1/* This memtest takes a human-noticable time. You normally only do it   once a boot, so I guess that it is worth it. */static int do_memtest (struct sx_board *board, int min, int max){	int i;	/* This is a marchb. Theoretically, marchb catches much more than	   simpler tests. In practise, the longer test just catches more	   intermittent errors. -- REW	   (For the theory behind memory testing see: 	   Testing Semiconductor Memories by A.J. van de Goor.) */	MARCHUP	 {W0;}	MARCHUP   {R0;W1;R1;W0;R0;W1;}	MARCHUP   {R1;W0;W1;}	MARCHDOWN {R1;W0;W1;W0;}	MARCHDOWN {R0;W1;W0;}	return 0;}#undef MARCHUP#undef MARCHDOWN#undef W0#undef W1#undef R0#undef R1#define MARCHUP    for (i=min;i<max;i+=2) #define MARCHDOWN  for (i=max-1;i>=min;i-=2)#define W0         write_sx_word (board, i, 0x55aa)#define W1         write_sx_word (board, i, 0xaa55)#define R0         if (read_sx_word (board, i) != 0x55aa) return 1#define R1         if (read_sx_word (board, i) != 0xaa55) return 1#if 0/* This memtest takes a human-noticable time. You normally only do it   once a boot, so I guess that it is worth it. */static int do_memtest_w (struct sx_board *board, int min, int max){	int i;	MARCHUP   {W0;}	MARCHUP   {R0;W1;R1;W0;R0;W1;}	MARCHUP   {R1;W0;W1;}	MARCHDOWN {R1;W0;W1;W0;}	MARCHDOWN {R0;W1;W0;}	return 0;}#endifstatic int sx_fw_ioctl (struct inode *inode, struct file *filp,                        unsigned int cmd, unsigned long arg){	int rc = 0;	int *descr = (int *)arg, i;	static struct sx_board *board = NULL;	int nbytes, offset;	unsigned long data;	char *tmp;	func_enter();#if 0 	/* Removed superuser check: Sysops can use the permissions on the device	   file to restrict access. Recommendation: Root only. (root.root 600) */	if (!capable(CAP_SYS_ADMIN)) {		return -EPERM;	}#endif	sx_dprintk (SX_DEBUG_FIRMWARE, "IOCTL %x: %lx\n", cmd, arg);	if (!board) board = &boards[0];	if (board->flags & SX_BOARD_PRESENT) {		sx_dprintk (SX_DEBUG_FIRMWARE, "Board present! (%x)\n", 		            board->flags);	} else {		sx_dprintk (SX_DEBUG_FIRMWARE, "Board not present! (%x) all:", 		            board->flags);		for (i=0;i< SX_NBOARDS;i++)			sx_dprintk (SX_DEBUG_FIRMWARE, "<%x> ", boards[i].flags);		sx_dprintk (SX_DEBUG_FIRMWARE, "\n");		return -EIO;	}	switch (cmd) {	case SXIO_SET_BOARD:		sx_dprintk (SX_DEBUG_FIRMWARE, "set board to %ld\n", arg);		if (arg > SX_NBOARDS) return -EIO;		sx_dprintk (SX_DEBUG_FIRMWARE, "not out of range\n");		if (!(boards[arg].flags	& SX_BOARD_PRESENT)) return -EIO;		sx_dprintk (SX_DEBUG_FIRMWARE, ".. and present!\n");		board = &boards[arg];		break;	case SXIO_GET_TYPE:		rc = -ENOENT; /* If we manage to miss one, return error. */		if (IS_SX_BOARD (board)) rc = SX_TYPE_SX;		if (IS_CF_BOARD (board)) rc = SX_TYPE_CF;		if (IS_SI_BOARD (board)) rc = SX_TYPE_SI;		if (IS_EISA_BOARD (board)) rc = SX_TYPE_SI;		sx_dprintk (SX_DEBUG_FIRMWARE, "returning type= %d\n", rc);		break;	case SXIO_DO_RAMTEST:		if (sx_initialized) /* Already initialized: better not ramtest the board.  */			return -EPERM;		if (IS_SX_BOARD (board)) {			rc          = do_memtest   (board, 0, 0x7000);			if (!rc) rc = do_memtest   (board, 0, 0x7000);			/*if (!rc) rc = do_memtest_w (board, 0, 0x7000);*/		} else {			rc             = do_memtest   (board, 0, 0x7ff8);			/* if (!rc) rc = do_memtest_w (board, 0, 0x7ff8); */		}		sx_dprintk (SX_DEBUG_FIRMWARE, "returning memtest result= %d\n", rc);		break;	case SXIO_DOWNLOAD:		if (sx_initialized) /* Already initialized */			return -EEXIST;		if (!sx_reset (board)) 			return -EIO;		sx_dprintk (SX_DEBUG_INIT, "reset the board...\n");		tmp = kmalloc (SX_CHUNK_SIZE, GFP_USER);		if (!tmp) return -ENOMEM;		Get_user (nbytes, descr++);		Get_user (offset, descr++); 		Get_user (data,	 descr++);		while (nbytes && data) {			for (i=0;i<nbytes;i += SX_CHUNK_SIZE) {				copy_from_user (tmp, (char *)data+i, 				                (i+SX_CHUNK_SIZE>nbytes)?nbytes-i:SX_CHUNK_SIZE);				memcpy_toio    ((char *) (board->base2 + offset + i), tmp, 				                (i+SX_CHUNK_SIZE>nbytes)?nbytes-i:SX_CHUNK_SIZE);			}			Get_user (nbytes, descr++);			Get_user (offset, descr++); 			Get_user (data,   descr++);		}		kfree (tmp);		sx_nports += sx_init_board (board);		rc = sx_nports;		break;	case SXIO_INIT:		if (sx_initialized) /* Already initialized */			return -EEXIST;		/* This is not allowed until all boards are initialized... */		for (i=0;i<SX_NBOARDS;i++) {			if ( (boards[i].flags & SX_BOARD_PRESENT) &&			     !(boards[i].flags & SX_BOARD_INITIALIZED))				return -EIO;		}		for (i=0;i<SX_NBOARDS;i++)			if (!(boards[i].flags & SX_BOARD_PRESENT)) break;		sx_dprintk (SX_DEBUG_FIRMWARE, "initing portstructs, %d boards, "		            "%d channels, first board: %d ports\n", 		            i, sx_nports, boards[0].nports);		rc = sx_init_portstructs (i, sx_nports);		sx_init_drivers ();		if (rc >= 0) 			sx_initialized++;		break;	case SXIO_SETDEBUG:		sx_debug = arg;		break;	case SXIO_GETDEBUG:		rc = sx_debug;		break;	case SXIO_GETGSDEBUG:	case SXIO_SETGSDEBUG:		rc = -EINVAL;		break;	case SXIO_GETNPORTS:		rc = sx_nports;		break;	default:		printk (KERN_WARNING "Unknown ioctl on firmware device (%x).\n", cmd);		break;	}	func_exit ();	return rc;}static void sx_break (struct tty_struct * tty, int flag){	struct sx_port *port = tty->driver_data;	int rv;	if (flag) 

⌨️ 快捷键说明

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