static int comxlapb_exit(struct net_device *dev) 
{
	struct comx_channel *ch = dev->priv;

	dev->flags		= 0;
	dev->type		= 0;
	dev->mtu		= 0;
	dev->hard_header_len    = 0;

	ch->LINE_rx	= NULL;
	ch->LINE_tx	= NULL;
	ch->LINE_status = NULL;
	ch->LINE_open	= NULL;
	ch->LINE_close	= NULL;
	ch->LINE_xmit	= NULL;
	ch->LINE_header	= NULL;
	ch->LINE_statistics = NULL;

	if (ch->debug_flags & DEBUG_COMX_LAPB) {
		comx_debug(dev, "%s: unregistering lapb\n", dev->name);
	}
	lapb_unregister(dev->priv);

	remove_proc_entry(FILENAME_T1, ch->procdir);
	remove_proc_entry(FILENAME_T2, ch->procdir);
	remove_proc_entry(FILENAME_N2, ch->procdir);
	remove_proc_entry(FILENAME_MODE, ch->procdir);
	remove_proc_entry(FILENAME_WINDOW, ch->procdir);

	MOD_DEC_USE_COUNT;
	return 0;
}
Esempio n. 2
0
static int hdlc_close(struct net_device *dev)
{
	hdlc_device *hdlc = dev_to_hdlc(dev);

	hdlc->close(hdlc);

	if (mode_is(hdlc, MODE_FR | MODE_SOFT) ||
	    mode_is(hdlc, MODE_CISCO | MODE_SOFT))
		fr_cisco_close(hdlc);
#ifdef CONFIG_HDLC_PPP
	else if (mode_is(hdlc, MODE_PPP | MODE_SOFT)) {
		sppp_close(dev);
		sppp_detach(dev);
		dev->rebuild_header = NULL;
		dev->change_mtu = hdlc_change_mtu;
		dev->mtu = HDLC_MAX_MTU;
		dev->hard_header_len = 16;
	}
#endif
#ifdef CONFIG_HDLC_X25
	else if (mode_is(hdlc, MODE_X25))
		lapb_unregister(hdlc);
#endif
	return 0;
}
Esempio n. 3
0
/* Close the low-level part of the X.25 channel. Easy! */
static int x25_asy_close(struct net_device *dev)
{
	struct x25_asy *sl = (struct x25_asy*)(dev->priv);
	int err;

	if (sl->tty == NULL)
		return -EBUSY;

	sl->tty->flags &= ~(1 << TTY_DO_WRITE_WAKEUP);
	netif_stop_queue(dev);
	if((err=lapb_unregister(sl))!=LAPB_OK)
		printk(KERN_ERR "x25_asy_close: lapb_unregister error -%d\n",err);
	return 0;
}
Esempio n. 4
0
static int lapbeth_close(struct net_device *dev)
{
	struct lapbethdev *lapbeth;
	int err;

	netif_stop_queue(dev);
	
	lapbeth = (struct lapbethdev *)dev->priv;

	if ((err = lapb_unregister(lapbeth)) != LAPB_OK)
		printk(KERN_ERR "lapbeth: lapb_unregister error - %d\n", err);

	MOD_DEC_USE_COUNT;

	return 0;
}
Esempio n. 5
0
/* Close the low-level part of the X.25 channel. Easy! */
static int x25_asy_close(struct net_device *dev)
{
	struct x25_asy *sl = (struct x25_asy*)(dev->priv);
	int err;

	spin_lock(&sl->lock);
	if (sl->tty) 
		sl->tty->flags &= ~(1 << TTY_DO_WRITE_WAKEUP);

	netif_stop_queue(dev);
	sl->rcount = 0;
	sl->xleft  = 0;
	if((err=lapb_unregister(dev))!=LAPB_OK)
		printk(KERN_ERR "x25_asy_close: lapb_unregister error -%d\n",err);
	spin_unlock(&sl->lock);
	return 0;
}
Esempio n. 6
0
/* Close the low-level part of the X.25 channel. Easy! */
static int x25_asy_close(struct net_device *dev)
{
	struct x25_asy *sl = netdev_priv(dev);
	int err;

	spin_lock(&sl->lock);
	if (sl->tty)
		clear_bit(TTY_DO_WRITE_WAKEUP, &sl->tty->flags);

	netif_stop_queue(dev);
	sl->rcount = 0;
	sl->xleft  = 0;
	err = lapb_unregister(dev);
	if (err != LAPB_OK)
		printk(KERN_ERR "x25_asy_close: lapb_unregister error -%d\n",
			err);
	spin_unlock(&sl->lock);
	return 0;
}
Esempio n. 7
0
/*
 * Close down an X.25 channel.
 * This means flushing out any pending queues, and then restoring the
 * TTY line discipline to what it was before it got hooked to X.25
 * (which usually is TTY again).
 */
