Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 170888
b: refs/heads/master
c: 4dd8230
h: refs/heads/master
v: v3
  • Loading branch information
Tilman Schmidt authored and David S. Miller committed Oct 29, 2009
1 parent 71d2dd0 commit c15ee9d
Show file tree
Hide file tree
Showing 6 changed files with 71 additions and 51 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 22077ebceb44f4097d4677e2a26bc1175143d647
refs/heads/master: 4dd8230acd20cb456cae02696b3da2986faad258
55 changes: 31 additions & 24 deletions trunk/drivers/isdn/gigaset/asyncdata.c
Original file line number Diff line number Diff line change
Expand Up @@ -156,7 +156,7 @@ static inline int hdlc_loop(unsigned char c, unsigned char *src, int numbytes,

/* end of frame */
gigaset_isdn_rcv_err(bcs);
dev_kfree_skb(skb);
dev_kfree_skb_any(skb);
} else if (!(inputstate & INS_have_data)) { /* 7E 7E */
#ifdef CONFIG_GIGASET_DEBUG
++bcs->emptycount;
Expand All @@ -172,7 +172,7 @@ static inline int hdlc_loop(unsigned char c, unsigned char *src, int numbytes,
"Checksum failed, %u bytes corrupted!\n",
skb->len);
gigaset_isdn_rcv_err(bcs);
dev_kfree_skb(skb);
dev_kfree_skb_any(skb);
} else if (likely(skb->len > 2)) {
__skb_trim(skb, skb->len - 2);
gigaset_skb_rcvd(bcs, skb);
Expand All @@ -182,7 +182,7 @@ static inline int hdlc_loop(unsigned char c, unsigned char *src, int numbytes,
"invalid packet size (%d)\n", skb->len);
gigaset_isdn_rcv_err(bcs);
}
dev_kfree_skb(skb);
dev_kfree_skb_any(skb);
}
}

Expand Down Expand Up @@ -430,11 +430,11 @@ EXPORT_SYMBOL_GPL(gigaset_m10x_input);
* opening and closing flags, preserving headroom data.
* parameters:
* skb skb containing original packet (freed upon return)
* headroom number of headroom bytes to preserve
* Return value:
* pointer to newly allocated skb containing the result frame
* and the original link layer header, NULL on error
*/
static struct sk_buff *HDLC_Encode(struct sk_buff *skb, int headroom)
static struct sk_buff *HDLC_Encode(struct sk_buff *skb)
{
struct sk_buff *hdlc_skb;
__u16 fcs;
Expand All @@ -456,17 +456,19 @@ static struct sk_buff *HDLC_Encode(struct sk_buff *skb, int headroom)

/* size of new buffer: original size + number of stuffing bytes
* + 2 bytes FCS + 2 stuffing bytes for FCS (if needed) + 2 flag bytes
* + room for acknowledgement header
* + room for link layer header
*/
hdlc_skb = dev_alloc_skb(skb->len + stuf_cnt + 6 + headroom);
hdlc_skb = dev_alloc_skb(skb->len + stuf_cnt + 6 + skb->mac_len);
if (!hdlc_skb) {
dev_kfree_skb(skb);
dev_kfree_skb_any(skb);
return NULL;
}

/* Copy acknowledgement header into new skb */
skb_reserve(hdlc_skb, headroom);
memcpy(hdlc_skb->head, skb->head, headroom);
/* Copy link layer header into new skb */
skb_reset_mac_header(hdlc_skb);
skb_reserve(hdlc_skb, skb->mac_len);
memcpy(skb_mac_header(hdlc_skb), skb_mac_header(skb), skb->mac_len);
hdlc_skb->mac_len = skb->mac_len;

/* Add flag sequence in front of everything.. */
*(skb_put(hdlc_skb, 1)) = PPP_FLAG;
Expand Down Expand Up @@ -497,7 +499,7 @@ static struct sk_buff *HDLC_Encode(struct sk_buff *skb, int headroom)

*(skb_put(hdlc_skb, 1)) = PPP_FLAG;

dev_kfree_skb(skb);
dev_kfree_skb_any(skb);
return hdlc_skb;
}

Expand All @@ -506,28 +508,33 @@ static struct sk_buff *HDLC_Encode(struct sk_buff *skb, int headroom)
* preserving headroom data.
* parameters:
* skb skb containing original packet (freed upon return)
* headroom number of headroom bytes to preserve
* Return value:
* pointer to newly allocated skb containing the result frame
* and the original link layer header, NULL on error
*/
static struct sk_buff *iraw_encode(struct sk_buff *skb, int headroom)
static struct sk_buff *iraw_encode(struct sk_buff *skb)
{
struct sk_buff *iraw_skb;
unsigned char c;
unsigned char *cp;
int len;

/* worst case: every byte must be stuffed */
iraw_skb = dev_alloc_skb(2*skb->len + headroom);
/* size of new buffer (worst case = every byte must be stuffed):
* 2 * original size + room for link layer header
*/
iraw_skb = dev_alloc_skb(2*skb->len + skb->mac_len);
if (!iraw_skb) {
dev_kfree_skb(skb);
dev_kfree_skb_any(skb);
return NULL;
}

/* Copy acknowledgement header into new skb */
skb_reserve(iraw_skb, headroom);
memcpy(iraw_skb->head, skb->head, headroom);
/* copy link layer header into new skb */
skb_reset_mac_header(iraw_skb);
skb_reserve(iraw_skb, skb->mac_len);
memcpy(skb_mac_header(iraw_skb), skb_mac_header(skb), skb->mac_len);
iraw_skb->mac_len = skb->mac_len;

/* copy and stuff data */
cp = skb->data;
len = skb->len;
while (len--) {
Expand All @@ -536,7 +543,7 @@ static struct sk_buff *iraw_encode(struct sk_buff *skb, int headroom)
*(skb_put(iraw_skb, 1)) = c;
*(skb_put(iraw_skb, 1)) = c;
}
dev_kfree_skb(skb);
dev_kfree_skb_any(skb);
return iraw_skb;
}

