summaryrefslogtreecommitdiffstats
path: root/drivers/isdn/gigaset/i4l.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/isdn/gigaset/i4l.c')
-rw-r--r--drivers/isdn/gigaset/i4l.c57
1 files changed, 32 insertions, 25 deletions
diff --git a/drivers/isdn/gigaset/i4l.c b/drivers/isdn/gigaset/i4l.c
index aca72a06184..c129ee47a8f 100644
--- a/drivers/isdn/gigaset/i4l.c
+++ b/drivers/isdn/gigaset/i4l.c
@@ -39,12 +39,12 @@
static int writebuf_from_LL(int driverID, int channel, int ack,
struct sk_buff *skb)
{
- struct cardstate *cs;
+ struct cardstate *cs = gigaset_get_cs_by_id(driverID);
struct bc_state *bcs;
+ unsigned char *ack_header;
unsigned len;
- unsigned skblen;
- if (!(cs = gigaset_get_cs_by_id(driverID))) {
+ if (!cs) {
pr_err("%s: invalid driver ID (%d)\n", __func__, driverID);
return -ENODEV;
}
@@ -78,11 +78,23 @@ static int writebuf_from_LL(int driverID, int channel, int ack,
return -EINVAL;
}
- skblen = ack ? len : 0;
- skb->head[0] = skblen & 0xff;
- skb->head[1] = skblen >> 8;
- gig_dbg(DEBUG_MCMD, "skb: len=%u, skblen=%u: %02x %02x",
- len, skblen, (unsigned) skb->head[0], (unsigned) skb->head[1]);
+ /* set up acknowledgement header */
+ if (skb_headroom(skb) < HW_HDR_LEN) {
+ /* should never happen */
+ dev_err(cs->dev, "%s: insufficient skb headroom\n", __func__);
+ return -ENOMEM;
+ }
+ skb_set_mac_header(skb, -HW_HDR_LEN);
+ skb->mac_len = HW_HDR_LEN;
+ ack_header = skb_mac_header(skb);
+ if (ack) {
+ ack_header[0] = len & 0xff;
+ ack_header[1] = len >> 8;
+ } else {
+ ack_header[0] = ack_header[1] = 0;
+ }
+ gig_dbg(DEBUG_MCMD, "skb: len=%u, ack=%d: %02x %02x",
+ len, ack, ack_header[0], ack_header[1]);
/* pass to device-specific module */
return cs->ops->send_skb(bcs, skb);
@@ -99,6 +111,7 @@ static int writebuf_from_LL(int driverID, int channel, int ack,
void gigaset_skb_sent(struct bc_state *bcs, struct sk_buff *skb)
{
isdn_if *iif = bcs->cs->iif;
+ unsigned char *ack_header = skb_mac_header(skb);
unsigned len;
isdn_ctrl response;
@@ -108,8 +121,7 @@ void gigaset_skb_sent(struct bc_state *bcs, struct sk_buff *skb)
dev_warn(bcs->cs->dev, "%s: skb->len==%d\n",
__func__, skb->len);
- len = (unsigned char) skb->head[0] |
- (unsigned) (unsigned char) skb->head[1] << 8;
+ len = ack_header[0] + ((unsigned) ack_header[1] << 8);
if (len) {
gig_dbg(DEBUG_MCMD, "ACKing to LL (id: %d, ch: %d, sz: %u)",
bcs->cs->myid, bcs->channel, len);
@@ -379,22 +391,19 @@ static int command_from_LL(isdn_ctrl *cntrl)
break;
case ISDN_CMD_PROCEED:
- gig_dbg(DEBUG_ANY, "ISDN_CMD_PROCEED"); //FIXME
+ gig_dbg(DEBUG_ANY, "ISDN_CMD_PROCEED");
break;
case ISDN_CMD_ALERT:
- gig_dbg(DEBUG_ANY, "ISDN_CMD_ALERT"); //FIXME
+ gig_dbg(DEBUG_ANY, "ISDN_CMD_ALERT");
if (cntrl->arg >= cs->channels) {
dev_err(cs->dev,
"ISDN_CMD_ALERT: invalid channel (%d)\n",
(int) cntrl->arg);
return -EINVAL;
}
- //bcs = cs->bcs + cntrl->arg;
- //bcs->proto2 = -1;
- // FIXME
break;
case ISDN_CMD_REDIR:
- gig_dbg(DEBUG_ANY, "ISDN_CMD_REDIR"); //FIXME
+ gig_dbg(DEBUG_ANY, "ISDN_CMD_REDIR");
break;
case ISDN_CMD_PROT_IO:
gig_dbg(DEBUG_ANY, "ISDN_CMD_PROT_IO");
@@ -474,7 +483,7 @@ int gigaset_isdn_icall(struct at_state_t *at_state)
/* fill ICALL structure */
response.parm.setup.si1 = 0; /* default: unknown */
response.parm.setup.si2 = 0;
- response.parm.setup.screen = 0; //FIXME how to set these?
+ response.parm.setup.screen = 0;
response.parm.setup.plan = 0;
if (!at_state->str_var[STR_ZBC]) {
/* no BC (internal call): assume speech, A-law */
@@ -495,26 +504,24 @@ int gigaset_isdn_icall(struct at_state_t *at_state)
return ICALL_IGNORE;
}
if (at_state->str_var[STR_NMBR]) {
- strncpy(response.parm.setup.phone, at_state->str_var[STR_NMBR],
- sizeof response.parm.setup.phone - 1);
- response.parm.setup.phone[sizeof response.parm.setup.phone - 1] = 0;
+ strlcpy(response.parm.setup.phone, at_state->str_var[STR_NMBR],
+ sizeof response.parm.setup.phone);
} else
response.parm.setup.phone[0] = 0;
if (at_state->str_var[STR_ZCPN]) {
- strncpy(response.parm.setup.eazmsn, at_state->str_var[STR_ZCPN],
- sizeof response.parm.setup.eazmsn - 1);
- response.parm.setup.eazmsn[sizeof response.parm.setup.eazmsn - 1] = 0;
+ strlcpy(response.parm.setup.eazmsn, at_state->str_var[STR_ZCPN],
+ sizeof response.parm.setup.eazmsn);
} else
response.parm.setup.eazmsn[0] = 0;
if (!bcs) {
dev_notice(cs->dev, "no channel for incoming call\n");
response.command = ISDN_STAT_ICALLW;
- response.arg = 0; //FIXME
+ response.arg = 0;
} else {
gig_dbg(DEBUG_CMD, "Sending ICALL");
response.command = ISDN_STAT_ICALL;
- response.arg = bcs->channel; //FIXME
+ response.arg = bcs->channel;
}
response.driver = cs->myid;
retval = iif->statcallb(&response);