/*
* Stuff used by all variants of the driver
*
* Copyright (c) 2001 by Stefan Eilers,
* Hansjoerg Lipp <hjlipp@web.de>,
* Tilman Schmidt <tilman@imap.cc>.
*
* =====================================================================
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
* =====================================================================
*/
#include "gigaset.h"
#include <linux/ctype.h>
#include <linux/module.h>
#include <linux/moduleparam.h>
/* Version Information */
#define DRIVER_AUTHOR "Hansjoerg Lipp <hjlipp@web.de>, Tilman Schmidt <tilman@imap.cc>, Stefan Eilers"
#define DRIVER_DESC "Driver for Gigaset 307x"
/* Module parameters */
int gigaset_debuglevel = DEBUG_DEFAULT;
EXPORT_SYMBOL_GPL(gigaset_debuglevel);
module_param_named(debug, gigaset_debuglevel, int, S_IRUGO|S_IWUSR);
MODULE_PARM_DESC(debug, "debug level");
/* driver state flags */
#define VALID_MINOR 0x01
#define VALID_ID 0x02
void gigaset_dbg_buffer(enum debuglevel level, const unsigned char *msg,
size_t len, const unsigned char *buf)
{
unsigned char outbuf[80];
unsigned char c;
size_t space = sizeof outbuf - 1;
unsigned char *out = outbuf;
size_t numin = len;
while (numin--) {
c = *buf++;
if (c == '~' || c == '^' || c == '\\') {
if (!space--)
break;
*out++ = '\\';
}
if (c & 0x80) {
if (!space--)
break;
*out++ = '~';
c ^= 0x80;
}
if (c < 0x20 || c == 0x7f) {
if (!space--)
break;
*out++ = '^';
c ^= 0x40;
}
if (!space--)
break;
*out++ = c;
}
*out = 0;
gig_dbg(level, "%s (%u bytes): %s", msg, (unsigned) len, outbuf);
}
EXPORT_SYMBOL_GPL(gigaset_dbg_buffer);
static int setflags(struct cardstate *cs, unsigned flags, unsigned delay)
{
int r;
r = cs->ops->set_modem_ctrl(cs, cs->control_state, flags);
cs->control_state = flags;
if (r < 0)
return r;
if (delay) {
set_current_state(TASK_INTERRUPTIBLE);
schedule_timeout(delay * HZ / 1000);
}
return 0;
}
int gigaset_enterconfigmode(struct cardstate *cs)
{
int i, r;
cs->control_state = TIOCM_RTS; //FIXME
r = setflags(cs, TIOCM_DTR, 200);
if (r < 0)
goto error;
r = setflags(cs, 0, 200);
if (r < 0)
goto error;
for (i = 0; i < 5; ++i) {
r = setflags(cs, TIOCM_RTS, 100);
if (r < 0)
goto error;
r = setflags(cs, 0, 100);
if (r < 0)
goto error;
}
r