Expand All @@ -548,7 +555,7 @@ static struct sk_buff *iraw_encode(struct sk_buff *skb, int headroom)
* Called by LL to encode and queue an skb for sending, and start
* transmission if necessary.
* Once the payload data has been transmitted completely, gigaset_skb_sent()
* will be called with the first cs->hw_hdr_len bytes of skb->head preserved.
* will be called with the skb's link layer header preserved.
*
* Return value:
* number of bytes accepted for sending (skb->len) if ok,
Expand All @@ -560,9 +567,9 @@ int gigaset_m10x_send_skb(struct bc_state *bcs, struct sk_buff *skb)
unsigned long flags;

if (bcs->proto2 == L2_HDLC)
skb = HDLC_Encode(skb, bcs->cs->hw_hdr_len);
skb = HDLC_Encode(skb);
else
skb = iraw_encode(skb, bcs->cs->hw_hdr_len);
skb = iraw_encode(skb);
if (!skb) {
dev_err(bcs->cs->dev,
"unable to allocate memory for encoding!\n");
Expand Down
29 changes: 15 additions & 14 deletions trunk/drivers/isdn/gigaset/capi.c
Original file line number Diff line number Diff line change
Expand Up @@ -362,6 +362,7 @@ void gigaset_skb_sent(struct bc_state *bcs, struct sk_buff *dskb)
struct cardstate *cs = bcs->cs;
struct gigaset_capi_ctr *iif = cs->iif;
struct gigaset_capi_appl *ap = bcs->ap;
unsigned char *req = skb_mac_header(dskb);
struct sk_buff *cskb;
u16 flags;

Expand All @@ -380,7 +381,7 @@ void gigaset_skb_sent(struct bc_state *bcs, struct sk_buff *dskb)
}

/* ToDo: honor unset "delivery confirmation" bit */
flags = CAPIMSG_FLAGS(dskb->head);
flags = CAPIMSG_FLAGS(req);

/* build DATA_B3_CONF message */
cskb = alloc_skb(CAPI_DATA_B3_CONF_LEN, GFP_ATOMIC);
Expand All @@ -393,11 +394,11 @@ void gigaset_skb_sent(struct bc_state *bcs, struct sk_buff *dskb)
CAPIMSG_SETAPPID(cskb->data, ap->id);
CAPIMSG_SETCOMMAND(cskb->data, CAPI_DATA_B3);
CAPIMSG_SETSUBCOMMAND(cskb->data, CAPI_CONF);
CAPIMSG_SETMSGID(cskb->data, CAPIMSG_MSGID(dskb->head));
CAPIMSG_SETMSGID(cskb->data, CAPIMSG_MSGID(req));
CAPIMSG_SETCONTROLLER(cskb->data, iif->ctr.cnr);
CAPIMSG_SETPLCI_PART(cskb->data, bcs->channel + 1);
CAPIMSG_SETNCCI_PART(cskb->data, 1);
CAPIMSG_SETHANDLE_CONF(cskb->data, CAPIMSG_HANDLE_REQ(dskb->head));
CAPIMSG_SETHANDLE_CONF(cskb->data, CAPIMSG_HANDLE_REQ(req));
if (flags & ~CAPI_FLAGS_DELIVERY_CONFIRMATION)
CAPIMSG_SETINFO_CONF(cskb->data,
CapiFlagsNotSupportedByProtocol);
Expand Down Expand Up @@ -437,7 +438,7 @@ void gigaset_skb_rcvd(struct bc_state *bcs, struct sk_buff *skb)
/* don't send further B3 messages if disconnected */
if (ap->connected < APCONN_ACTIVE) {
gig_dbg(DEBUG_LLDATA, "disconnected, discarding data");
dev_kfree_skb(skb);
dev_kfree_skb_any(skb);
return;
}

