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

📄 sx.c

📁 Linux Kernel 2.6.9 for OMAP1710
💻 C
📖 第 1 页 / 共 5 页
字号:
   the card some time to breathe between accesses. (Otherwise the   processor on the card might not be able to access its OWN bus... */#define TIMEOUT_1 30#define TIMEOUT_2 1000000#ifdef DEBUGstatic void my_hd (unsigned char *addr, int len){	int i, j, ch;	for (i=0;i<len;i+=16) {		printk ("%p ", addr+i);		for (j=0;j<16;j++) {			printk ("%02x %s", addr[j+i], (j==7)?" ":"");		}		for (j=0;j<16;j++) {			ch = addr[j+i];			printk ("%c", (ch < 0x20)?'.':((ch > 0x7f)?'.':ch));		}		printk ("\n");	}}#endif/* This needs redoing for Alpha -- REW -- Done. */static inline void write_sx_byte (struct sx_board *board, int offset, u8 byte){	writeb (byte, board->base+offset);}static inline u8 read_sx_byte (struct sx_board *board, int offset){	return readb (board->base+offset);}static inline void write_sx_word (struct sx_board *board, int offset, u16 word){	writew (word, board->base+offset);}static inline u16 read_sx_word (struct sx_board *board, int offset){	return readw (board->base + offset);}static int sx_busy_wait_eq (struct sx_board *board,                      	    int offset, int mask, int correctval){	int i;	func_enter ();	for (i=0; i < TIMEOUT_1 ;i++)		if ((read_sx_byte (board, offset) & mask) == correctval) {			func_exit ();			return 1;		}	for (i=0; i < TIMEOUT_2 ;i++) {		if ((read_sx_byte (board, offset) & mask) == correctval) {			func_exit ();			return 1;		}		udelay (1);	}	func_exit ();	return 0;}static int sx_busy_wait_neq (struct sx_board *board,                       	     int offset, int mask, int badval){	int i;	func_enter ();	for (i=0; i < TIMEOUT_1 ;i++)		if ((read_sx_byte (board, offset) & mask) != badval) {			func_exit ();			return 1;		}	for (i=0; i < TIMEOUT_2 ;i++) {		if ((read_sx_byte (board, offset) & mask) != badval) {			func_exit ();			return 1;		}		udelay (1);	}	func_exit ();	return 0;}/* 5.6.4 of 6210028 r2.3 */static int sx_reset (struct sx_board *board){	func_enter ();	if (IS_SX_BOARD (board)) {		write_sx_byte (board, SX_CONFIG, 0);		write_sx_byte (board, SX_RESET, 1); /* Value doesn't matter */		if (!sx_busy_wait_eq (board, SX_RESET_STATUS, 1, 0)) {			printk (KERN_INFO "sx: Card doesn't respond to reset....\n");			return 0;		}	} else if (IS_EISA_BOARD(board)) {		outb(board->irq<<4, board->eisa_base+0xc02);	} else if (IS_SI1_BOARD(board)) {	        write_sx_byte (board, SI1_ISA_RESET,   0); // value does not matter	} else {		/* Gory details of the SI/ISA board */		write_sx_byte (board, SI2_ISA_RESET,    SI2_ISA_RESET_SET);		write_sx_byte (board, SI2_ISA_IRQ11,    SI2_ISA_IRQ11_CLEAR);		write_sx_byte (board, SI2_ISA_IRQ12,    SI2_ISA_IRQ12_CLEAR);		write_sx_byte (board, SI2_ISA_IRQ15,    SI2_ISA_IRQ15_CLEAR);		write_sx_byte (board, SI2_ISA_INTCLEAR, SI2_ISA_INTCLEAR_CLEAR);		write_sx_byte (board, SI2_ISA_IRQSET,   SI2_ISA_IRQSET_CLEAR);	}	func_exit ();	return 1;}/* This doesn't work on machines where "NULL" isn't 0 *//* If you have one of those, someone will need to write    the equivalent of this, which will amount to about 3 lines. I don't   want to complicate this right now. -- REW   (See, I do write comments every now and then :-) */#define OFFSETOF(strct, elem) ((long)&(((struct strct *)NULL)->elem))#define CHAN_OFFSET(port,elem) (port->ch_base + OFFSETOF (_SXCHANNEL, elem))#define MODU_OFFSET(board,addr,elem)    (addr + OFFSETOF (_SXMODULE, elem))#define  BRD_OFFSET(board,elem)                (OFFSETOF (_SXCARD, elem))#define sx_write_channel_byte(port, elem, val) \   write_sx_byte (port->board, CHAN_OFFSET (port, elem), val)#define sx_read_channel_byte(port, elem) \   read_sx_byte (port->board, CHAN_OFFSET (port, elem))#define sx_write_channel_word(port, elem, val) \   write_sx_word (port->board, CHAN_OFFSET (port, elem), val)#define sx_read_channel_word(port, elem) \   read_sx_word (port->board, CHAN_OFFSET (port, elem))#define sx_write_module_byte(board, addr, elem, val) \   write_sx_byte (board, MODU_OFFSET (board, addr, elem), val)#define sx_read_module_byte(board, addr, elem) \   read_sx_byte (board, MODU_OFFSET (board, addr, elem))#define sx_write_module_word(board, addr, elem, val) \   write_sx_word (board, MODU_OFFSET (board, addr, elem), val)#define sx_read_module_word(board, addr, elem) \   read_sx_word (board, MODU_OFFSET (board, addr, elem))#define sx_write_board_byte(board, elem, val) \   write_sx_byte (board, BRD_OFFSET (board, elem), val)#define sx_read_board_byte(board, elem) \   read_sx_byte (board, BRD_OFFSET (board, elem))#define sx_write_board_word(board, elem, val) \   write_sx_word (board, BRD_OFFSET (board, elem), val)#define sx_read_board_word(board, elem) \   read_sx_word (board, BRD_OFFSET (board, elem))static int sx_start_board (struct sx_board *board){	if (IS_SX_BOARD (board)) {		write_sx_byte (board, SX_CONFIG, SX_CONF_BUSEN);	} else if (IS_EISA_BOARD(board)) {		write_sx_byte(board, SI2_EISA_OFF, SI2_EISA_VAL);		outb((board->irq<<4)|4, board->eisa_base+0xc02);	} else if (IS_SI1_BOARD(board)) {		write_sx_byte (board, SI1_ISA_RESET_CLEAR, 0);		write_sx_byte (board, SI1_ISA_INTCL, 0);	} else {		/* Don't bug me about the clear_set. 		   I haven't the foggiest idea what it's about -- REW */		write_sx_byte (board, SI2_ISA_RESET,    SI2_ISA_RESET_CLEAR);		write_sx_byte (board, SI2_ISA_INTCLEAR, SI2_ISA_INTCLEAR_SET);	}	return 1;}#define SX_IRQ_REG_VAL(board) \        ((board->flags & SX_ISA_BOARD)?(board->irq << 4):0)/* Note. The SX register is write-only. Therefore, we have to enable the   bus too. This is a no-op, if you don't mess with this driver... */static int sx_start_interrupts (struct sx_board *board){	/* Don't call this with board->irq == 0 */	if (IS_SX_BOARD(board)) {		write_sx_byte (board, SX_CONFIG, SX_IRQ_REG_VAL (board) | 		                                 SX_CONF_BUSEN | 		                                 SX_CONF_HOSTIRQ);	} else if (IS_EISA_BOARD(board)) {		inb(board->eisa_base+0xc03);  	} else if (IS_SI1_BOARD(board)) {	       write_sx_byte (board, SI1_ISA_INTCL,0);	       write_sx_byte (board, SI1_ISA_INTCL_CLEAR,0);	} else {		switch (board->irq) {		case 11:write_sx_byte (board, SI2_ISA_IRQ11, SI2_ISA_IRQ11_SET);break;		case 12:write_sx_byte (board, SI2_ISA_IRQ12, SI2_ISA_IRQ12_SET);break;		case 15:write_sx_byte (board, SI2_ISA_IRQ15, SI2_ISA_IRQ15_SET);break;		default:printk (KERN_INFO "sx: SI/XIO card doesn't support interrupt %d.\n", 		                board->irq);		return 0;		}		write_sx_byte (board, SI2_ISA_INTCLEAR, SI2_ISA_INTCLEAR_SET);	}	return 1;}static int sx_send_command (struct sx_port *port,                      	    int command, int mask, int newstat){	func_enter2 ();	write_sx_byte (port->board, CHAN_OFFSET (port, hi_hstat), command);	func_exit ();	return sx_busy_wait_eq (port->board, CHAN_OFFSET (port, hi_hstat), mask, newstat);}static char *mod_type_s (int module_type){	switch (module_type) {	case TA4:       return "TA4";	case TA8:       return "TA8";	case TA4_ASIC:  return "TA4_ASIC";	case TA8_ASIC:  return "TA8_ASIC";	case MTA_CD1400:return "MTA_CD1400";	case SXDC:      return "SXDC";	default:return "Unknown/invalid";	}}static char *pan_type_s (int pan_type){	switch (pan_type) {	case MOD_RS232DB25:     return "MOD_RS232DB25";	case MOD_RS232RJ45:     return "MOD_RS232RJ45";	case MOD_RS422DB25:     return "MOD_RS422DB25";	case MOD_PARALLEL:      return "MOD_PARALLEL";	case MOD_2_RS232DB25:   return "MOD_2_RS232DB25";	case MOD_2_RS232RJ45:   return "MOD_2_RS232RJ45";	case MOD_2_RS422DB25:   return "MOD_2_RS422DB25";	case MOD_RS232DB25MALE: return "MOD_RS232DB25MALE";	case MOD_2_PARALLEL:    return "MOD_2_PARALLEL";	case MOD_BLANK:         return "empty";	default:return "invalid";	}}static int mod_compat_type (int module_type){	return module_type >> 4;}static void sx_reconfigure_port(struct sx_port *port){	if (sx_read_channel_byte (port, hi_hstat) == HS_IDLE_OPEN) {		if (sx_send_command (port, HS_CONFIG, -1, HS_IDLE_OPEN) != 1) {			printk (KERN_WARNING "sx: Sent reconfigure command, but card didn't react.\n");		}	} else {		sx_dprintk (SX_DEBUG_TERMIOS, 		            "sx: Not sending reconfigure: port isn't open (%02x).\n", 		            sx_read_channel_byte (port, hi_hstat));	}	}static void sx_setsignals (struct sx_port *port, int dtr, int rts){	int t;	func_enter2 ();	t = sx_read_channel_byte (port, hi_op);	if (dtr >= 0) t = dtr? (t | OP_DTR): (t & ~OP_DTR);	if (rts >= 0) t = rts? (t | OP_RTS): (t & ~OP_RTS);	sx_write_channel_byte (port, hi_op, t);	sx_dprintk (SX_DEBUG_MODEMSIGNALS, "setsignals: %d/%d\n", dtr, rts);	func_exit ();}static int sx_getsignals (struct sx_port *port){	int i_stat,o_stat;	o_stat = sx_read_channel_byte (port, hi_op);	i_stat = sx_read_channel_byte (port, hi_ip);	sx_dprintk (SX_DEBUG_MODEMSIGNALS, "getsignals: %d/%d  (%d/%d) %02x/%02x\n",	            (o_stat & OP_DTR) != 0, (o_stat & OP_RTS) != 0,	            port->c_dcd, sx_get_CD (port),	            sx_read_channel_byte (port, hi_ip),	            sx_read_channel_byte (port, hi_state));	return (((o_stat & OP_DTR)?TIOCM_DTR:0) |	        ((o_stat & OP_RTS)?TIOCM_RTS:0) |	        ((i_stat & IP_CTS)?TIOCM_CTS:0) |	        ((i_stat & IP_DCD)?TIOCM_CAR:0) |	        ((i_stat & IP_DSR)?TIOCM_DSR:0) |	        ((i_stat & IP_RI)?TIOCM_RNG:0)	        );}static void sx_set_baud (struct sx_port *port){	int t;	if (port->board->ta_type == MOD_SXDC) {		switch (port->gs.baud) {		  /* Save some typing work... */#define e(x) case x:t= BAUD_ ## x ; break			e(50);e(75);e(110);e(150);e(200);e(300);e(600);                        e(1200);e(1800);e(2000);e(2400);e(4800);e(7200);                        e(9600);e(14400);e(19200);e(28800);e(38400);                        e(56000);e(57600);e(64000);e(76800);e(115200);			e(128000);e(150000);e(230400);e(256000);e(460800);                        e(921600);		case 134    :t = BAUD_134_5;   break;		case 0      :t = -1;								 break;		default:			/* Can I return "invalid"? */			t = BAUD_9600;			printk (KERN_INFO "sx: unsupported baud rate: %d.\n", port->gs.baud);			break;		}#undef e		if (t > 0) {			/* The baud rate is not set to 0, so we're enabeling DTR... -- REW */			sx_setsignals (port, 1, -1); 			/* XXX This is not TA & MTA compatible */			sx_write_channel_byte (port, hi_csr, 0xff);			sx_write_channel_byte (port, hi_txbaud, t);			sx_write_channel_byte (port, hi_rxbaud, t);		} else {			sx_setsignals (port, 0, -1);		}	} else {		switch (port->gs.baud) {#define e(x) case x:t= CSR_ ## x ; break			e(75);e(150);e(300);e(600);e(1200);e(2400);e(4800);                        e(1800);e(9600);			e(19200);e(57600);e(38400);			/* TA supports 110, but not 115200, MTA supports 115200, but not 110 */		case 110: 			if (port->board->ta_type == MOD_TA) {				t = CSR_110;				break;			} else {				t = CSR_9600;				printk (KERN_INFO "sx: Unsupported baud rate: %d.\n", port->gs.baud);				break;			}		case 115200: 			if (port->board->ta_type == MOD_TA) {				t = CSR_9600;				printk (KERN_INFO "sx: Unsupported baud rate: %d.\n", port->gs.baud);				break;			} else {				t = CSR_110;				break;			}		case 0      :t = -1;								 break;		default:			t = CSR_9600;			printk (KERN_INFO "sx: Unsupported baud rate: %d.\n", port->gs.baud);			break;		}#undef e		if (t >= 0) {			sx_setsignals (port, 1, -1);			sx_write_channel_byte (port, hi_csr, t * 0x11);		} else {			sx_setsignals (port, 0, -1);		}	}}/* Simon Allen's version of this routine was 225 lines long. 85 is a lot   better. -- REW */static int sx_set_real_termios (void *ptr){	struct sx_port *port = ptr;	func_enter2();	if (!port->gs.tty)		return 0;	/* What is this doing here? -- REW	   Ha! figured it out. It is to allow you to get DTR active again	   if you've dropped it with stty 0. Moved to set_baud, where it	   belongs (next to the drop dtr if baud == 0) -- REW */	/* sx_setsignals (port, 1, -1); */	sx_set_baud (port);#define CFLAG port->gs.tty->termios->c_cflag	sx_write_channel_byte (port, hi_mr1,	                       (C_PARENB (port->gs.tty)? MR1_WITH:MR1_NONE) |	                       (C_PARODD (port->gs.tty)? MR1_ODD:MR1_EVEN) |	                       (C_CRTSCTS(port->gs.tty)? MR1_RTS_RXFLOW:0) |	                       (((CFLAG & CSIZE)==CS8) ? MR1_8_BITS:0) |	                       (((CFLAG & CSIZE)==CS7) ? MR1_7_BITS:0) |	                       (((CFLAG & CSIZE)==CS6) ? MR1_6_BITS:0) |	                       (((CFLAG & CSIZE)==CS5) ? MR1_5_BITS:0) );	sx_write_channel_byte (port, hi_mr2,	                       (C_CRTSCTS(port->gs.tty)?MR2_CTS_TXFLOW:0) |	                       (C_CSTOPB (port->gs.tty)?MR2_2_STOP:MR2_1_STOP));

⌨️ 快捷键说明

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