summaryrefslogtreecommitdiff
path: root/kernel/xpp/card_pri.c
diff options
context:
space:
mode:
authortzafrir <tzafrir@5390a7c7-147a-4af0-8ec9-7488f05a26cb>2008-05-13 21:08:09 +0000
committertzafrir <tzafrir@5390a7c7-147a-4af0-8ec9-7488f05a26cb>2008-05-13 21:08:09 +0000
commitd7e54a785544ac40abc4a88383df3a913ca466e8 (patch)
treeabf630c8372e7c81407172ad31190fa8a617a8ed /kernel/xpp/card_pri.c
parent823cf303caf13cc6e4fd2c2173804f0990b29532 (diff)
xpp r5723: Includes, among others:
* New firmware protocol version: 3.0 . * New numbers for the device types: (e.g. in card_init* scripts) - FXS: 1 (was: 3) - FXO: 2 (was: 4) - BRI: 3 (was: 6 for TE, 7 for NT) - PRI: 4 (was: 9) * Init scripts of FXS and FXO modules are now written in Perl as well (be sure to have File::Basename, e.g: perl-modules in Debian). * calibrate_slics merged into init_card_1_30 . * Module parameter print_dbg replaced with debug . Same meaning. * init_fxo_modes removed: content moved into init_card_2_30, verified at build time. * Code tested with sparse. Most warnings were fixed. * Set ZT_SIG_DACS for the bchans in the PRI and BRI modules to not get ignored by ztscan. * Handle null config_desc we get from some crazy USB controllers. * genzaptelconf: Fix reporting of empty slots in list mode. * xpp_blink can now blink a single analog port. * "slics" has been renamed "chipregs". * Fixed a small typo in fpga_load(8). * Fixed bashism in xpp_fxloader. Merged revisions 4264 via svnmerge from http://svn.digium.com/svn/zaptel/branches/1.2 git-svn-id: http://svn.digium.com/svn/zaptel/branches/1.4@4266 5390a7c7-147a-4af0-8ec9-7488f05a26cb
Diffstat (limited to 'kernel/xpp/card_pri.c')
-rw-r--r--kernel/xpp/card_pri.c464
1 files changed, 130 insertions, 334 deletions
diff --git a/kernel/xpp/card_pri.c b/kernel/xpp/card_pri.c
index 2187bb7..335b933 100644
--- a/kernel/xpp/card_pri.c
+++ b/kernel/xpp/card_pri.c
@@ -36,8 +36,8 @@
static const char rcsid[] = "$Id$";
-DEF_PARM(int, print_dbg, 0, 0644, "Print DBG statements"); /* must be before zap_debug.h */
-DEF_PARM(uint, poll_interval, 500, 0644, "Poll channel state interval in milliseconds (0 - disable)");
+static DEF_PARM(int, debug, 0, 0644, "Print DBG statements"); /* must be before zap_debug.h */
+static DEF_PARM(uint, poll_interval, 500, 0644, "Poll channel state interval in milliseconds (0 - disable)");
#define PRI_LINES_BITMASK BITMASK(31)
#define PRI_DCHAN_SIGCAP ( \
@@ -50,11 +50,13 @@ DEF_PARM(uint, poll_interval, 500, 0644, "Poll channel state interval in millise
ZT_SIG_FXOGS | \
ZT_SIG_FXOKS | \
ZT_SIG_CAS | \
+ ZT_SIG_DACS | \
ZT_SIG_SF \
)
-#define PRI_BCHAN_SIGCAP ZT_SIG_CLEAR
+#define PRI_BCHAN_SIGCAP (ZT_SIG_CLEAR | ZT_SIG_DACS)
#define MAX_SLAVES 4 /* we have MUX of 4 clocks */
+#define PRI_PORT(xpd) ((xpd)->addr.subunit)
/*---------------- PRI Protocol Commands ----------------------------------*/
@@ -62,8 +64,6 @@ static bool pri_packet_is_valid(xpacket_t *pack);
static void pri_packet_dump(const char *msg, xpacket_t *pack);
static int proc_pri_info_read(char *page, char **start, off_t off, int count, int *eof, void *data);
static int proc_pri_info_write(struct file *file, const char __user *buffer, unsigned long count, void *data);
-static int proc_xpd_register_read(char *page, char **start, off_t off, int count, int *eof, void *data);
-static int proc_xpd_register_write(struct file *file, const char __user *buffer, unsigned long count, void *data);
static int pri_startup(struct zt_span *span);
static int pri_shutdown(struct zt_span *span);
static int pri_lineconfig(xpd_t *xpd, int lineconfig);
@@ -71,8 +71,6 @@ static int pri_lineconfig(xpd_t *xpd, int lineconfig);
#define PROC_REGISTER_FNAME "slics"
#define PROC_PRI_INFO_FNAME "pri_info"
-#define VALID_CHIPSEL(x) ((x) == 0)
-
enum pri_protocol {
PRI_PROTO_0 = 0,
PRI_PROTO_E1 = 1,
@@ -246,15 +244,12 @@ struct pri_leds {
struct PRI_priv_data {
bool is_nt;
bool clock_source;
- struct proc_dir_entry *regfile;
struct proc_dir_entry *pri_info;
enum pri_protocol pri_protocol;
int deflaw;
unsigned int dchan_num;
bool initialized;
bool local_loopback;
- reg_cmd_t requested_reply;
- reg_cmd_t last_reply;
uint poll_noreplies;
uint layer1_replies;
byte reg_frs0;
@@ -286,20 +281,21 @@ static /* 0x33 */ DECLARE_CMD(PRI, SET_LED, enum pri_led_selectors led_sel, enum
static int query_subunit(xpd_t *xpd, byte regnum)
{
-#if 0
- XPD_DBG(GENERAL, xpd, "(%d%d): REG=0x%02X\n",
+ XPD_DBG(REGS, xpd, "(%d%d): REG=0x%02X\n",
xpd->addr.unit, xpd->addr.subunit,
regnum);
-#endif
return xpp_register_request(
xpd->xbus, xpd,
- 0, /* chipsel */
- 0, /* writing */
- 1, /* do_subreg */
+ PRI_PORT(xpd), /* portno */
+ 0, /* writing */
regnum,
- xpd->addr.subunit, /* subreg */
- 0, /* data_L */
- 0); /* data_H */
+ 0, /* do_subreg */
+ 0, /* subreg */
+ 0, /* data_L */
+ 0, /* do_datah */
+ 0, /* data_H */
+ 0 /* should_reply */
+ );
}
@@ -310,13 +306,16 @@ static int write_subunit(xpd_t *xpd, byte regnum, byte val)
regnum, val);
return xpp_register_request(
xpd->xbus, xpd,
- 0, /* chipsel */
- 1, /* writing */
- 1, /* do_subreg */
+ PRI_PORT(xpd), /* portno */
+ 1, /* writing */
regnum,
- xpd->addr.subunit, /* subreg */
- val, /* data_L */
- 0); /* data_H */
+ 0, /* do_subreg */
+ 0, /* subreg */
+ val, /* data_L */
+ 0, /* do_datah */
+ 0, /* data_H */
+ 0 /* should_reply */
+ );
}
static int pri_write_reg(xpd_t *xpd, int regnum, byte val)
@@ -326,35 +325,34 @@ static int pri_write_reg(xpd_t *xpd, int regnum, byte val)
regnum, val);
return xpp_register_request(
xpd->xbus, xpd,
- 0, /* chipsel */
- 1, /* writing */
- 0, /* do_subreg */
+ PRI_PORT(xpd), /* portno */
+ 1, /* writing */
regnum,
- 0, /* subreg */
- val, /* data_L */
- 0); /* data_H */
+ 0, /* do_subreg */
+ 0, /* subreg */
+ val, /* data_L */
+ 0, /* do_datah */
+ 0, /* data_H */
+ 0 /* should_reply */
+ );
}
-static xpd_t *PRI_card_new(xbus_t *xbus, int unit, int subunit, const xproto_table_t *proto_table, byte subtype, byte revision)
+static void pri_proc_remove(xbus_t *xbus, xpd_t *xpd)
{
- xpd_t *xpd = NULL;
struct PRI_priv_data *priv;
- int channels = min(31, CHANNELS_PERXPD); /* worst case */
- XBUS_DBG(GENERAL, xbus, "\n");
- xpd = xpd_alloc(sizeof(struct PRI_priv_data), proto_table, channels);
- if(!xpd)
- return NULL;
+ BUG_ON(!xpd);
priv = xpd->priv;
- xpd->revision = revision;
- priv->pri_protocol = PRI_PROTO_0; /* Default, changes in set_pri_proto() */
- priv->deflaw = ZT_LAW_DEFAULT; /* Default, changes in set_pri_proto() */
- xpd->type_name =
- type_name(priv->pri_protocol, 0); /* Default, changes in set_nt() */
- return xpd;
+ XPD_DBG(PROC, xpd, "\n");
+#ifdef CONFIG_PROC_FS
+ if(priv->pri_info) {
+ XPD_DBG(PROC, xpd, "Removing xpd PRI_INFO file\n");
+ remove_proc_entry(PROC_PRI_INFO_FNAME, xpd->proc_xpd_dir);
+ }
+#endif
}
-static void clean_proc(xbus_t *xbus, xpd_t *xpd)
+static int pri_proc_create(xbus_t *xbus, xpd_t *xpd)
{
struct PRI_priv_data *priv;
@@ -362,16 +360,21 @@ static void clean_proc(xbus_t *xbus, xpd_t *xpd)
priv = xpd->priv;
XPD_DBG(PROC, xpd, "\n");
#ifdef CONFIG_PROC_FS
- if(priv->regfile) {
- XPD_DBG(PROC, xpd, "Removing registers file\n");
- priv->regfile->data = NULL;
- remove_proc_entry(PROC_REGISTER_FNAME, xpd->proc_xpd_dir);
- }
- if(priv->pri_info) {
- XPD_DBG(PROC, xpd, "Removing xpd PRI_INFO file\n");
- remove_proc_entry(PROC_PRI_INFO_FNAME, xpd->proc_xpd_dir);
+ XPD_DBG(PROC, xpd, "Creating PRI_INFO file\n");
+ priv->pri_info = create_proc_entry(PROC_PRI_INFO_FNAME, 0644, xpd->proc_xpd_dir);
+ if(!priv->pri_info) {
+ XPD_ERR(xpd, "Failed to create proc '%s'\n", PROC_PRI_INFO_FNAME);
+ goto err;
}
+ priv->pri_info->owner = THIS_MODULE;
+ priv->pri_info->write_proc = proc_pri_info_write;
+ priv->pri_info->read_proc = proc_pri_info_read;
+ priv->pri_info->data = xpd;
#endif
+ return 0;
+err:
+ pri_proc_remove(xbus, xpd);
+ return -EINVAL;
}
static bool valid_pri_modes(const xpd_t *xpd)
@@ -588,10 +591,10 @@ static int set_master_mode(const char *msg, xpd_t *xpd)
lim0 &= ~REG_LIM0_MAS;
if(priv->pri_protocol == PRI_PROTO_E1)
{
- lim0 |= REG_LIM0_RTRS; /* Receive termination: Integrated resistor is switched on (100 Ohm || 300 Ohm = 75 Ohm) */
- xsp |= REG_XSP_E_EBP | REG_XSP_E_AXS | REG_XSP_E_XSIF;
- } else if(priv->pri_protocol == PRI_PROTO_T1) {
lim0 &= ~REG_LIM0_RTRS; /* Receive termination: Integrated resistor is switched off (100 Ohm, no internal 300 Ohm) */;
+ xsp |= REG_XSP_E_EBP | REG_XSP_E_AXS | REG_XSP_E_XSIF;
+ } else if(priv->pri_protocol == PRI_PROTO_T1) {
+ lim0 |= REG_LIM0_RTRS; /* Receive termination: Integrated resistor is switched on (100 Ohm || 300 Ohm = 75 Ohm) */
xsp |= REG_FMR5_T_XTM;
}
XPD_DBG(SIGNAL, xpd, "%s(%s): %s\n", __FUNCTION__, msg, (is_master_mode) ? "MASTER" : "SLAVE");
@@ -680,7 +683,7 @@ static int pri_lineconfig(xpd_t *xpd, int lineconfig)
const char *crcstr = "";
byte fmr0 = 0; /* Dummy initilizations to */
byte fmr2 = 0; /* silense false gcc warnings */
- byte fmr4 = 0x0C;
+ byte fmr4 = 0; /* Dummy initilizations to */
unsigned int bad_bits;
int i;
@@ -716,11 +719,14 @@ static int pri_lineconfig(xpd_t *xpd, int lineconfig)
}
if(bad_bits)
goto bad_lineconfig;
- if(priv->pri_protocol == PRI_PROTO_E1)
+ if(priv->pri_protocol == PRI_PROTO_E1) {
fmr2 = REG_FMR2_E_AXRA | REG_FMR2_E_ALMF; /* 0x03 */
- else if(priv->pri_protocol == PRI_PROTO_T1)
+ fmr4 = 0x9F; /* E1.XSW: All spare bits = 1*/
+ } else if(priv->pri_protocol == PRI_PROTO_T1) {
fmr2 = REG_FMR2_T_SSP | REG_FMR2_T_AXRA; /* 0x22 */
- else if(priv->pri_protocol == PRI_PROTO_J1) {
+ fmr4 = 0x0C;
+ } else if(priv->pri_protocol == PRI_PROTO_J1) {
+ fmr4 = 0x1C;
XPD_ERR(xpd, "J1 unsupported yet\n");
return -ENOSYS;
}
@@ -819,49 +825,47 @@ static int pri_chanconfig(struct zt_chan *chan, int sigtype)
return 0;
}
-static int PRI_card_init(xbus_t *xbus, xpd_t *xpd)
+static xpd_t *PRI_card_new(xbus_t *xbus, int unit, int subunit, const xproto_table_t *proto_table, byte subtype, int subunits, bool to_phone)
{
+ xpd_t *xpd = NULL;
struct PRI_priv_data *priv;
+ int channels = min(31, CHANNELS_PERXPD); /* worst case */
int ret = 0;
- xproto_table_t *proto_table;
- BUG_ON(!xpd);
- XPD_DBG(GENERAL, xpd, "\n");
- xpd->type = XPD_TYPE_PRI;
- proto_table = &PROTO_TABLE(PRI);
+ XBUS_DBG(GENERAL, xbus, "\n");
+ xpd = xpd_alloc(sizeof(struct PRI_priv_data), proto_table, channels);
+ if(!xpd)
+ return NULL;
priv = xpd->priv;
- xpd->xops = &proto_table->xops;
-#ifdef CONFIG_PROC_FS
- XPD_DBG(PROC, xpd, "Creating PRI_INFO file\n");
- priv->pri_info = create_proc_entry(PROC_PRI_INFO_FNAME, 0644, xpd->proc_xpd_dir);
- if(!priv->pri_info) {
- XPD_ERR(xpd, "Failed to create proc '%s'\n", PROC_PRI_INFO_FNAME);
- ret = -ENOENT;
+ priv->pri_protocol = PRI_PROTO_0; /* Default, changes in set_pri_proto() */
+ priv->deflaw = ZT_LAW_DEFAULT; /* Default, changes in set_pri_proto() */
+ xpd->type_name =
+ type_name(priv->pri_protocol, 0); /* Default, changes in set_nt() */
+ if(xpd_common_init(xbus, xpd, unit, subunit, subtype, subunits) < 0)
goto err;
- }
- priv->pri_info->owner = THIS_MODULE;
- priv->pri_info->write_proc = proc_pri_info_write;
- priv->pri_info->read_proc = proc_pri_info_read;
- priv->pri_info->data = xpd;
- XPD_DBG(PROC, xpd, "Creating registers file\n");
- priv->regfile = create_proc_entry(PROC_REGISTER_FNAME, 0644, xpd->proc_xpd_dir);
- if(!priv->regfile) {
- XPD_ERR(xpd, "Failed to create proc file '%s'\n", PROC_REGISTER_FNAME);
- ret = -ENOENT;
+ if(pri_proc_create(xbus, xpd) < 0)
goto err;
- }
- priv->regfile->owner = THIS_MODULE;
- priv->regfile->write_proc = proc_xpd_register_write;
- priv->regfile->read_proc = proc_xpd_register_read;
- priv->regfile->data = xpd;
-#endif
/* Assume E1, changes later from user space */
ret = set_pri_proto(xpd, PRI_PROTO_E1);
if(ret < 0)
goto err;
- ret = run_initialize_registers(xpd);
- if(ret < 0)
- goto err;
+ return xpd;
+err:
+ xpd_free(xpd);
+ return NULL;
+}
+
+static int PRI_card_init(xbus_t *xbus, xpd_t *xpd)
+{
+ struct PRI_priv_data *priv;
+ int ret = 0;
+ xproto_table_t *proto_table;
+
+ BUG_ON(!xpd);
+ XPD_DBG(GENERAL, xpd, "\n");
+ xpd->type = XPD_TYPE_PRI;
+ proto_table = &PROTO_TABLE(PRI);
+ priv = xpd->priv;
/*
* initialization script should have set correct
* operating modes.
@@ -870,7 +874,6 @@ static int PRI_card_init(xbus_t *xbus, xpd_t *xpd)
XPD_NOTICE(xpd, "PRI protocol not set\n");
goto err;
}
- XPD_DBG(GENERAL, xpd, "done\n");
for(ret = 0; ret < NUM_LEDS; ret++) {
DO_LED(xpd, ret, PRI_LED_ON);
msleep(20);
@@ -879,7 +882,7 @@ static int PRI_card_init(xbus_t *xbus, xpd_t *xpd)
priv->initialized = 1;
return 0;
err:
- clean_proc(xbus, xpd);
+ pri_proc_remove(xbus, xpd);
XPD_ERR(xpd, "Failed initializing registers (%d)\n", ret);
return ret;
}
@@ -891,7 +894,7 @@ static int PRI_card_remove(xbus_t *xbus, xpd_t *xpd)
BUG_ON(!xpd);
priv = xpd->priv;
XPD_DBG(GENERAL, xpd, "\n");
- clean_proc(xbus, xpd);
+ pri_proc_remove(xbus, xpd);
return 0;
}
@@ -1275,7 +1278,7 @@ static void PRI_card_pcm_tospan(xbus_t *xbus, xpd_t *xpd, xpacket_t *pack)
}
if(logical_chan == PRI_DCHAN_IDX(priv)) {
if(priv->dchan_rx_sample != pcm[0]) {
- if(print_dbg & DBG_PCM) {
+ if(debug & DBG_PCM) {
XPD_INFO(xpd, "RX-D-Chan: prev=0x%X now=0x%X\n",
priv->dchan_rx_sample, pcm[0]);
dump_packet("RX-D-Chan", pack, 1);
@@ -1307,19 +1310,7 @@ static /* 0x0F */ HOSTCMD(PRI, XPD_STATE, bool on)
return 0;
}
-static /* 0x0F */ HOSTCMD(PRI, RING, lineno_t chan, bool on)
-{
- XPD_ERR(xpd, "%s: Unsupported\n", __FUNCTION__);
- return -ENOSYS;
-}
-
-static /* 0x0F */ HOSTCMD(PRI, RELAY_OUT, byte which, bool on)
-{
- XPD_ERR(xpd, "%s: Unsupported\n", __FUNCTION__);
- return -ENOSYS;
-}
-
-/* 0x33 */ HOSTCMD(PRI, SET_LED, enum pri_led_selectors led_sel, enum pri_led_state to_led_state)
+static /* 0x33 */ HOSTCMD(PRI, SET_LED, enum pri_led_selectors led_sel, enum pri_led_state to_led_state)
{
int ret = 0;
xframe_t *xframe;
@@ -1336,6 +1327,7 @@ static /* 0x0F */ HOSTCMD(PRI, RELAY_OUT, byte which, bool on)
pri_leds = &RPACKET_FIELD(pack, PRI, SET_LED, pri_leds);
pri_leds->state = to_led_state;
pri_leds->led_sel = led_sel;
+ pri_leds->reserved = 0;
XPACKET_LEN(pack) = RPACKET_SIZE(PRI, SET_LED);
ret = send_cmd_frame(xbus, xframe);
priv->ledstate[led_sel] = to_led_state;
@@ -1343,7 +1335,7 @@ static /* 0x0F */ HOSTCMD(PRI, RELAY_OUT, byte which, bool on)
}
/*---------------- PRI: Astribank Reply Handlers --------------------------*/
-static void layer1_state(xpd_t *xpd, byte subunit, byte data_low)
+static void layer1_state(xpd_t *xpd, byte data_low)
{
struct PRI_priv_data *priv;
int alarms = 0;
@@ -1351,10 +1343,6 @@ static void layer1_state(xpd_t *xpd, byte subunit, byte data_low)
BUG_ON(!xpd);
priv = xpd->priv;
BUG_ON(!priv);
- if(xpd->addr.subunit != subunit) {
- XPD_NOTICE(xpd, "layer1_state got wrong subunit=%d. Ignored.\n", subunit);
- return;
- }
priv->poll_noreplies = 0;
if(data_low & REG_FRS0_LOS)
alarms |= ZT_ALARM_RED;
@@ -1390,36 +1378,46 @@ static void layer1_state(xpd_t *xpd, byte subunit, byte data_low)
}
priv->reg_frs0 = data_low;
priv->layer1_replies++;
- XPD_DBG(REGS, xpd, "subunit=%d data_low=0x%02X\n", subunit, data_low);
+ XPD_DBG(REGS, xpd, "subunit=%d data_low=0x%02X\n", xpd->addr.subunit, data_low);
}
static int PRI_card_register_reply(xbus_t *xbus, xpd_t *xpd, reg_cmd_t *info)
{
unsigned long flags;
struct PRI_priv_data *priv;
-
+ struct xpd_addr addr;
+ xpd_t *orig_xpd;
+
+ /* Map UNIT + PORTNUM to XPD */
+ orig_xpd = xpd;
+ addr.unit = orig_xpd->addr.unit;
+ addr.subunit = info->portnum;
+ xpd = xpd_byaddr(xbus, addr.unit, addr.subunit);
+ if(!xpd) {
+ static int rate_limit;
+
+ if((rate_limit++ % 1003) < 5)
+ notify_bad_xpd(__FUNCTION__, xbus, addr , orig_xpd->xpdname);
+ return -EPROTO;
+ }
spin_lock_irqsave(&xpd->lock, flags);
priv = xpd->priv;
BUG_ON(!priv);
-#if 1
- if(print_dbg)
- dump_reg_cmd("PRI", info, 0);
-#endif
- if(info->multibyte) {
+ if(info->is_multibyte) {
XPD_NOTICE(xpd, "Got Multibyte: %d bytes, eoframe: %d\n",
info->bytes, info->eoframe);
goto end;
}
- if(REG_FIELD(info, regnum) == REG_FRS0 && REG_FIELD(info, do_subreg))
- layer1_state(xpd, REG_FIELD(info, subreg), REG_FIELD(info, data_low));
- if(REG_FIELD(info, regnum) == REG_FRS1 && REG_FIELD(info, do_subreg))
+ if(REG_FIELD(info, regnum) == REG_FRS0 && !REG_FIELD(info, do_subreg))
+ layer1_state(xpd, REG_FIELD(info, data_low));
+ if(REG_FIELD(info, regnum) == REG_FRS1 && !REG_FIELD(info, do_subreg))
priv->reg_frs1 = REG_FIELD(info, data_low);
/* Update /proc info only if reply relate to the last slic read request */
if(
- REG_FIELD(&priv->requested_reply, regnum) == REG_FIELD(info, regnum) &&
- REG_FIELD(&priv->requested_reply, do_subreg) == REG_FIELD(info, do_subreg) &&
- REG_FIELD(&priv->requested_reply, subreg) == REG_FIELD(info, subreg)) {
- priv->last_reply = *info;
+ REG_FIELD(&xpd->requested_reply, regnum) == REG_FIELD(info, regnum) &&
+ REG_FIELD(&xpd->requested_reply, do_subreg) == REG_FIELD(info, do_subreg) &&
+ REG_FIELD(&xpd->requested_reply, subreg) == REG_FIELD(info, subreg)) {
+ xpd->last_reply = *info;
}
end:
@@ -1432,7 +1430,8 @@ static xproto_table_t PROTO_TABLE(PRI) = {
.entries = {
/* Table Card Opcode */
},
- .name = "PRI_xx", /* xpd->type_name is set in set_nt() */
+ .name = "PRI", /* protocol name */
+ .ports_per_subunit = 1,
.type = XPD_TYPE_PRI,
.xops = {
.card_new = PRI_card_new,
@@ -1448,8 +1447,6 @@ static xproto_table_t PROTO_TABLE(PRI) = {
.card_close = PRI_card_close,
.card_register_reply = PRI_card_register_reply,
- .RING = XPROTO_CALLER(PRI, RING),
- .RELAY_OUT = XPROTO_CALLER(PRI, RELAY_OUT),
.XPD_STATE = XPROTO_CALLER(PRI, XPD_STATE),
},
.packet_is_valid = pri_packet_is_valid,
@@ -1610,208 +1607,7 @@ static int proc_pri_info_read(char *page, char **start, off_t off, int count, in
return len;
}
-/*
- *
- * Direct/Indirect
- * |
- * | Reg#
- * | |
- * | | Data (only in Write)
- * | | |
- * | | +-+-+
- * v v v v
- * FF WD 06 01 05
- * ^ ^
- * | |
- * | Write/Read
- * |
- * Chan#
- *
- */
-static int handle_register_command(xpd_t *xpd, char *cmdline)
-{
- unsigned chipsel;
- unsigned data = 0;
- unsigned xdata1 = 0;
- unsigned xdata2 = 0;
- char op; /* [W]rite, [R]ead */
- char reg_type; /* [D]irect, [S]ubregister */
- int reg_num;
- int subreg;
- int elements;
- bool writing;
- char *p;
- reg_cmd_t regcmd;
- xbus_t *xbus;
- int ret = -EINVAL;
- struct PRI_priv_data *priv;
- byte buf[MAX_PROC_WRITE];
-
- BUG_ON(!xpd);
- xbus = xpd->xbus;
- priv = xpd->priv;
- BUG_ON(!priv);
- if((p = strchr(cmdline, '#')) != NULL) /* Truncate comments */
- *p = '\0';
- if((p = strchr(cmdline, ';')) != NULL) /* Truncate comments */
- *p = '\0';
- for(p = cmdline; *p && (*p == ' ' || *p == '\t'); p++) /* Trim leading whitespace */
- ;
- if(*p == '\0')
- return 0;
- if(!XBUS_GET(xbus)) {
- XBUS_DBG(GENERAL, xbus, "Dropped packet. Is shutting down.\n");
- return -EBUSY;
- }
- memset(buf, 0, MAX_PROC_WRITE);
- elements = sscanf(cmdline, "%d %c%c %x %x %x %x %x",
- &chipsel,
- &op, &reg_type, &reg_num,
- &subreg,
- &data, &xdata1, &xdata2);
- XPD_DBG(PROC, xpd, "'%s': %d %c%c %02X %02X %02X\n", cmdline, chipsel, op, reg_type, reg_num, subreg, data);
- if(elements < 3) { // At least: chipsel, op, reg_type, reg_num
- ERR("Not enough arguments: (%d args) '%s'\n", elements, cmdline);
- goto out;
- }
- if(!VALID_CHIPSEL(chipsel)) {
- ERR("Bad chip select number: %d\n", chipsel);
- goto out;
- }
- REG_FIELD(&regcmd, chipsel) = chipsel;
- switch(op) {
- case 'W':
- writing = 1;
- break;
- case 'R':
- writing = 0;
- break;
- default:
- ERR("Unkown operation type '%c'\n", op);
- goto out;
- }
- if(
- (op == 'W' && reg_type == 'D' && elements != 5) ||
- (op == 'W' && reg_type == 'S' && elements != 6) ||
- (op == 'R' && reg_type == 'D' && elements != 4) ||
- (op == 'R' && reg_type == 'S' && elements != 5)
- ) {
- ERR("Bad number of elements: '%s' (%d elements): %d %c%c %02X %02X %02X\n",
- cmdline, elements,
- chipsel, op, reg_type, reg_num, subreg, data);
- goto out;
- }
- switch(reg_type) {
- case 'S':
- REG_FIELD(&regcmd, do_subreg) = 1;
- REG_FIELD(&regcmd, regnum) = reg_num;
- REG_FIELD(&regcmd, subreg) = subreg;
- REG_FIELD(&regcmd, data_low) = data;
- XPD_DBG(PROC, xpd, "SUBREG\n");
- break;
- case 'D':
- REG_FIELD(&regcmd, do_subreg) = 0;
- REG_FIELD(&regcmd, regnum) = reg_num;
- REG_FIELD(&regcmd, subreg) = 0;
- REG_FIELD(&regcmd, data_low) = subreg;
- XPD_DBG(PROC, xpd, "DIRECT\n");
- break;
- default:
- ERR("Unkown register type '%c'\n", reg_type);
- goto out;
- }
- regcmd.bytes = sizeof(regcmd) - 1;
- REG_FIELD(&regcmd, read_request) = writing;
- REG_FIELD(&regcmd, data_high) = 0;
- priv->requested_reply = regcmd;
- if(print_dbg)
- dump_reg_cmd("PRI", &regcmd, 1);
- ret = xpp_register_request(xpd->xbus, xpd,
- REG_FIELD(&regcmd, chipsel),
- writing,
- REG_FIELD(&regcmd, do_subreg),
- REG_FIELD(&regcmd, regnum),
- REG_FIELD(&regcmd, subreg),
- REG_FIELD(&regcmd, data_low),
- REG_FIELD(&regcmd, data_high));
-out:
- XBUS_PUT(xbus);
- return ret;
-}
-
-static int proc_xpd_register_write(struct file *file, const char __user *buffer, unsigned long count, void *data)
-{
- xpd_t *xpd = data;
- char buf[MAX_PROC_WRITE];
- char *p;
- int i;
- int ret;
-
- if(!xpd)
- return -ENODEV;
- for(i = 0; i < count; /* noop */) {
- for(p = buf; p < buf + MAX_PROC_WRITE; p++) { /* read a line */
- if(i >= count)
- break;
- if(get_user(*p, buffer + i))
- return -EFAULT;
- i++;
- if(*p == '\n' || *p == '\r') /* whatever */
- break;
- }
- if(p >= buf + MAX_PROC_WRITE)
- return -E2BIG;
- *p = '\0';
- ret = handle_register_command(xpd, buf);
- if(ret < 0)
- return ret;
- msleep(1);
- }
- return count;
-}
-
-
-static int proc_xpd_register_read(char *page, char **start, off_t off, int count, int *eof, void *data)
-{
- int len = 0;
- unsigned long flags;
- xpd_t *xpd = data;
- reg_cmd_t *info;
- struct PRI_priv_data *priv;
-
- if(!xpd)
- return -ENODEV;
- priv = xpd->priv;
- BUG_ON(!priv);
- spin_lock_irqsave(&xpd->lock, flags);
- info = &priv->last_reply;
- len += sprintf(page + len, "# Writing bad data into this file may damage your hardware!\n");
- len += sprintf(page + len, "# Consult firmware docs first\n");
- len += sprintf(page + len, "#\n");
- if(REG_FIELD(info, do_subreg)) {
- len += sprintf(page + len, "#CH\tOP\tReg.\tSub\tDL\n");
- len += sprintf(page + len, "%2d\tRS\t%02X\t%02X\t%02X\n",
- REG_FIELD(info, chipsel),
- REG_FIELD(info, regnum), REG_FIELD(info, subreg), REG_FIELD(info, data_low));
- } else {
- len += sprintf(page + len, "#CH\tOP\tReg.\tDL\n");
- len += sprintf(page + len, "%2d\tRD\t%02X\t%02X\n",
- REG_FIELD(info, chipsel),
- REG_FIELD(info, regnum), REG_FIELD(info, data_low));
- }
- spin_unlock_irqrestore(&xpd->lock, flags);
- if (len <= off+count)
- *eof = 1;
- *start = page + off;
- len -= off;
- if (len > count)
- len = count;
- if (len < 0)
- len = 0;
- return len;
-}
-
-int __init card_pri_startup(void)
+static int __init card_pri_startup(void)
{
DBG(GENERAL, "\n");
@@ -1820,7 +1616,7 @@ int __init card_pri_startup(void)
return 0;
}
-void __exit card_pri_cleanup(void)
+static void __exit card_pri_cleanup(void)
{
DBG(GENERAL, "\n");
xproto_unregister(&PROTO_TABLE(PRI));