Expand Down Expand Up @@ -1461,7 +1462,7 @@ static void do_connect_resp(struct gigaset_capi_ctr *iif,
/* decode message */
capi_message2cmsg(cmsg, skb->data);
dump_cmsg(DEBUG_CMD, __func__, cmsg);
dev_kfree_skb(skb);
dev_kfree_skb_any(skb);

/* extract and check channel number from PLCI */
channel = (cmsg->adr.adrPLCI >> 8) & 0xff;
Expand Down Expand Up @@ -1652,7 +1653,7 @@ static void do_connect_b3_resp(struct gigaset_capi_ctr *iif,
((cmsg->adr.adrNCCI >> 16) & 0xffff) != 1) {
dev_notice(cs->dev, "%s: invalid %s 0x%02x\n",
"CONNECT_B3_RESP", "NCCI", cmsg->adr.adrNCCI);
dev_kfree_skb(skb);
dev_kfree_skb_any(skb);
return;
}
bcs = &cs->bcs[channel-1];
Expand All @@ -1665,7 +1666,7 @@ static void do_connect_b3_resp(struct gigaset_capi_ctr *iif,
if (!gigaset_add_event(cs, &bcs->at_state,
EV_HUP, NULL, 0, NULL)) {
dev_err(cs->dev, "%s: out of memory\n", __func__);
dev_kfree_skb(skb);
dev_kfree_skb_any(skb);
return;
}
gig_dbg(DEBUG_CMD, "scheduling HUP");
Expand Down Expand Up @@ -1880,12 +1881,12 @@ static void do_data_b3_req(struct gigaset_capi_ctr *iif,
return;
}

/*
* pull CAPI message from skb,
* pass payload data to device-specific module
* CAPI message will be preserved in headroom
*/
/* pull CAPI message into link layer header */
skb_reset_mac_header(skb);
skb->mac_len = msglen;
skb_pull(skb, msglen);

/* pass to device-specific module */
if (cs->ops->send_skb(&cs->bcs[channel-1], skb) < 0) {
send_conf(iif, ap, skb, CAPI_MSGOSRESOURCEERR);
return;
Expand Down Expand Up @@ -1946,15 +1947,15 @@ static void do_nothing(struct gigaset_capi_ctr *iif,
capi_message2cmsg(&iif->acmsg, skb->data);
dump_cmsg(DEBUG_CMD, __func__, &iif->acmsg);
}
dev_kfree_skb(skb);
dev_kfree_skb_any(skb);
}

static void do_data_b3_resp(struct gigaset_capi_ctr *iif,
struct gigaset_capi_appl *ap,
struct sk_buff *skb)
{
dump_rawmsg(DEBUG_LLDATA, __func__, skb->data);
dev_kfree_skb(skb);
dev_kfree_skb_any(skb);
}

/* table of outgoing CAPI message handlers with lookup function */
Expand Down
2 changes: 1 addition & 1 deletion trunk/drivers/isdn/gigaset/gigaset.h
Original file line number Diff line number Diff line change
Expand Up @@ -625,7 +625,7 @@ struct gigaset_ops {

/* Called from LL interface to put an skb into the send-queue.
* After sending is completed, gigaset_skb_sent() must be called
* with the first cs->hw_hdr_len bytes of skb->head preserved. */
* with the skb's link layer header preserved. */
int (*send_skb)(struct bc_state *bcs, struct sk_buff *skb);

/* Called from ev-layer.c to process a block of data
Expand Down
28 changes: 20 additions & 8 deletions trunk/drivers/isdn/gigaset/i4l.c
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,8 @@ static int writebuf_from_LL(int driverID, int channel, int ack,
{
struct cardstate *cs;
struct bc_state *bcs;
unsigned char *ack_header;
unsigned len;
unsigned skblen;

if (!(cs = gigaset_get_cs_by_id(driverID))) {
pr_err("%s: invalid driver ID (%d)\n", __func__, driverID);
Expand Down Expand Up @@ -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);
Expand All @@ -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;

Expand All @@ -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);
Expand Down
6 changes: 3 additions & 3 deletions trunk/drivers/isdn/gigaset/isocdata.c
Original file line number Diff line number Diff line change
Expand Up @@ -576,12 +576,12 @@ static inline void hdlc_done(struct bc_state *bcs)
dev_notice(cs->dev, "received short frame (%d octets)\n",
procskb->len);
bcs->hw.bas->runts++;
dev_kfree_skb(procskb);
dev_kfree_skb_any(procskb);
gigaset_isdn_rcv_err(bcs);
} else if (bcs->fcs != PPP_GOODFCS) {
dev_notice(cs->dev, "frame check error (0x%04x)\n", bcs->fcs);
bcs->hw.bas->fcserrs++;
dev_kfree_skb(procskb);
dev_kfree_skb_any(procskb);
gigaset_isdn_rcv_err(bcs);
} else {
len = procskb->len;
Expand Down Expand Up @@ -985,7 +985,7 @@ void gigaset_isoc_input(struct inbuf_t *inbuf)
* Called by LL to queue an skb for sending, and start transmission if
* necessary.
* Once the payload data has been transmitted completely, gigaset_skb_sent()
* will be called with the first cs->hw_hdr_len bytes of skb->head preserved.
* will be called with the skb's link layer header preserved.
*
* Return value:
* number of bytes accepted for sending (skb->len) if ok,
Expand Down

0 comments on commit c15ee9d

Please sign in to comment.