static void x25_asy_close_tty(struct tty_struct *tty)
{
	struct x25_asy *sl = tty->disc_data;
	int err;

	/* First make sure we're connected. */
	if (!sl || sl->magic != X25_ASY_MAGIC)
		return;

	rtnl_lock();
	if (sl->dev->flags & IFF_UP)
		dev_close(sl->dev);
	rtnl_unlock();

	err = lapb_unregister(sl->dev);
	if (err != LAPB_OK)
		pr_err("x25_asy_close: lapb_unregister error: %d\n",
		       err);

	tty->disc_data = NULL;
	sl->tty = NULL;
	x25_asy_free(sl);
}
Esempio n. 8
0
int manual_process() {
	struct lapb_callbacks callbacks;
	int lapb_res;

	fd_set			read_set;
	struct timeval	timeout;
	int sr = 0;

	char buffer[4];

	/* LAPB init */
	bzero(&callbacks, sizeof(struct lapb_callbacks));
	callbacks.transmit_data = transmit_data;
	callbacks.debug = lapb_debug;
	lapb_res = lapb_register(&callbacks, NULL, &lapb_server);
	if (lapb_res != LAPB_OK) {
		printf("lapb_register return %d\n", lapb_res);
		exit(EXIT_FAILURE);
	};
	//lapb_server->mode = LAPB_DCE;

	print_man_commands();

	while (!exit_flag) {
		FD_ZERO(&read_set);
		FD_SET(fileno(stdin), &read_set);
		timeout.tv_sec  = 0;
		timeout.tv_usec = 100000;
		sr = select(fileno(stdin) + 1, &read_set, NULL, NULL, &timeout);
		if (sr > 0) {
			bzero(buffer, sizeof(buffer));
			while (read(0, buffer, sizeof(buffer)) <= 1)
				write(0, ">", 1);
			//printf("\n");
			int action = atoi(buffer);
			switch (action) {
				case 1: /* SABM */
					//lapb_send_control(lapb_server, LAPB_SABM, LAPB_POLLON, LAPB_COMMAND);
					//
					break;
				case 2: /* SABME */
					//lapb_send_control(lapb_server, LAPB_SABME, LAPB_POLLON, LAPB_COMMAND);
					//
					break;
				case 3: /* DISC */
					//lapb_send_control(lapb_server, LAPB_DISC, LAPB_POLLON, LAPB_COMMAND);
					//
					break;
				case 4: /* UA */
					//lapb_send_control(lapb_server, LAPB_UA, LAPB_POLLON, LAPB_RESPONSE);
					//
					break;
				case 5: /* DM */
					//lapb_send_control(lapb_server, LAPB_DM, LAPB_POLLON, LAPB_RESPONSE);
					//
					break;
				case 6: /* RR good*/
					//lapb_send_control(lapb_server, LAPB_RR, LAPB_POLLON, LAPB_RESPONSE);
					//
					break;
				case 7: /* RR bad*/
					//lapb_server->vr++;
					//lapb_send_control(lapb_server, LAPB_RR, LAPB_POLLON, LAPB_RESPONSE);
					//
					break;
				case 0:
					exit_flag = TRUE;
					break;
				default:
					printf("Command is not supported\n\n");
					break;
			};
		};

	};


	lapb_unregister(lapb_server);

	return EXIT_SUCCESS;
}
Esempio n. 9
0
int main (int argc, char *argv[]) {
	(void)argc;
	(void)argv;
	int ret;
	int dbg = TRUE;

	struct lapb_callbacks callbacks;
	int lapb_res;

	char buffer[2048];

	unsigned char lapb_equipment_type = LAPB_DCE;
	unsigned char lapb_modulo = LAPB_STANDARD;

	pthread_t server_thread;
	struct tcp_server_struct * server_struct = NULL;

	pthread_t timer_thread;
	struct timer_thread_struct * timer_struct = NULL;

	pthread_t logger_thread;

	printf("*******************************************\n");
	printf("******                               ******\n");
	printf("******  LAPB EMULATOR (server side)  ******\n");
	printf("******                               ******\n");
	printf("*******************************************\n");

	/* Initialize syslog */
	setlogmask (LOG_UPTO (LOG_DEBUG));
	openlog ("server_app", LOG_CONS | LOG_PID | LOG_NDELAY, LOG_LOCAL1);

	ret = pthread_create(&logger_thread, NULL, logger_function, NULL);
	if (ret) {
		perror("Error - pthread_create()");
		closelog();
		exit(EXIT_FAILURE);
	};
	printf("Logger thread created(code %d)\n", ret);
	while (!is_logger_started())
		sleep_ms(200);
	printf("Logger started\n\n");

	lapb_debug(0, "Program started by User %d", getuid ());

	/* Setup signal handler */
	setup_signals_handler();

	if (dbg)
		goto label_1;

	/* Select program mode */
	printf("\nSelect program mode:\n1. Automatic\n2. Manual\n");
	write(0, ">", 1);
	while (read(0, buffer, sizeof(buffer)) <= 1)
		write(0, ">", 1);
	if (atoi(buffer) == 2)
		AutomaticMode = FALSE;
	else {
		/* Set up equipment mode: DTE or DCE */
		printf("\nSelect equipment type:\n1. DTE\n2. DCE\n");
		write(0, ">", 1);
		while (read(0, buffer, sizeof(buffer)) <= 1)
			write(0, ">", 1);
		if (atoi(buffer) == 1)
			lapb_equipment_type = LAPB_DTE;

		/* Set up lapb modulo: STANDARD or EXTENDED */
		printf("\nSelect modulo value:\n1. STANDARD(8)\n2. EXTENDED(128)\n");
		write(0, ">", 1);
		while (read(0, buffer, sizeof(buffer)) <= 1)
			write(0, ">", 1);
		if (atoi(buffer) == 2)
			lapb_modulo = LAPB_EXTENDED;
	};

label_1:

	/* Create TCP server */
	server_struct = malloc(sizeof(struct tcp_server_struct));

	if (dbg) {
		server_struct->port = 1234;
		goto label_2;
	};

	printf("\nEnter server port[1234]: ");
	fgets(buffer, sizeof(buffer) - 1, stdin);
	int tmp_len = strlen(buffer);
	if (tmp_len == 1)
		server_struct->port = 1234;
	else {
		buffer[strlen(buffer) - 1] = 0;
		server_struct->port = atoi(buffer);
	};

label_2:

	/* TCP server callbacks */
	server_struct->new_data_received = new_data_received;
	server_struct->no_active_connection = no_active_connection;

	ret = pthread_create(&server_thread, NULL, server_function, (void*)server_struct);
	if (ret) {
		fprintf(stderr, "Error - pthread_create() return code: %d\n", ret);
		exit(EXIT_FAILURE);
	};
	printf("TCP server thread created(code %d)\n", ret);
	while (!is_server_started())
		sleep_ms(200);
	printf("TCP server started\n\n");

	if (!AutomaticMode)
		return manual_process();

	/* Create timer */
	timer_struct = malloc(sizeof(struct timer_thread_struct));
	timer_struct->interval = 10; /* milliseconds */
	//bzero(timer_struct->timers_list, sizeof(timer_struct->timers_list));
	ret = pthread_create(&timer_thread, NULL, timer_thread_function, (void*)timer_struct);
	if (ret) {
		lapb_debug(0, "Error - pthread_create() return code: %d\n", ret);
		closelog();
		exit(EXIT_FAILURE);
	};
	printf("Timer thread created(code %d)\n", ret);
	while (!is_timer_thread_started())
		sleep_ms(200);
	printf("Timer started\n\n");


	/* LAPB init */
	bzero(&callbacks, sizeof(struct lapb_callbacks));
	callbacks.connect_confirmation = connect_confirmation;
	callbacks.connect_indication = connect_indication;
	callbacks.disconnect_confirmation = disconnect_confirmation;
	callbacks.disconnect_indication = disconnect_indication;
	callbacks.data_indication = data_indication;
	callbacks.transmit_data = transmit_data;

	callbacks.add_timer = timer_add;
	callbacks.del_timer = timer_del;
	callbacks.start_timer = timer_start;
	callbacks.stop_timer = timer_stop;

	callbacks.debug = lapb_debug;

	/* Define LAPB values */
	struct lapb_params params;
	params.mode = lapb_modulo | LAPB_SLP | lapb_equipment_type;
	params.window = LAPB_DEFAULT_SWINDOW;
	params.N1 = LAPB_DEFAULT_N1;	/* I frame size is 135 bytes */
	params.T201_interval = 1000;	/* 1s */
	params.T202_interval = 100;		/* 0.1s */
	params.N201 = 10;					/* T201 timer will repeat for 10 times */
	params.low_order_bits = FALSE;
	params.auto_connecting = TRUE;

	lapb_res = lapb_register(&callbacks, &params, &lapb_server);
	if (lapb_res != LAPB_OK) {
		printf("lapb_register return %d\n", lapb_res);
		exit(EXIT_FAILURE);
	};
	//lapb_server->mode = lapb_modulo | LAPB_SLP | lapb_equipment_type;

	/* Redefine some default values */
	lapb_server->T201_interval = 1000; /* 1s */
	lapb_server->T202_interval = 100;  /* 0.5s */
	lapb_server->N201 = 10;	/* Try 10 times */
	//lapb_server->low_order_bits = TRUE;

	/* Start endless loop */
	printf("Run Main loop\n\n");
	main_loop(lapb_server);

	printf("Main loop ended\n");

	terminate_tcp_server();
	while (is_server_started())
		sleep_ms(200);
	printf("TCP server stopped\n");
	int * thread_result;
	pthread_join(server_thread, (void **)&thread_result);
	printf("TCP server thread exit(code %d)\n", *thread_result);
	free(thread_result);
	if (server_struct != NULL)
		free(server_struct);

	terminate_timer_thread();
	while (is_timer_thread_started())
		sleep_ms(200);
	printf("Timer stopped\n");
	pthread_join(timer_thread, (void **)&thread_result);
	printf("Timer thread exit(code %d)\n", *thread_result);
	free(thread_result);
	if (timer_struct != NULL)
		free(timer_struct);

	lapb_unregister(lapb_server);

	terminate_logger();
	while (is_logger_started())
		sleep_ms(200);
	printf("Logger stopped\n");
	pthread_join(logger_thread, (void **)&thread_result);
	printf("Logger thread exit(code %d)\n", *thread_result);
	free(thread_result);


	/* Close syslog */
	closelog();
	printf("Exit application\n\n");
	return EXIT_SUCCESS;
}
Esempio n. 10
0
static void x25_close(struct net_device *dev)
{
	lapb_unregister(dev);
}
Esempio n. 11
0
int main (int argc, char *argv[]) {
	(void)argc;
	(void)argv;
	int ret;
	int dbg = TRUE;

	struct lapb_callbacks lapb_callbacks;
	int res;

	char buffer[2048];

	_uchar lapb_equipment_type = LAPB_DCE;
	_uchar lapb_modulo = LAPB_STANDARD;

	pthread_t server_thread;
	struct tcp_server_struct * server_thread_struct = NULL;

	pthread_t timer_thread;
	struct timer_thread_struct * timer_thread_struct = NULL;

	pthread_t logger_thread;

	printf("*******************************************\n");
	printf("******                               ******\n");
	printf("******  X25 EMULATOR (server side)  ******\n");
	printf("******                               ******\n");
	printf("*******************************************\n");

	/* Initialize syslog */
	setlogmask (LOG_UPTO (LOG_DEBUG));
	openlog ("server_app", LOG_CONS | LOG_PID | LOG_NDELAY, LOG_LOCAL1);

	ret = pthread_create(&logger_thread, NULL, logger_function, NULL);
	if (ret) {
		perror("Error - pthread_create()");
		closelog();
		exit(EXIT_FAILURE);
	};
	printf("Logger thread created(code %d)\n", ret);
	while (!is_logger_started())
		sleep_ms(200);
	printf("Logger started\n\n");

	lapb_debug(0, "Program started by User %d", getuid ());

	/* Setup signal handler */
	setup_signals_handler();

	if (dbg)
		goto label_1;

	/* Select program mode */
	printf("\nSelect program mode:\n1. Automatic\n2. Manual\n");
	write(0, ">", 1);
	while (read(0, buffer, sizeof(buffer)) <= 1)
		write(0, ">", 1);
	if (atoi(buffer) == 2)
		AutomaticMode = FALSE;
	else {
		/* Set up equipment mode: DTE or DCE */
		printf("\nSelect equipment type:\n1. DTE\n2. DCE\n");
		write(0, ">", 1);
		while (read(0, buffer, sizeof(buffer)) <= 1)
			write(0, ">", 1);
		if (atoi(buffer) == 1)
			lapb_equipment_type = LAPB_DTE;

		/* Set up lapb modulo: STANDARD or EXTENDED */
		printf("\nSelect modulo value:\n1. STANDARD(8)\n2. EXTENDED(128)\n");
		write(0, ">", 1);
		while (read(0, buffer, sizeof(buffer)) <= 1)
			write(0, ">", 1);
		if (atoi(buffer) == 2)
			lapb_modulo = LAPB_EXTENDED;
	};

label_1:

	/* Create TCP server */
	server_thread_struct = malloc(sizeof(struct tcp_server_struct));

	if (dbg) {
		server_thread_struct->port = 1234;
		goto label_2;
	};

	printf("\nEnter server port[1234]: ");
	fgets(buffer, sizeof(buffer) - 1, stdin);
	int tmp_len = strlen(buffer);
	if (tmp_len == 1)
		server_thread_struct->port = 1234;
	else {
		buffer[strlen(buffer) - 1] = 0;
		server_thread_struct->port = atoi(buffer);
	};

label_2:

	/* TCP server callbacks */
	server_thread_struct->new_data_received = new_data_received;
	server_thread_struct->no_active_connection = no_active_connection;

	ret = pthread_create(&server_thread, NULL, server_function, (void*)server_thread_struct);
	if (ret) {
		fprintf(stderr, "Error - pthread_create() return code: %d\n", ret);
		exit(EXIT_FAILURE);
	};
	printf("TCP server thread created(code %d)\n", ret);
	while (!is_server_started())
		sleep_ms(200);
	printf("TCP server started\n\n");

//	if (!AutomaticMode)
//		return manual_process();

	/* Create timer */
	timer_thread_struct = malloc(sizeof(struct timer_thread_struct));
	timer_thread_struct->interval = 10; /* milliseconds */
	timer_thread_struct->main_lock = main_lock;
	timer_thread_struct->main_unlock = main_unlock;
	ret = pthread_create(&timer_thread, NULL, timer_thread_function, (void*)timer_thread_struct);
	if (ret) {
		lapb_debug(0, "Error - pthread_create() return code: %d\n", ret);
		closelog();
		exit(EXIT_FAILURE);
	};
	printf("Timer thread created(code %d)\n", ret);
	while (!is_timer_thread_started())
		sleep_ms(200);
	printf("Timer started\n\n");


	/* LAPB init */
	bzero(&lapb_callbacks, sizeof(struct lapb_callbacks));
	lapb_callbacks.connect_confirmation = lapb_connect_confirmation_cb;
	lapb_callbacks.connect_indication = lapb_connect_indication_cb;
	lapb_callbacks.disconnect_confirmation = lapb_disconnect_confirmation_cb;
	lapb_callbacks.disconnect_indication = lapb_disconnect_indication_cb;
	lapb_callbacks.data_indication = lapb_data_indication_cb;
	lapb_callbacks.transmit_data = lapb_transmit_data;

	lapb_callbacks.add_timer = timer_add;
	lapb_callbacks.del_timer = timer_del;
	lapb_callbacks.start_timer = timer_start;
	lapb_callbacks.stop_timer = timer_stop;

	lapb_callbacks.debug = lapb_debug;

	/* Define LAPB values */
	struct lapb_params lapb_params;
	lapb_params.mode = lapb_modulo | LAPB_SLP | lapb_equipment_type;
	lapb_params.window = LAPB_DEFAULT_SWINDOW;
	lapb_params.N1 = LAPB_DEFAULT_N1;		/* I frame size is 135 bytes */
	lapb_params.T201_interval = 1000;		/* 1s */
	lapb_params.T202_interval = 100;		/* 0.1s */
	lapb_params.N201 = 10;					/* T201 timer will repeat for 10 times */
	lapb_params.low_order_bits = FALSE;
	lapb_params.auto_connecting = TRUE;

	res = lapb_register(&lapb_callbacks, &lapb_params, &lapb_server);
	if (res != LAPB_OK) {
		printf("lapb_register return %d\n", res);
		exit(EXIT_FAILURE);
	};




	/* X25 init */
	struct x25_callbacks x25_callbacks;
	bzero(&x25_callbacks, sizeof(struct x25_callbacks));
	x25_callbacks.link_connect_request = lapb_connect_request;
	x25_callbacks.link_disconnect_request = lapb_disconnect_request;
	x25_callbacks.link_send_frame = lapb_data_request;

	x25_callbacks.call_indication = x25_call_indication_cb;
	x25_callbacks.call_accepted = x25_call_accepted_cb;
	x25_callbacks.data_indication = x25_data_indication_cb;

	x25_callbacks.add_timer = timer_add;
	x25_callbacks.del_timer = timer_del;
	x25_callbacks.start_timer = timer_start;
	x25_callbacks.stop_timer = timer_stop;

	x25_callbacks.debug = x25_debug;

	/* Define X25 values */
	//struct x25_params x25_params;

	//res = x25_register(&x25_callbacks, &x25_params, &x25_server);
	res = x25_register(&x25_callbacks, NULL, &x25_server);
	if (res != X25_OK) {
		printf("x25_register return %d\n", res);
		goto exit;
	};
	x25_server->mode = (lapb_equipment_type & LAPB_DCE ? X25_DCE : X25_DTE) | (lapb_modulo & LAPB_EXTENDED ? X25_EXTENDED : X25_STANDARD);
	x25_add_link(x25_server, lapb_server);
	lapb_server->L3_ptr = x25_server;

	printf("Enter local X25 address[7654321]: ");
	fgets(x25_server->source_addr.x25_addr, 16, stdin);
	tmp_len = strlen(x25_server->source_addr.x25_addr);
	if (tmp_len == 1)
		sprintf(x25_server->source_addr.x25_addr, "7654321");
	else
		x25_server->source_addr.x25_addr[tmp_len - 1] = 0;

	struct x25_address dest_addr;
	sprintf(dest_addr.x25_addr, "1234567");

	x25_server->lci = 128;

	x25_debug(0, "[X25]");
	x25_debug(0, "[X25]");
	x25_debug(0, "[X25]");

	/* Start endless loop */
	printf("Run Main loop\n\n");
	main_loop(x25_server, &dest_addr);

	printf("Main loop ended\n");

exit:
	terminate_tcp_server();
	while (is_server_started())
		sleep_ms(200);
	printf("TCP server stopped\n");
	int * thread_result;
	pthread_join(server_thread, (void **)&thread_result);
	printf("TCP server thread exit(code %d)\n", *thread_result);
	free(thread_result);
	if (server_thread_struct != NULL)
		free(server_thread_struct);

	terminate_timer_thread();
	while (is_timer_thread_started())
		sleep_ms(200);
	printf("Timer stopped\n");
	pthread_join(timer_thread, (void **)&thread_result);
	printf("Timer thread exit(code %d)\n", *thread_result);
	free(thread_result);
	if (timer_thread_struct != NULL)
		free(timer_thread_struct);

	lapb_unregister(lapb_server);

	terminate_logger();
	while (is_logger_started())
		sleep_ms(200);
	printf("Logger stopped\n");
	pthread_join(logger_thread, (void **)&thread_result);
	printf("Logger thread exit(code %d)\n", *thread_result);
	free(thread_result);


	/* Close syslog */
	closelog();
	printf("Exit application\n\n");
	return EXIT_SUCCESS;
}
Esempio n. 12
0
static int hdlc_open(struct net_device *dev)
{
	hdlc_device *hdlc = dev_to_hdlc(dev);
	int result;

	if (hdlc->mode == MODE_NONE)
		return -ENOSYS;

	memset(&(hdlc->stats), 0, sizeof(struct net_device_stats));

	if (mode_is(hdlc, MODE_FR | MODE_SOFT) ||
	    mode_is(hdlc, MODE_CISCO | MODE_SOFT))
		fr_cisco_open(hdlc);
#ifdef CONFIG_HDLC_PPP
	else if (mode_is(hdlc, MODE_PPP | MODE_SOFT)) {
		sppp_attach(&hdlc->pppdev);
		/* sppp_attach nukes them. We don't need syncppp's ioctl */
		dev->do_ioctl = hdlc_ioctl;
		hdlc->pppdev.sppp.pp_flags &= ~PP_CISCO;
		dev->type = ARPHRD_PPP;
		result = sppp_open(dev);
		if (result) {
			sppp_detach(dev);
			return result;
		}
	}
#endif
#ifdef CONFIG_HDLC_X25
	else if (mode_is(hdlc, MODE_X25)) {
		struct lapb_register_struct cb;

		cb.connect_confirmation = x25_connected;
		cb.connect_indication = x25_connected;
		cb.disconnect_confirmation = x25_disconnected;
		cb.disconnect_indication = x25_disconnected;
		cb.data_indication = x25_data_indication;
		cb.data_transmit = x25_data_transmit;

		result = lapb_register(hdlc, &cb);
		if (result != LAPB_OK)
			return result;
	}
#endif
	result = hdlc->open(hdlc);
	if (result) {
		if (mode_is(hdlc, MODE_FR | MODE_SOFT) ||
		    mode_is(hdlc, MODE_CISCO | MODE_SOFT))
			fr_cisco_close(hdlc);
#ifdef CONFIG_HDLC_PPP
		else if (mode_is(hdlc, MODE_PPP | MODE_SOFT)) {
			sppp_close(dev);
			sppp_detach(dev);
			dev->rebuild_header = NULL;
			dev->change_mtu = hdlc_change_mtu;
			dev->mtu = HDLC_MAX_MTU;
			dev->hard_header_len = 16;
		}
#endif
#ifdef CONFIG_HDLC_X25
		else if (mode_is(hdlc, MODE_X25))
			lapb_unregister(hdlc);
#endif
	}

	return result;
}