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

📄 sx.c

📁 linux 内核源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
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 doesn't 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));	switch (CFLAG & CSIZE) {	case CS8:		sx_write_channel_byte(port, hi_mask, 0xff);		break;	case CS7:		sx_write_channel_byte(port, hi_mask, 0x7f);		break;	case CS6:		sx_write_channel_byte(port, hi_mask, 0x3f);		break;	case CS5:		sx_write_channel_byte(port, hi_mask, 0x1f);		break;	default:

⌨️ 快捷键说明

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