summaryrefslogtreecommitdiff
path: root/drivers/isdn
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/isdn')
-rw-r--r--drivers/isdn/capi/capidrv.c24
-rw-r--r--drivers/isdn/capi/capiutil.c42
-rw-r--r--drivers/isdn/capi/kcapi.c4
-rw-r--r--drivers/isdn/gigaset/bas-gigaset.c2
-rw-r--r--drivers/isdn/gigaset/capi.c155
-rw-r--r--drivers/isdn/gigaset/ev-layer.c119
-rw-r--r--drivers/isdn/gigaset/usb-gigaset.c18
-rw-r--r--drivers/isdn/i4l/isdn_tty.c5
-rw-r--r--drivers/isdn/mISDN/dsp_cmx.c109
9 files changed, 324 insertions, 154 deletions
diff --git a/drivers/isdn/capi/capidrv.c b/drivers/isdn/capi/capidrv.c
index fd6d28f3fc36..1cc6ca8bfbda 100644
--- a/drivers/isdn/capi/capidrv.c
+++ b/drivers/isdn/capi/capidrv.c
@@ -506,7 +506,10 @@ static void send_message(capidrv_contr *card, _cmsg *cmsg)
struct sk_buff *skb;
size_t len;
- capi_cmsg2message(cmsg, cmsg->buf);
+ if (capi_cmsg2message(cmsg, cmsg->buf)) {
+ printk(KERN_ERR "capidrv::send_message: parser failure\n");
+ return;
+ }
len = CAPIMSG_LEN(cmsg->buf);
skb = alloc_skb(len, GFP_ATOMIC);
if (!skb) {
@@ -1578,7 +1581,12 @@ static _cmsg s_cmsg;
static void capidrv_recv_message(struct capi20_appl *ap, struct sk_buff *skb)
{
- capi_message2cmsg(&s_cmsg, skb->data);
+ if (capi_message2cmsg(&s_cmsg, skb->data)) {
+ printk(KERN_ERR "capidrv: applid=%d: received invalid message\n",
+ ap->applid);
+ kfree_skb(skb);
+ return;
+ }
if (debugmode > 3) {
_cdebbuf *cdb = capi_cmsg2str(&s_cmsg);
@@ -1903,7 +1911,11 @@ static int capidrv_command(isdn_ctrl *c, capidrv_contr *card)
NULL, /* Useruserdata */
NULL /* Facilitydataarray */
);
- capi_cmsg2message(&cmdcmsg, cmdcmsg.buf);
+ if (capi_cmsg2message(&cmdcmsg, cmdcmsg.buf)) {
+ printk(KERN_ERR "capidrv-%d: capidrv_command: parser failure\n",
+ card->contrnr);
+ return -EINVAL;
+ }
plci_change_state(card, bchan->plcip, EV_PLCI_CONNECT_RESP);
send_message(card, &cmdcmsg);
return 0;
@@ -2090,7 +2102,11 @@ static int if_sendbuf(int id, int channel, int doack, struct sk_buff *skb)
if (capidrv_add_ack(nccip, datahandle, doack ? (int)skb->len : -1) < 0)
return 0;
- capi_cmsg2message(&sendcmsg, sendcmsg.buf);
+ if (capi_cmsg2message(&sendcmsg, sendcmsg.buf)) {
+ printk(KERN_ERR "capidrv-%d: if_sendbuf: parser failure\n",
+ card->contrnr);
+ return -EINVAL;
+ }
msglen = CAPIMSG_LEN(sendcmsg.buf);
if (skb_headroom(skb) < msglen) {
struct sk_buff *nskb = skb_realloc_headroom(skb, msglen);
diff --git a/drivers/isdn/capi/capiutil.c b/drivers/isdn/capi/capiutil.c
index 6e797e502cfa..36c1b37cea0a 100644
--- a/drivers/isdn/capi/capiutil.c
+++ b/drivers/isdn/capi/capiutil.c
@@ -205,14 +205,26 @@ static unsigned command_2_index(unsigned c, unsigned sc)
{
if (c & 0x80)
c = 0x9 + (c & 0x0f);
- else if (c <= 0x0f);
else if (c == 0x41)
c = 0x9 + 0x1;
- else if (c == 0xff)
+ if (c > 0x18)
c = 0x00;
return (sc & 3) * (0x9 + 0x9) + c;
}
+/**
+ * capi_cmd2par() - find parameter string for CAPI 2.0 command/subcommand
+ * @cmd: command number
+ * @subcmd: subcommand number
+ *
+ * Return value: static string, NULL if command/subcommand unknown
+ */
+
+static unsigned char *capi_cmd2par(u8 cmd, u8 subcmd)
+{
+ return cpars[command_2_index(cmd, subcmd)];
+}
+
/*-------------------------------------------------------*/
#define TYP (cdef[cmsg->par[cmsg->p]].typ)
#define OFF (((u8 *)cmsg) + cdef[cmsg->par[cmsg->p]].off)
@@ -305,7 +317,9 @@ unsigned capi_cmsg2message(_cmsg *cmsg, u8 *msg)
cmsg->m = msg;
cmsg->l = 8;
cmsg->p = 0;
- cmsg->par = cpars[command_2_index(cmsg->Command, cmsg->Subcommand)];
+ cmsg->par = capi_cmd2par(cmsg->Command, cmsg->Subcommand);
+ if (!cmsg->par)
+ return 1; /* invalid command/subcommand */
pars_2_message(cmsg);
@@ -378,7 +392,9 @@ unsigned capi_message2cmsg(_cmsg *cmsg, u8 *msg)
cmsg->p = 0;
byteTRcpy(cmsg->m + 4, &cmsg->Command);
byteTRcpy(cmsg->m + 5, &cmsg->Subcommand);
- cmsg->par = cpars[command_2_index(cmsg->Command, cmsg->Subcommand)];
+ cmsg->par = capi_cmd2par(cmsg->Command, cmsg->Subcommand);
+ if (!cmsg->par)
+ return 1; /* invalid command/subcommand */
message_2_pars(cmsg);
@@ -473,12 +489,17 @@ static char *mnames[] =
* @cmd: command number
* @subcmd: subcommand number
*
- * Return value: static string, NULL if command/subcommand unknown
+ * Return value: static string
*/
char *capi_cmd2str(u8 cmd, u8 subcmd)
{
- return mnames[command_2_index(cmd, subcmd)];
+ char *result;
+
+ result = mnames[command_2_index(cmd, subcmd)];
+ if (result == NULL)
+ result = "INVALID_COMMAND";
+ return result;
}
@@ -628,6 +649,9 @@ static _cdebbuf *printstruct(_cdebbuf *cdb, u8 *m)
static _cdebbuf *protocol_message_2_pars(_cdebbuf *cdb, _cmsg *cmsg, int level)
{
+ if (!cmsg->par)
+ return NULL; /* invalid command/subcommand */
+
for (; TYP != _CEND; cmsg->p++) {
int slen = 29 + 3 - level;
int i;
@@ -762,10 +786,10 @@ _cdebbuf *capi_message2str(u8 *msg)
cmsg->p = 0;
byteTRcpy(cmsg->m + 4, &cmsg->Command);
byteTRcpy(cmsg->m + 5, &cmsg->Subcommand);
- cmsg->par = cpars[command_2_index(cmsg->Command, cmsg->Subcommand)];
+ cmsg->par = capi_cmd2par(cmsg->Command, cmsg->Subcommand);
cdb = bufprint(cdb, "%-26s ID=%03d #0x%04x LEN=%04d\n",
- mnames[command_2_index(cmsg->Command, cmsg->Subcommand)],
+ capi_cmd2str(cmsg->Command, cmsg->Subcommand),
((unsigned short *) msg)[1],
((unsigned short *) msg)[3],
((unsigned short *) msg)[0]);
@@ -799,7 +823,7 @@ _cdebbuf *capi_cmsg2str(_cmsg *cmsg)
cmsg->l = 8;
cmsg->p = 0;
cdb = bufprint(cdb, "%s ID=%03d #0x%04x LEN=%04d\n",
- mnames[command_2_index(cmsg->Command, cmsg->Subcommand)],
+ capi_cmd2str(cmsg->Command, cmsg->Subcommand),
((u16 *) cmsg->m)[1],
((u16 *) cmsg->m)[3],
((u16 *) cmsg->m)[0]);
diff --git a/drivers/isdn/capi/kcapi.c b/drivers/isdn/capi/kcapi.c
index c123709acf82..823f6985b260 100644
--- a/drivers/isdn/capi/kcapi.c
+++ b/drivers/isdn/capi/kcapi.c
@@ -1184,7 +1184,7 @@ static int old_capi_manufacturer(unsigned int cmd, void __user *data)
* Return value: CAPI result code
*/
-int capi20_manufacturer(unsigned int cmd, void __user *data)
+int capi20_manufacturer(unsigned long cmd, void __user *data)
{
struct capi_ctr *ctr;
int retval;
@@ -1259,7 +1259,7 @@ int capi20_manufacturer(unsigned int cmd, void __user *data)
}
default:
- printk(KERN_ERR "kcapi: manufacturer command %d unknown.\n",
+ printk(KERN_ERR "kcapi: manufacturer command %lu unknown.\n",
cmd);
break;
diff --git a/drivers/isdn/gigaset/bas-gigaset.c b/drivers/isdn/gigaset/bas-gigaset.c
index b7ae0a0dd5b6..aecec6d32463 100644
--- a/drivers/isdn/gigaset/bas-gigaset.c
+++ b/drivers/isdn/gigaset/bas-gigaset.c
@@ -2365,7 +2365,7 @@ static int gigaset_probe(struct usb_interface *interface,
endpoint = &hostif->endpoint[0].desc;
usb_fill_int_urb(ucs->urb_int_in, udev,
usb_rcvintpipe(udev,
- (endpoint->bEndpointAddress) & 0x0f),
+ usb_endpoint_num(endpoint)),
ucs->int_in_buf, IP_MSGSIZE, read_int_callback, cs,
endpoint->bInterval);
rc = usb_submit_urb(ucs->urb_int_in, GFP_KERNEL);
diff --git a/drivers/isdn/gigaset/capi.c b/drivers/isdn/gigaset/capi.c
index 3286903a95d2..ccec7778cad2 100644
--- a/drivers/isdn/gigaset/capi.c
+++ b/drivers/isdn/gigaset/capi.c
@@ -250,6 +250,8 @@ static inline void dump_rawmsg(enum debuglevel level, const char *tag,
l -= 12;
if (l <= 0)
return;
+ if (l > 64)
+ l = 64; /* arbitrary limit */
dbgline = kmalloc(3 * l, GFP_ATOMIC);
if (!dbgline)
return;
@@ -645,7 +647,13 @@ int gigaset_isdn_icall(struct at_state_t *at_state)
__func__);
break;
}
- capi_cmsg2message(&iif->hcmsg, __skb_put(skb, msgsize));
+ if (capi_cmsg2message(&iif->hcmsg,
+ __skb_put(skb, msgsize))) {
+ dev_err(cs->dev, "%s: message parser failure\n",
+ __func__);
+ dev_kfree_skb_any(skb);
+ break;
+ }
dump_cmsg(DEBUG_CMD, __func__, &iif->hcmsg);
/* add to listeners on this B channel, update state */
@@ -691,7 +699,12 @@ static void send_disconnect_ind(struct bc_state *bcs,
dev_err(cs->dev, "%s: out of memory\n", __func__);
return;
}
- capi_cmsg2message(&iif->hcmsg, __skb_put(skb, CAPI_DISCONNECT_IND_LEN));
+ if (capi_cmsg2message(&iif->hcmsg,
+ __skb_put(skb, CAPI_DISCONNECT_IND_LEN))) {
+ dev_err(cs->dev, "%s: message parser failure\n", __func__);
+ dev_kfree_skb_any(skb);
+ return;
+ }
dump_cmsg(DEBUG_CMD, __func__, &iif->hcmsg);
capi_ctr_handle_message(&iif->ctr, ap->id, skb);
}
@@ -721,8 +734,12 @@ static void send_disconnect_b3_ind(struct bc_state *bcs,
dev_err(cs->dev, "%s: out of memory\n", __func__);
return;
}
- capi_cmsg2message(&iif->hcmsg,
- __skb_put(skb, CAPI_DISCONNECT_B3_IND_BASELEN));
+ if (capi_cmsg2message(&iif->hcmsg,
+ __skb_put(skb, CAPI_DISCONNECT_B3_IND_BASELEN))) {
+ dev_err(cs->dev, "%s: message parser failure\n", __func__);
+ dev_kfree_skb_any(skb);
+ return;
+ }
dump_cmsg(DEBUG_CMD, __func__, &iif->hcmsg);
capi_ctr_handle_message(&iif->ctr, ap->id, skb);
}
@@ -787,7 +804,11 @@ void gigaset_isdn_connD(struct bc_state *bcs)
dev_err(cs->dev, "%s: out of memory\n", __func__);
return;
}
- capi_cmsg2message(&iif->hcmsg, __skb_put(skb, msgsize));
+ if (capi_cmsg2message(&iif->hcmsg, __skb_put(skb, msgsize))) {
+ dev_err(cs->dev, "%s: message parser failure\n", __func__);
+ dev_kfree_skb_any(skb);
+ return;
+ }
dump_cmsg(DEBUG_CMD, __func__, &iif->hcmsg);
capi_ctr_handle_message(&iif->ctr, ap->id, skb);
}
@@ -887,7 +908,11 @@ void gigaset_isdn_connB(struct bc_state *bcs)
dev_err(cs->dev, "%s: out of memory\n", __func__);
return;
}
- capi_cmsg2message(&iif->hcmsg, __skb_put(skb, msgsize));
+ if (capi_cmsg2message(&iif->hcmsg, __skb_put(skb, msgsize))) {
+ dev_err(cs->dev, "%s: message parser failure\n", __func__);
+ dev_kfree_skb_any(skb);
+ return;
+ }
dump_cmsg(DEBUG_CMD, __func__, &iif->hcmsg);
capi_ctr_handle_message(&iif->ctr, ap->id, skb);
}
@@ -1094,13 +1119,19 @@ static void send_conf(struct gigaset_capi_ctr *iif,
struct sk_buff *skb,
u16 info)
{
+ struct cardstate *cs = iif->ctr.driverdata;
+
/*
* _CONF replies always only have NCCI and Info parameters
* so they'll fit into the _REQ message skb
*/
capi_cmsg_answer(&iif->acmsg);
iif->acmsg.Info = info;
- capi_cmsg2message(&iif->acmsg, skb->data);
+ if (capi_cmsg2message(&iif->acmsg, skb->data)) {
+ dev_err(cs->dev, "%s: message parser failure\n", __func__);
+ dev_kfree_skb_any(skb);
+ return;
+ }
__skb_trim(skb, CAPI_STDCONF_LEN);
dump_cmsg(DEBUG_CMD, __func__, &iif->acmsg);
capi_ctr_handle_message(&iif->ctr, ap->id, skb);
@@ -1122,7 +1153,11 @@ static void do_facility_req(struct gigaset_capi_ctr *iif,
static u8 confparam[10]; /* max. 9 octets + length byte */
/* decode message */
- capi_message2cmsg(cmsg, skb->data);
+ if (capi_message2cmsg(cmsg, skb->data)) {
+ dev_err(cs->dev, "%s: message parser failure\n", __func__);
+ dev_kfree_skb_any(skb);
+ return;
+ }
dump_cmsg(DEBUG_CMD, __func__, cmsg);
/*
@@ -1180,6 +1215,7 @@ static void do_facility_req(struct gigaset_capi_ctr *iif,
confparam[3] = 2; /* length */
capimsg_setu16(confparam, 4,
CapiSupplementaryServiceNotSupported);
+ break;
}
info = CapiSuccess;
confparam[3] = 2; /* length */
@@ -1220,6 +1256,7 @@ static void do_facility_req(struct gigaset_capi_ctr *iif,
}
/* send FACILITY_CONF with given Info and confirmation parameter */
+ dev_kfree_skb_any(skb);
capi_cmsg_answer(cmsg);
cmsg->Info = info;
cmsg->FacilityConfirmationParameter = confparam;
@@ -1229,7 +1266,11 @@ static void do_facility_req(struct gigaset_capi_ctr *iif,
dev_err(cs->dev, "%s: out of memory\n", __func__);
return;
}
- capi_cmsg2message(cmsg, __skb_put(cskb, msgsize));
+ if (capi_cmsg2message(cmsg, __skb_put(cskb, msgsize))) {
+ dev_err(cs->dev, "%s: message parser failure\n", __func__);
+ dev_kfree_skb_any(cskb);
+ return;
+ }
dump_cmsg(DEBUG_CMD, __func__, cmsg);
capi_ctr_handle_message(&iif->ctr, ap->id, cskb);
}
@@ -1243,8 +1284,14 @@ static void do_listen_req(struct gigaset_capi_ctr *iif,
struct gigaset_capi_appl *ap,
struct sk_buff *skb)
{
+ struct cardstate *cs = iif->ctr.driverdata;
+
/* decode message */
- capi_message2cmsg(&iif->acmsg, skb->data);
+ if (capi_message2cmsg(&iif->acmsg, skb->data)) {
+ dev_err(cs->dev, "%s: message parser failure\n", __func__);
+ dev_kfree_skb_any(skb);
+ return;
+ }
dump_cmsg(DEBUG_CMD, __func__, &iif->acmsg);
/* store listening parameters */
@@ -1261,8 +1308,14 @@ static void do_alert_req(struct gigaset_capi_ctr *iif,
struct gigaset_capi_appl *ap,
struct sk_buff *skb)
{
+ struct cardstate *cs = iif->ctr.driverdata;
+
/* decode message */
- capi_message2cmsg(&iif->acmsg, skb->data);
+ if (capi_message2cmsg(&iif->acmsg, skb->data)) {
+ dev_err(cs->dev, "%s: message parser failure\n", __func__);
+ dev_kfree_skb_any(skb);
+ return;
+ }
dump_cmsg(DEBUG_CMD, __func__, &iif->acmsg);
send_conf(iif, ap, skb, CapiAlertAlreadySent);
}
@@ -1287,7 +1340,11 @@ static void do_connect_req(struct gigaset_capi_ctr *iif,
u16 info;
/* decode message */
- capi_message2cmsg(cmsg, skb->data);
+ if (capi_message2cmsg(cmsg, skb->data)) {
+ dev_err(cs->dev, "%s: message parser failure\n", __func__);
+ dev_kfree_skb_any(skb);
+ return;
+ }
dump_cmsg(DEBUG_CMD, __func__, cmsg);
/* get free B channel & construct PLCI */
@@ -1574,7 +1631,11 @@ static void do_connect_resp(struct gigaset_capi_ctr *iif,
int channel;
/* decode message */
- capi_message2cmsg(cmsg, skb->data);
+ if (capi_message2cmsg(cmsg, skb->data)) {
+ dev_err(cs->dev, "%s: message parser failure\n", __func__);
+ dev_kfree_skb_any(skb);
+ return;
+ }
dump_cmsg(DEBUG_CMD, __func__, cmsg);
dev_kfree_skb_any(skb);
@@ -1740,7 +1801,11 @@ static void do_connect_b3_req(struct gigaset_capi_ctr *iif,
int channel;
/* decode message */
- capi_message2cmsg(cmsg, skb->data);
+ if (capi_message2cmsg(cmsg, skb->data)) {
+ dev_err(cs->dev, "%s: message parser failure\n", __func__);
+ dev_kfree_skb_any(skb);
+ return;
+ }
dump_cmsg(DEBUG_CMD, __func__, cmsg);
/* extract and check channel number from PLCI */
@@ -1785,7 +1850,11 @@ static void do_connect_b3_resp(struct gigaset_capi_ctr *iif,
u8 command;
/* decode message */
- capi_message2cmsg(cmsg, skb->data);
+ if (capi_message2cmsg(cmsg, skb->data)) {
+ dev_err(cs->dev, "%s: message parser failure\n", __func__);
+ dev_kfree_skb_any(skb);
+ return;
+ }
dump_cmsg(DEBUG_CMD, __func__, cmsg);
/* extract and check channel number and NCCI */
@@ -1825,7 +1894,11 @@ static void do_connect_b3_resp(struct gigaset_capi_ctr *iif,
capi_cmsg_header(cmsg, ap->id, command, CAPI_IND,
ap->nextMessageNumber++, cmsg->adr.adrNCCI);
__skb_trim(skb, msgsize);
- capi_cmsg2message(cmsg, skb->data);
+ if (capi_cmsg2message(cmsg, skb->data)) {
+ dev_err(cs->dev, "%s: message parser failure\n", __func__);
+ dev_kfree_skb_any(skb);
+ return;
+ }
dump_cmsg(DEBUG_CMD, __func__, cmsg);
capi_ctr_handle_message(&iif->ctr, ap->id, skb);
}
@@ -1847,7 +1920,11 @@ static void do_disconnect_req(struct gigaset_capi_ctr *iif,
int channel;
/* decode message */
- capi_message2cmsg(cmsg, skb->data);
+ if (capi_message2cmsg(cmsg, skb->data)) {
+ dev_err(cs->dev, "%s: message parser failure\n", __func__);
+ dev_kfree_skb_any(skb);
+ return;
+ }
dump_cmsg(DEBUG_CMD, __func__, cmsg);
/* extract and check channel number from PLCI */
@@ -1903,8 +1980,14 @@ static void do_disconnect_req(struct gigaset_capi_ctr *iif,
kfree(b3cmsg);
return;
}
- capi_cmsg2message(b3cmsg,
- __skb_put(b3skb, CAPI_DISCONNECT_B3_IND_BASELEN));
+ if (capi_cmsg2message(b3cmsg,
+ __skb_put(b3skb, CAPI_DISCONNECT_B3_IND_BASELEN))) {
+ dev_err(cs->dev, "%s: message parser failure\n",
+ __func__);
+ kfree(b3cmsg);
+ dev_kfree_skb_any(b3skb);
+ return;
+ }
dump_cmsg(DEBUG_CMD, __func__, b3cmsg);
kfree(b3cmsg);
capi_ctr_handle_message(&iif->ctr, ap->id, b3skb);
@@ -1935,7 +2018,11 @@ static void do_disconnect_b3_req(struct gigaset_capi_ctr *iif,
int channel;
/* decode message */
- capi_message2cmsg(cmsg, skb->data);
+ if (capi_message2cmsg(cmsg, skb->data)) {
+ dev_err(cs->dev, "%s: message parser failure\n", __func__);
+ dev_kfree_skb_any(skb);
+ return;
+ }
dump_cmsg(DEBUG_CMD, __func__, cmsg);
/* extract and check channel number and NCCI */
@@ -2052,8 +2139,14 @@ static void do_reset_b3_req(struct gigaset_capi_ctr *iif,
struct gigaset_capi_appl *ap,
struct sk_buff *skb)
{
+ struct cardstate *cs = iif->ctr.driverdata;
+
/* decode message */
- capi_message2cmsg(&iif->acmsg, skb->data);
+ if (capi_message2cmsg(&iif->acmsg, skb->data)) {
+ dev_err(cs->dev, "%s: message parser failure\n", __func__);
+ dev_kfree_skb_any(skb);
+ return;
+ }
dump_cmsg(DEBUG_CMD, __func__, &iif->acmsg);
send_conf(iif, ap, skb,
CapiResetProcedureNotSupportedByCurrentProtocol);
@@ -2066,8 +2159,14 @@ static void do_unsupported(struct gigaset_capi_ctr *iif,
struct gigaset_capi_appl *ap,
struct sk_buff *skb)
{
+ struct cardstate *cs = iif->ctr.driverdata;
+
/* decode message */
- capi_message2cmsg(&iif->acmsg, skb->data);
+ if (capi_message2cmsg(&iif->acmsg, skb->data)) {
+ dev_err(cs->dev, "%s: message parser failure\n", __func__);
+ dev_kfree_skb_any(skb);
+ return;
+ }
dump_cmsg(DEBUG_CMD, __func__, &iif->acmsg);
send_conf(iif, ap, skb, CapiMessageNotSupportedInCurrentState);
}
@@ -2079,8 +2178,14 @@ static void do_nothing(struct gigaset_capi_ctr *iif,
struct gigaset_capi_appl *ap,
struct sk_buff *skb)
{
+ struct cardstate *cs = iif->ctr.driverdata;
+
/* decode message */
- capi_message2cmsg(&iif->acmsg, skb->data);
+ if (capi_message2cmsg(&iif->acmsg, skb->data)) {
+ dev_err(cs->dev, "%s: message parser failure\n", __func__);
+ dev_kfree_skb_any(skb);
+ return;
+ }
dump_cmsg(DEBUG_CMD, __func__, &iif->acmsg);
dev_kfree_skb_any(skb);
}
@@ -2357,7 +2462,7 @@ int gigaset_isdn_regdev(struct cardstate *cs, const char *isdnid)
struct gigaset_capi_ctr *iif;
int rc;
- iif = kmalloc(sizeof(*iif), GFP_KERNEL);
+ iif = kzalloc(sizeof(*iif), GFP_KERNEL);
if (!iif) {
pr_err("%s: out of memory\n", __func__);
return -ENOMEM;
@@ -2366,7 +2471,7 @@ int gigaset_isdn_regdev(struct cardstate *cs, const char *isdnid)
/* prepare controller structure */
iif->ctr.owner = THIS_MODULE;
iif->ctr.driverdata = cs;
- strncpy(iif->ctr.name, isdnid, sizeof(iif->ctr.name));
+ strncpy(iif->ctr.name, isdnid, sizeof(iif->ctr.name) - 1);
iif->ctr.driver_name = "gigaset";
iif->ctr.load_firmware = NULL;
iif->ctr.reset_ctr = NULL;
diff --git a/drivers/isdn/gigaset/ev-layer.c b/drivers/isdn/gigaset/ev-layer.c
index 7459b127ddd5..c8ced12fa452 100644
--- a/drivers/isdn/gigaset/ev-layer.c
+++ b/drivers/isdn/gigaset/ev-layer.c
@@ -604,14 +604,14 @@ void gigaset_handle_modem_response(struct cardstate *cs)
}
EXPORT_SYMBOL_GPL(gigaset_handle_modem_response);
-/* disconnect
+/* disconnect_nobc
* process closing of connection associated with given AT state structure
+ * without B channel
*/
-static void disconnect(struct at_state_t **at_state_p)
+static void disconnect_nobc(struct at_state_t **at_state_p,
+ struct cardstate *cs)
{
unsigned long flags;
- struct bc_state *bcs = (*at_state_p)->bcs;
- struct cardstate *cs = (*at_state_p)->cs;
spin_lock_irqsave(&cs->lock, flags);
++(*at_state_p)->seq_index;
@@ -622,23 +622,44 @@ static void disconnect(struct at_state_t **at_state_p)
gig_dbg(DEBUG_EVENT, "Scheduling PC_UMMODE");
cs->commands_pending = 1;
}
- spin_unlock_irqrestore(&cs->lock, flags);
- if (bcs) {
- /* B channel assigned: invoke hardware specific handler */
- cs->ops->close_bchannel(bcs);
- /* notify LL */
- if (bcs->chstate & (CHS_D_UP | CHS_NOTIFY_LL)) {
- bcs->chstate &= ~(CHS_D_UP | CHS_NOTIFY_LL);
- gigaset_isdn_hupD(bcs);
- }
- } else {
- /* no B channel assigned: just deallocate */
- spin_lock_irqsave(&cs->lock, flags);
+ /* check for and deallocate temporary AT state */
+ if (!list_empty(&(*at_state_p)->list)) {
list_del(&(*at_state_p)->list);
kfree(*at_state_p);
*at_state_p = NULL;
- spin_unlock_irqrestore(&cs->lock, flags);
+ }
+
+ spin_unlock_irqrestore(&cs->lock, flags);
+}
+
+/* disconnect_bc
+ * process closing of connection associated with given AT state structure
+ * and B channel
+ */
+static void disconnect_bc(struct at_state_t *at_state,
+ struct cardstate *cs, struct bc_state *bcs)
+{
+ unsigned long flags;
+
+ spin_lock_irqsave(&cs->lock, flags);
+ ++at_state->seq_index;
+
+ /* revert to selected idle mode */
+ if (!cs->cidmode) {
+ cs->at_state.pending_commands |= PC_UMMODE;
+ gig_dbg(DEBUG_EVENT, "Scheduling PC_UMMODE");
+ cs->commands_pending = 1;
+ }
+ spin_unlock_irqrestore(&cs->lock, flags);
+
+ /* invoke hardware specific handler */
+ cs->ops->close_bchannel(bcs);
+
+ /* notify LL */
+ if (bcs->chstate & (CHS_D_UP | CHS_NOTIFY_LL)) {
+ bcs->chstate &= ~(CHS_D_UP | CHS_NOTIFY_LL);
+ gigaset_isdn_hupD(bcs);
}
}
@@ -646,7 +667,7 @@ static void disconnect(struct at_state_t **at_state_p)
* get a free AT state structure: either one of those associated with the
* B channels of the Gigaset device, or if none of those is available,
* a newly allocated one with bcs=NULL
- * The structure should be freed by calling disconnect() after use.
+ * The structure should be freed by calling disconnect_nobc() after use.
*/
static inline struct at_state_t *get_free_channel(struct cardstate *cs,
int cid)
@@ -1057,7 +1078,7 @@ static void do_action(int action, struct cardstate *cs,
struct event_t *ev)
{
struct at_state_t *at_state = *p_at_state;
- struct at_state_t *at_state2;
+ struct bc_state *bcs2;
unsigned long flags;
int channel;
@@ -1156,8 +1177,8 @@ static void do_action(int action, struct cardstate *cs,
break;
case ACT_RING:
/* get fresh AT state structure for new CID */
- at_state2 = get_free_channel(cs, ev->parameter);
- if (!at_state2) {
+ at_state = get_free_channel(cs, ev->parameter);
+ if (!at_state) {
dev_warn(cs->dev,
"RING ignored: could not allocate channel structure\n");
break;
@@ -1166,16 +1187,16 @@ static void do_action(int action, struct cardstate *cs,
/* initialize AT state structure
* note that bcs may be NULL if no B channel is free
*/
- at_state2->ConState = 700;
+ at_state->ConState = 700;
for (i = 0; i < STR_NUM; ++i) {
- kfree(at_state2->str_var[i]);
- at_state2->str_var[i] = NULL;
+ kfree(at_state->str_var[i]);
+ at_state->str_var[i] = NULL;
}
- at_state2->int_var[VAR_ZCTP] = -1;
+ at_state->int_var[VAR_ZCTP] = -1;
spin_lock_irqsave(&cs->lock, flags);
- at_state2->timer_expires = RING_TIMEOUT;
- at_state2->timer_active = 1;
+ at_state->timer_expires = RING_TIMEOUT;
+ at_state->timer_active = 1;
spin_unlock_irqrestore(&cs->lock, flags);
break;
case ACT_ICALL:
@@ -1213,14 +1234,17 @@ static void do_action(int action, struct cardstate *cs,
case ACT_DISCONNECT:
cs->cur_at_seq = SEQ_NONE;
at_state->cid = -1;
- if (bcs && cs->onechannel && cs->dle) {
+ if (!bcs) {
+ disconnect_nobc(p_at_state, cs);
+ } else if (cs->onechannel && cs->dle) {
/* Check for other open channels not needed:
* DLE only used for M10x with one B channel.
*/
at_state->pending_commands |= PC_DLE0;
cs->commands_pending = 1;
- } else
- disconnect(p_at_state);
+ } else {
+ disconnect_bc(at_state, cs, bcs);
+ }
break;
case ACT_FAKEDLE0:
at_state->int_var[VAR_ZDLE] = 0;
@@ -1228,24 +1252,27 @@ static void do_action(int action, struct cardstate *cs,
/* fall through */
case ACT_DLE0:
cs->cur_at_seq = SEQ_NONE;
- at_state2 = &cs->bcs[cs->curchannel].at_state;
- disconnect(&at_state2);
+ bcs2 = cs->bcs + cs->curchannel;
+ disconnect_bc(&bcs2->at_state, cs, bcs2);
break;
case ACT_ABORTHUP:
cs->cur_at_seq = SEQ_NONE;
dev_warn(cs->dev, "Could not hang up.\n");
at_state->cid = -1;
- if (bcs && cs->onechannel)
+ if (!bcs)
+ disconnect_nobc(p_at_state, cs);
+ else if (cs->onechannel)
at_state->pending_commands |= PC_DLE0;
else
- disconnect(p_at_state);
+ disconnect_bc(at_state, cs, bcs);
schedule_init(cs, MS_RECOVER);
break;
case ACT_FAILDLE0:
cs->cur_at_seq = SEQ_NONE;
- dev_warn(cs->dev, "Could not leave DLE mode.\n");
- at_state2 = &cs->bcs[cs->curchannel].at_state;
- disconnect(&at_state2);
+ dev_warn(cs->dev, "Error leaving DLE mode.\n");
+ cs->dle = 0;
+ bcs2 = cs->bcs + cs->curchannel;
+ disconnect_bc(&bcs2->at_state, cs, bcs2);
schedule_init(cs, MS_RECOVER);
break;
case ACT_FAILDLE1:
@@ -1274,14 +1301,14 @@ static void do_action(int action, struct cardstate *cs,
if (reinit_and_retry(cs, channel) < 0) {
dev_warn(cs->dev,
"Could not get a call ID. Cannot dial.\n");
- at_state2 = &cs->bcs[channel].at_state;
- disconnect(&at_state2);
+ bcs2 = cs->bcs + channel;
+ disconnect_bc(&bcs2->at_state, cs, bcs2);
}
break;
case ACT_ABORTCID:
cs->cur_at_seq = SEQ_NONE;
- at_state2 = &cs->bcs[cs->curchannel].at_state;
- disconnect(&at_state2);
+ bcs2 = cs->bcs + cs->curchannel;
+ disconnect_bc(&bcs2->at_state, cs, bcs2);
break;
case ACT_DIALING:
@@ -1290,7 +1317,10 @@ static void do_action(int action, struct cardstate *cs,
break;
case ACT_ABORTACCEPT: /* hangup/error/timeout during ICALL procssng */
- disconnect(p_at_state);
+ if (bcs)
+ disconnect_bc(at_state, cs, bcs);
+ else
+ disconnect_nobc(p_at_state, cs);
break;
case ACT_ABORTDIAL: /* error/timeout during dial preparation */
@@ -1379,6 +1409,11 @@ static void do_action(int action, struct cardstate *cs,
/* events from the LL */
case ACT_DIAL:
+ if (!ev->ptr) {
+ *p_genresp = 1;
+ *p_resp_code = RSP_ERROR;
+ break;
+ }
start_dial(at_state, ev->ptr, ev->parameter);
break;
case ACT_ACCEPT:
diff --git a/drivers/isdn/gigaset/usb-gigaset.c b/drivers/isdn/gigaset/usb-gigaset.c
index d0a41cb0cf62..a8e652dac54d 100644
--- a/drivers/isdn/gigaset/usb-gigaset.c
+++ b/drivers/isdn/gigaset/usb-gigaset.c
@@ -135,14 +135,13 @@ struct usb_cardstate {
/* Output buffer */
unsigned char *bulk_out_buffer;
int bulk_out_size;
- __u8 bulk_out_endpointAddr;
+ int bulk_out_epnum;
struct urb *bulk_out_urb;
/* Input buffer */
unsigned char *rcvbuf;
int rcvbuf_size;
struct urb *read_urb;
- __u8 int_in_endpointAddr;
char bchars[6]; /* for request 0x19 */
};
@@ -466,7 +465,7 @@ static int send_cb(struct cardstate *cs, struct cmdbuf_t *cb)
usb_fill_bulk_urb(ucs->bulk_out_urb, ucs->udev,
usb_sndbulkpipe(ucs->udev,
- ucs->bulk_out_endpointAddr & 0x0f),
+ ucs->bulk_out_epnum),
cb->buf + cb->offset, count,
gigaset_write_bulk_callback, cs);
@@ -498,6 +497,7 @@ static int send_cb(struct cardstate *cs, struct cmdbuf_t *cb)
static int gigaset_write_cmd(struct cardstate *cs, struct cmdbuf_t *cb)
{
unsigned long flags;
+ int len;
gigaset_dbg_buffer(cs->mstate != MS_LOCKED ?
DEBUG_TRANSCMD : DEBUG_LOCKCMD,
@@ -516,10 +516,11 @@ static int gigaset_write_cmd(struct cardstate *cs, struct cmdbuf_t *cb)
spin_unlock_irqrestore(&cs->cmdlock, flags);
spin_lock_irqsave(&cs->lock, flags);
+ len = cb->len;
if (cs->connected)
tasklet_schedule(&cs->write_tasklet);
spin_unlock_irqrestore(&cs->lock, flags);
- return cb->len;
+ return len;
}
static int gigaset_write_room(struct cardstate *cs)
@@ -628,8 +629,7 @@ static int write_modem(struct cardstate *cs)
if (cs->connected) {
usb_fill_bulk_urb(ucs->bulk_out_urb, ucs->udev,
usb_sndbulkpipe(ucs->udev,
- ucs->bulk_out_endpointAddr &
- 0x0f),
+ ucs->bulk_out_epnum),
ucs->bulk_out_buffer, count,
gigaset_write_bulk_callback, cs);
ret = usb_submit_urb(ucs->bulk_out_urb, GFP_ATOMIC);
@@ -714,7 +714,7 @@ static int gigaset_probe(struct usb_interface *interface,
buffer_size = le16_to_cpu(endpoint->wMaxPacketSize);
ucs->bulk_out_size = buffer_size;
- ucs->bulk_out_endpointAddr = endpoint->bEndpointAddress;
+ ucs->bulk_out_epnum = usb_endpoint_num(endpoint);
ucs->bulk_out_buffer = kmalloc(buffer_size, GFP_KERNEL);
if (!ucs->bulk_out_buffer) {
dev_err(cs->dev, "Couldn't allocate bulk_out_buffer\n");
@@ -741,7 +741,6 @@ static int gigaset_probe(struct usb_interface *interface,
}
buffer_size = le16_to_cpu(endpoint->wMaxPacketSize);
ucs->rcvbuf_size = buffer_size;
- ucs->int_in_endpointAddr = endpoint->bEndpointAddress;
ucs->rcvbuf = kmalloc(buffer_size, GFP_KERNEL);
if (!ucs->rcvbuf) {
dev_err(cs->dev, "Couldn't allocate rcvbuf\n");
@@ -750,8 +749,7 @@ static int gigaset_probe(struct usb_interface *interface,
}
/* Fill the interrupt urb and send it to the core */
usb_fill_int_urb(ucs->read_urb, udev,
- usb_rcvintpipe(udev,
- endpoint->bEndpointAddress & 0x0f),
+ usb_rcvintpipe(udev, usb_endpoint_num(endpoint)),
ucs->rcvbuf, buffer_size,
gigaset_read_int_callback,
cs, endpoint->bInterval);
diff --git a/drivers/isdn/i4l/isdn_tty.c b/drivers/isdn/i4l/isdn_tty.c
index 3c5f2491a16f..bc912611fe09 100644
--- a/drivers/isdn/i4l/isdn_tty.c
+++ b/drivers/isdn/i4l/isdn_tty.c
@@ -1043,11 +1043,6 @@ isdn_tty_change_speed(modem_info *info)
if (!(cflag & PARODD))
cval |= UART_LCR_EPAR;
- /* CTS flow control flag and modem status interrupts */
- if (cflag & CRTSCTS) {
- port->flags |= ASYNC_CTS_FLOW;
- } else
- port->flags &= ~ASYNC_CTS_FLOW;
if (cflag & CLOCAL)
port->flags &= ~ASYNC_CHECK_CD;
else {
diff --git a/drivers/isdn/mISDN/dsp_cmx.c b/drivers/isdn/mISDN/dsp_cmx.c
index a4f05c54c32b..87f7dff20ff6 100644
--- a/drivers/isdn/mISDN/dsp_cmx.c
+++ b/drivers/isdn/mISDN/dsp_cmx.c
@@ -1454,66 +1454,63 @@ dsp_cmx_send_member(struct dsp *dsp, int len, s32 *c, int members)
#ifdef CMX_CONF_DEBUG
if (0) {
#else
- if (members == 2) {
+ if (members == 2) {
#endif
- /* "other" becomes other party */
- other = (list_entry(conf->mlist.next,
- struct dsp_conf_member, list))->dsp;
- if (other == member)
- other = (list_entry(conf->mlist.prev,
- struct dsp_conf_member, list))->dsp;
- o_q = other->rx_buff; /* received data */
- o_rr = (other->rx_R + len) & CMX_BUFF_MASK;
- /* end of rx-pointer */
- o_r = (o_rr - rr + r) & CMX_BUFF_MASK;
- /* start rx-pointer at current read position*/
- /* -> if echo is NOT enabled */
- if (!dsp->echo.software) {
- /*
- * -> copy other member's rx-data,
- * if tx-data is available, mix
- */
- while (o_r != o_rr && t != tt) {
- *d++ = dsp_audio_mix_law[(p[t] << 8) | o_q[o_r]];
- t = (t + 1) & CMX_BUFF_MASK;
- o_r = (o_r + 1) & CMX_BUFF_MASK;
- }
- while (o_r != o_rr) {
- *d++ = o_q[o_r];
- o_r = (o_r + 1) & CMX_BUFF_MASK;
- }
- /* -> if echo is enabled */
- } else {
- /*
- * -> mix other member's rx-data with echo,
- * if tx-data is available, mix
- */
- while (r != rr && t != tt) {
- sample = dsp_audio_law_to_s32[p[t]] +
- dsp_audio_law_to_s32[q[r]] +
- dsp_audio_law_to_s32[o_q[o_r]];
- if (sample < -32768)
- sample = -32768;
- else if (sample > 32767)
- sample = 32767;
- *d++ = dsp_audio_s16_to_law[sample & 0xffff];
- /* tx-data + rx_data + echo */
- t = (t + 1) & CMX_BUFF_MASK;
- r = (r + 1) & CMX_BUFF_MASK;
- o_r = (o_r + 1) & CMX_BUFF_MASK;
- }
- while (r != rr) {
- *d++ = dsp_audio_mix_law[(q[r] << 8) | o_q[o_r]];
- r = (r + 1) & CMX_BUFF_MASK;
- o_r = (o_r + 1) & CMX_BUFF_MASK;
- }
+ /* "other" becomes other party */
+ other = (list_entry(conf->mlist.next,
+ struct dsp_conf_member, list))->dsp;
+ if (other == member)
+ other = (list_entry(conf->mlist.prev,
+ struct dsp_conf_member, list))->dsp;
+ o_q = other->rx_buff; /* received data */
+ o_rr = (other->rx_R + len) & CMX_BUFF_MASK;
+ /* end of rx-pointer */
+ o_r = (o_rr - rr + r) & CMX_BUFF_MASK;
+ /* start rx-pointer at current read position*/
+ /* -> if echo is NOT enabled */
+ if (!dsp->echo.software) {
+ /*
+ * -> copy other member's rx-data,
+ * if tx-data is available, mix
+ */
+ while (o_r != o_rr && t != tt) {
+ *d++ = dsp_audio_mix_law[(p[t] << 8) | o_q[o_r]];
+ t = (t + 1) & CMX_BUFF_MASK;
+ o_r = (o_r + 1) & CMX_BUFF_MASK;
+ }
+ while (o_r != o_rr) {
+ *d++ = o_q[o_r];
+ o_r = (o_r + 1) & CMX_BUFF_MASK;
+ }
+ /* -> if echo is enabled */
+ } else {
+ /*
+ * -> mix other member's rx-data with echo,
+ * if tx-data is available, mix
+ */
+ while (r != rr && t != tt) {
+ sample = dsp_audio_law_to_s32[p[t]] +
+ dsp_audio_law_to_s32[q[r]] +
+ dsp_audio_law_to_s32[o_q[o_r]];
+ if (sample < -32768)
+ sample = -32768;
+ else if (sample > 32767)
+ sample = 32767;
+ *d++ = dsp_audio_s16_to_law[sample & 0xffff];
+ /* tx-data + rx_data + echo */
+ t = (t + 1) & CMX_BUFF_MASK;
+ r = (r + 1) & CMX_BUFF_MASK;
+ o_r = (o_r + 1) & CMX_BUFF_MASK;
+ }
+ while (r != rr) {
+ *d++ = dsp_audio_mix_law[(q[r] << 8) | o_q[o_r]];
+ r = (r + 1) & CMX_BUFF_MASK;
+ o_r = (o_r + 1) & CMX_BUFF_MASK;
}
- dsp->tx_R = t;
- goto send_packet;
}
-#ifdef DSP_NEVER_DEFINED
+ dsp->tx_R = t;
+ goto send_packet;
}
-#endif
/* PROCESS DATA (three or more members) */
/* -> if echo is NOT enabled */
if (!dsp->echo.software) {