Gigaset driver port to CAPI
Subsystems (2)
cover Gigaset driver port to CAPI
Folks,
the following set of six patches adds a configuration option to the Gigaset driver to interface to Kernel CAPI instead of the old ISDN4Linux subsystem. Although my unit test are not quite done yet I would appreciate comments.
The patchset is based on 2.6.31-rc6. The first two patches are bugfixes to the existing driver, the third one adds kerneldoc comments for a few functions. These three are included just so that the following ones will apply cleanly, although you are welcome to comment on them, too.
Patch 4 reorganizes the existing driver's code so that the new interface can be fitted in.
Patch 5 adds the Kconfig mechanism for making the ISDN subsystem interface selectable.
Patch 6 finally adds the actual Kernel CAPI interface, and is of course the one I am most eager to hear opinions about.
Thanks,
Tilman
RFC PATCH 1/6 gigaset: fix reject/hangup handling
Signal D channel disconnect in a few cases where it was missed, including when an incoming call is disconnected before it was accepted.
Impact: error handling improvement
--- drivers/isdn/gigaset/ev-layer.c | 5 +++++ 1 file changed, 5 insertions(+)
drivers/isdn/gigaset/ev-layer.c +5 -0
@@ -707,6 +707,11 @@ static void disconnect(struct at_state_t **at_state_p)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_i4l_channel_cmd (bcs,ISDN_STAT_DHUP ); + } }else {/* no B channel assigned: just deallocate */ spin_lock_irqsave (&cs->lock, flags);
Signature · 1 line
1.6.2.1.214.ge986c
RFC PATCH 2/6 gigaset: handle isoc frame errors more gracefully
In reply to Tilman SchmidtDon't drop the remainder of an URB if an isochronous frame has an error.
Impact: error handling improvement
--- drivers/isdn/gigaset/bas-gigaset.c | 18 +++++++----------- 1 files changed, 7 insertions(+), 11 deletions(-)
drivers/isdn/gigaset/bas-gigaset.c +7 -11
@@ -1331,28 +1331,24 @@ static void read_iso_tasklet(unsigned long data) rcvbuf = urb->transfer_buffer; totleft = urb->actual_length;for (frame =0 ; totleft >0 && frame <BAS_NUMFRAMES ; frame++) { -if (unlikely (urb->iso_frame_desc[frame].status)) { + numbytes = urb->iso_frame_desc[frame].actual_length; +if (unlikely (urb->iso_frame_desc[frame].status))dev_warn (cs->dev, -"isochronous read: frame %d: %s\n" , - frame, +"isochronous read: frame %d[%d]: %s\n" , + frame, numbytes,get_usb_statmsg ( urb->iso_frame_desc[frame].status)); -break ; - } - numbytes = urb->iso_frame_desc[frame].actual_length; -if (unlikely (numbytes >BAS_MAXFRAME )) { +if (unlikely (numbytes >BAS_MAXFRAME ))dev_warn (cs->dev,"isochronous read: frame %d: " "numbytes (%d) > BAS_MAXFRAME\n" , frame, numbytes); -break ; - }if (unlikely (numbytes > totleft)) {dev_warn (cs->dev,"isochronous read: frame %d: " "numbytes (%d) > totleft (%d)\n" , frame, numbytes, totleft); -break ; + numbytes = totleft; } offset = urb->iso_frame_desc[frame].offset;if (unlikely (offset + numbytes >BAS_INBUFSIZE )) {
@@ -1361,7 +1357,7 @@ static void read_iso_tasklet(unsigned long data)"offset (%d) + numbytes (%d) " "> BAS_INBUFSIZE\n" , frame, offset, numbytes); -break ; + numbytes =BAS_INBUFSIZE - offset; }gigaset_isoc_receive (rcvbuf + offset, numbytes, bcs); totleft -= numbytes;
Signature · 1 line
1.6.2.1.214.ge986c
RFC PATCH 3/6 gigaset: add kerneldoc comments
In reply to Tilman SchmidtAdd kerneldoc comments to some functions in the Gigaset driver.
Impact: documentation
--- drivers/isdn/gigaset/asyncdata.c | 23 +++++-- drivers/isdn/gigaset/common.c | 126 +++++++++++++++++++++++++++++++------- drivers/isdn/gigaset/ev-layer.c | 9 ++- drivers/isdn/gigaset/i4l.c | 17 +++++ drivers/isdn/gigaset/interface.c | 9 +++ 5 files changed, 153 insertions(+), 31 deletions(-)
drivers/isdn/gigaset/asyncdata.c +16 -7
@@ -334,7 +334,14 @@ static inline int iraw_loop(unsigned char c, unsigned char *src, int numbytes,return startbytes - numbytes; } -/* process a block of data received from the device +/** +* gigaset_m10x_input() - process a block of data received from the device +* @inbuf: received data and device descriptor structure. +* +* Called by hardware module {ser,usb}_gigaset with a block of received +* bytes. Separates the bytes received over the serial data channel into +* user data and command replies (locked/unlocked) according to the +* current state of the interface. */ void gigaset_m10x_input (struct inbuf_t *inbuf) {
@@ -543,12 +550,14 @@ static struct sk_buff *iraw_encode(struct sk_buff *skb, int head, int tail)return iraw_skb; } -/* gigaset_send_skb -* called by common.c to queue an skb for sending -* and start transmission if necessary -* parameters: -* B Channel control structure -* skb +/** +* gigaset_send_skb() - queue an skb for sending +* @bcs: B channel descriptor structure. +* @skb: data to send. +* +* Called by common.c to encode and queue an skb for sending, and start +* transmission if necessary. +* * Return value: * number of bytes accepted for sending * (skb->len if ok, 0 if out of buffer space)
drivers/isdn/gigaset/common.c +104 -22
196 lines not on this page · raw message
drivers/isdn/gigaset/ev-layer.c +7 -2
@@ -474,8 +474,13 @@ static int cid_of_response(char *s)//FIXME is ;<digit>+ at end of non-CID response really impossible? } -/* This function will be called via task queue from the callback handler. -* We received a modem response and have to handle it.. +/** +* gigaset_handle_modem_response() - process received modem response +* @cs: device descriptor structure. +* +* Called by asyncdata/isocdata if a block of data received from the +* device must be processed as a modem command response. The data is +* already in the cs structure. */ void gigaset_handle_modem_response (struct cardstate *cs) {
drivers/isdn/gigaset/i4l.c +17 -0
@@ -79,6 +79,14 @@ static int writebuf_from_LL(int driverID, int channel, int ack,return cs->ops->send_skb (bcs, skb); } +/** +* gigaset_skb_sent() - acknowledge sending an skb +* @bcs: B channel descriptor structure. +* @skb: sent data. +* +* Called by hardware module {bas,ser,usb}_gigaset when the data in a +* skb has been successfully sent, for signalling completion to the LL. +*/ void gigaset_skb_sent (struct bc_state *bcs,struct sk_buff *skb) {unsigned len;
@@ -455,6 +463,15 @@ int gigaset_isdn_setup_accept(struct at_state_t *at_state)return 0 ; } +/** +* gigaset_isdn_icall() - signal incoming call +* @at_state: connection state structure. +* +* Called by main module to notify the LL that an incoming call has been +* received. @at_state contains the parameters of the call. +* +* Return value: call disposition (ICALL_*) +*/ int gigaset_isdn_icall (struct at_state_t *at_state) {struct cardstate *cs = at_state->cs;
drivers/isdn/gigaset/interface.c +9 -0
@@ -616,6 +616,15 @@ void gigaset_if_free(struct cardstate *cs)tty_unregister_device (drv->tty, cs->minor_index); } +/** +* gigaset_if_receive() - pass a received block of data to the tty device +* @cs: device descriptor structure. +* @buffer: received data. +* @len: number of bytes received. +* +* Called by asyncdata/isocdata if a block of data received from the +* device must be sent to userspace through the ttyG* device. +*/ void gigaset_if_receive (struct cardstate *cs,unsigned char *buffer,size_t len) {
Signature · 1 line
1.6.2.1.214.ge986c
RFC PATCH 4/6 gigaset: prepare for CAPI implementation
In reply to Tilman SchmidtMove all isdn4linux dependencies to i4l.c so that we can develop a replacement file capi.c interfacing to Kernel CAPI instead.
Impact: refactoring, no functional change
--- drivers/isdn/gigaset/asyncdata.c | 116 ++++----- drivers/isdn/gigaset/bas-gigaset.c | 4 +- drivers/isdn/gigaset/common.c | 50 ++-- drivers/isdn/gigaset/ev-layer.c | 63 +++-- drivers/isdn/gigaset/gigaset.h | 90 ++----- drivers/isdn/gigaset/i4l.c | 499 +++++++++++++++++++++--------------- drivers/isdn/gigaset/isocdata.c | 99 ++++---- 7 files changed, 489 insertions(+), 432 deletions(-)
drivers/isdn/gigaset/asyncdata.c +52 -64
@@ -119,8 +119,6 @@ static inline int hdlc_loop(unsigned char c, unsigned char *src, int numbytes,int inputstate = bcs->inputstate;__u16 fcs = bcs->fcs;struct sk_buff *skb = bcs->skb; -unsigned char error; -struct sk_buff *compskb;int startbytes = numbytes;int l;
@@ -158,8 +156,8 @@ byte_stuff:#endif /* end of frame */ - error =1 ; -gigaset_rcv_error (NULL , cs, bcs); +gigaset_isdn_rcv_err (bcs); +dev_kfree_skb (skb); }else if (!(inputstate & INS_have_data)) {/* 7E 7E */ #ifdef CONFIG_GIGASET_DEBUG ++bcs->emptycount;
@@ -170,50 +168,34 @@ byte_stuff: "7e----------------------------");/* end of frame */ - error =0 ; -if (unlikely (fcs !=PPP_GOODFCS )) {dev_err (cs->dev,"Checksum failed, %u bytes corrupted!\n" , skb->len); - compskb =NULL ; -gigaset_rcv_error (compskb, cs, bcs); - error =1 ; +gigaset_isdn_rcv_err (bcs); +dev_kfree_skb (skb); + }else if (likely ((l = skb->len) >2 )) { +__skb_trim (skb, l-2 ); +gigaset_skb_rcvd (bcs, skb); }else { -if (likely ((l = skb->len) >2 )) { - skb->tail -=2 ; - skb->len -=2 ; - }else { -dev_kfree_skb (skb); - skb =NULL ; - inputstate |= INS_skip_frame; -if (l ==1 ) { -dev_err (cs->dev, -"invalid packet size (1)!\n" ); - error =1 ; -gigaset_rcv_error (NULL , - cs, bcs); - } - } -if (likely (!(error || - (inputstate & - INS_skip_frame)))) { -gigaset_rcv_skb (skb, cs, bcs); +if (l) { +dev_err (cs->dev, +"invalid packet size (%d)\n" , l); +gigaset_isdn_rcv_err (bcs); } +dev_kfree_skb (skb); } } -if (unlikely (error)) -if (skb) -dev_kfree_skb (skb); - fcs =PPP_INITFCS ; inputstate &= ~(INS_have_data | INS_skip_frame);if (unlikely (bcs->ignore)) { inputstate |= INS_skip_frame; skb =NULL ; - }else if (likely ((skb =dev_alloc_skb (SBUFSIZE +HW_HDR_LEN )) !=NULL )) { -skb_reserve (skb,HW_HDR_LEN ); + }else if ((skb = +dev_alloc_skb (SBUFSIZE + cs->hw_hdr_len)) + !=NULL ) { +skb_reserve (skb, cs->hw_hdr_len); }else {dev_warn (cs->dev,"could not allocate new skb\n" );
@@ -314,15 +296,15 @@ static inline int iraw_loop(unsigned char c, unsigned char *src, int numbytes,/* pass data up */ if (likely (inputstate & INS_have_data)) {if (likely (!(inputstate & INS_skip_frame))) { -gigaset_rcv_skb (skb, cs, bcs); +gigaset_skb_rcvd (bcs, skb); } inputstate &= ~(INS_have_data | INS_skip_frame);if (unlikely (bcs->ignore)) { inputstate |= INS_skip_frame; skb =NULL ; - }else if (likely ((skb =dev_alloc_skb (SBUFSIZE +HW_HDR_LEN )) - !=NULL )) { -skb_reserve (skb,HW_HDR_LEN ); + }else if ((skb =dev_alloc_skb (SBUFSIZE + cs->hw_hdr_len)) + !=NULL ) { +skb_reserve (skb, cs->hw_hdr_len); }else {dev_warn (cs->dev,"could not allocate new skb\n" ); inputstate |= INS_skip_frame;
@@ -383,7 +365,7 @@ void gigaset_m10x_input(struct inbuf_t *inbuf)/* FIXME use function pointers? */ if (inbuf->inputstate & INS_command) procbytes =cmd_loop (c, src, numbytes, inbuf); -else if (inbuf->bcs->proto2 ==ISDN_PROTO_L2_HDLC ) +else if (inbuf->bcs->proto2 ==L2_HDLC ) procbytes =hdlc_loop (c, src, numbytes, inbuf);else procbytes =iraw_loop (c, src, numbytes, inbuf);
@@ -440,16 +422,16 @@ EXPORT_SYMBOL_GPL(gigaset_m10x_input);/* == data output ========================================================== */ -/* Encoding of a PPP packet into an octet stuffed HDLC frame -* with FCS, opening and closing flags. +/* +* Encode a data packet into an octet stuffed HDLC frame with FCS, +* opening and closing flags, preserving headroom data. * parameters: -* skb skb containing original packet (freed upon return) -* head number of headroom bytes to allocate in result skb -* tail number of tailroom bytes to allocate in result skb +* 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 */ -static struct sk_buff *HDLC_Encode (struct sk_buff *skb,int head,int tail) +static struct sk_buff *HDLC_Encode (struct sk_buff *skb,int headroom) {struct sk_buff *hdlc_skb;__u16 fcs;
@@ -471,16 +453,17 @@ static struct sk_buff *HDLC_Encode(struct sk_buff *skb, int head, int tail)/* 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 */ - hdlc_skb =dev_alloc_skb (skb->len + stuf_cnt +6 + tail + head); + hdlc_skb =dev_alloc_skb (skb->len + stuf_cnt +6 + headroom);if (!hdlc_skb) {dev_kfree_skb (skb);return NULL ; } -skb_reserve (hdlc_skb, head); -/* Copy acknowledge request into new skb */ -memcpy (hdlc_skb->head, skb->head,2 ); +/* Copy acknowledgement header into new skb */ +skb_reserve (hdlc_skb, headroom); +memcpy (hdlc_skb->head, skb->head, headroom);/* Add flag sequence in front of everything.. */ *(skb_put (hdlc_skb,1 )) =PPP_FLAG ;
@@ -515,15 +498,16 @@ static struct sk_buff *HDLC_Encode(struct sk_buff *skb, int head, int tail)return hdlc_skb; } -/* Encoding of a raw packet into an octet stuffed bit inverted frame +/* +* Encode a data packet into an octet stuffed raw bit inverted frame, +* preserving headroom data. * parameters: -* skb skb containing original packet (freed upon return) -* head number of headroom bytes to allocate in result skb -* tail number of tailroom bytes to allocate in result skb +* 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 */ -static struct sk_buff *iraw_encode (struct sk_buff *skb,int head,int tail) +static struct sk_buff *iraw_encode (struct sk_buff *skb,int headroom) {struct sk_buff *iraw_skb;unsigned char c;
@@ -531,12 +515,15 @@ static struct sk_buff *iraw_encode(struct sk_buff *skb, int head, int tail)int len;/* worst case: every byte must be stuffed */ - iraw_skb =dev_alloc_skb (2 *skb->len + tail + head); + iraw_skb =dev_alloc_skb (2 *skb->len + headroom);if (!iraw_skb) {dev_kfree_skb (skb);return NULL ; } -skb_reserve (iraw_skb, head); + +/* Copy acknowledgement header into new skb */ +skb_reserve (iraw_skb, headroom); +memcpy (iraw_skb->head, skb->head, headroom); cp = skb->data; len = skb->len;
@@ -551,27 +538,28 @@ static struct sk_buff *iraw_encode(struct sk_buff *skb, int head, int tail) }/** -* gigaset_send_skb() - queue an skb for sending +* gigaset_m10x_send_skb() - queue an skb for sending * @bcs: B channel descriptor structure. * @skb: data to send. * -* Called by common.c to encode and queue an skb for sending, and start +* 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. * * Return value: -* number of bytes accepted for sending -* (skb->len if ok, 0 if out of buffer space) -* or error code (< 0, eg. -EINVAL) +* number of bytes accepted for sending (skb->len) if ok, +* error code < 0 (eg. -ENOMEM) on error */ int gigaset_m10x_send_skb (struct bc_state *bcs,struct sk_buff *skb) {unsigned len = skb->len;unsigned long flags; -if (bcs->proto2 ==ISDN_PROTO_L2_HDLC ) - skb =HDLC_Encode (skb,HW_HDR_LEN ,0 ); +if (bcs->proto2 ==L2_HDLC ) + skb =HDLC_Encode (skb, bcs->cs->hw_hdr_len);else - skb =iraw_encode (skb,HW_HDR_LEN ,0 ); + skb =iraw_encode (skb, bcs->cs->hw_hdr_len);if (!skb) {dev_err (bcs->cs->dev,"unable to allocate memory for encoding!\n" );
drivers/isdn/gigaset/bas-gigaset.c +2 -2
@@ -907,7 +907,7 @@ static int starturbs(struct bc_state *bcs)int rc;/* initialize L2 reception */ -if (bcs->proto2 ==ISDN_PROTO_L2_HDLC ) +if (bcs->proto2 ==L2_HDLC ) bcs->inputstate |= INS_flag_hunt;/* submit all isochronous input URBs */
@@ -1060,7 +1060,7 @@ static int submit_iso_write_urb(struct isow_urbctx_t *ucx)"%s: buffer busy at frame %d" , __func__, nframe);/* tasklet will be restarted from -gigaset_send_skb() */ +gigaset_isoc_send_skb() */ }else { dev_err(ucx->bcs->cs->dev, "%s: buffer error %d at frame %d\n",
drivers/isdn/gigaset/common.c +29 -21
105 lines not on this page · raw message
drivers/isdn/gigaset/ev-layer.c +35 -28
159 lines not on this page · raw message
drivers/isdn/gigaset/gigaset.h +27 -63
167 lines not on this page · raw message
drivers/isdn/gigaset/i4l.c +294 -205
657 lines not on this page · raw message
drivers/isdn/gigaset/isocdata.c +50 -49
186 lines not on this page · raw message
Signature · 1 line
1.6.2.1.214.ge986c
RFC PATCH 5/6 gigaset: allow building without I4L
In reply to Tilman SchmidtAdd a dummy LL interface to the Gigaset driver so that it can be built and, in a limited way, used without the ISDN4Linux subsystem.
Impact: new configuration alternative
--- drivers/isdn/gigaset/Kconfig | 13 +++++++- drivers/isdn/gigaset/Makefile | 4 ++- drivers/isdn/gigaset/dummyll.c | 68 ++++++++++++++++++++++++++++++++++++++++ 3 files changed, 83 insertions(+), 2 deletions(-) create mode 100644 drivers/isdn/gigaset/dummyll.c
drivers/isdn/gigaset/Kconfig +12 -1
@@ -1,6 +1,5 @@ menuconfig ISDN_DRV_GIGASET tristate "Siemens Gigaset support" - depends on ISDN_I4L select CRC_CCITT select BITREVERSE help
@@ -11,9 +10,21 @@ menuconfig ISDN_DRV_GIGASET If you have one of these devices, say M here and for at least one of the connection specific parts that follow. This will build a module called "gigaset". + Note: If you build the ISDN4Linux subsystem (ISDN_I4L) + as a module, you have to build this driver as a module too, + otherwise the Gigaset device won't show up as an ISDN device. if ISDN_DRV_GIGASET +config GIGASET_I4L + bool + depends on ISDN_I4L='y'||(ISDN_I4L='m'&&ISDN_DRV_GIGASET='m') + default y + +config GIGASET_DUMMYLL + bool + default !GIGASET_I4L + config GIGASET_BASE tristate "Gigaset base station support" depends on USB
drivers/isdn/gigaset/Makefile +3 -1
@@ -1,4 +1,6 @@ -gigaset-y := common.o interface.o proc.o ev-layer.o i4l.o asyncdata.o +gigaset-y := common.o interface.o proc.o ev-layer.o asyncdata.o +gigaset-$(CONFIG_GIGASET_I4L) += i4l.o +gigaset-$(CONFIG_GIGASET_DUMMYLL) += dummyll.o usb_gigaset-y := usb-gigaset.o ser_gigaset-y := ser-gigaset.o bas_gigaset-y := bas-gigaset.o isocdata.o
drivers/isdn/gigaset/dummyll.c new file +68 -0
68 lines not on this page · raw message
Signature · 1 line
1.6.2.1.214.ge986c
RFC PATCH 6/6 gigaset: add Kernel CAPI interface
In reply to Tilman SchmidtAdd a Kernel CAPI interface to the Gigaset driver.
Impact: new functionality
--- drivers/isdn/gigaset/Kconfig | 18 +- drivers/isdn/gigaset/Makefile | 1 + drivers/isdn/gigaset/capi.c | 1855 +++++++++++++++++++++++++++++++++++++++ drivers/isdn/gigaset/common.c | 19 + drivers/isdn/gigaset/ev-layer.c | 26 +- drivers/isdn/gigaset/gigaset.h | 7 +- 6 files changed, 1910 insertions(+), 16 deletions(-) create mode 100644 drivers/isdn/gigaset/capi.c
drivers/isdn/gigaset/Kconfig +15 -3
@@ -10,20 +10,32 @@ menuconfig ISDN_DRV_GIGASET If you have one of these devices, say M here and for at least one of the connection specific parts that follow. This will build a module called "gigaset". - Note: If you build the ISDN4Linux subsystem (ISDN_I4L) + Note: If you build your ISDN subsystem (ISDN_CAPI or ISDN_I4L) as a module, you have to build this driver as a module too, otherwise the Gigaset device won't show up as an ISDN device. if ISDN_DRV_GIGASET +config GIGASET_CAPI + bool "Gigaset CAPI support (EXPERIMENTAL)" + depends on EXPERIMENTAL + depends on ISDN_CAPI='y'||(ISDN_CAPI='m'&&ISDN_DRV_GIGASET='m') + default ISDN_I4L='n' + help + Build the Gigaset driver as a CAPI 2.0 driver interfacing with + the Kernel CAPI subsystem. To use it with the old ISDN4Linux + subsystem you'll have to enable the capidrv glue driver. + (select ISDN_CAPI_CAPIDRV.) + Say N to build the old native ISDN4Linux variant. + config GIGASET_I4L bool depends on ISDN_I4L='y'||(ISDN_I4L='m'&&ISDN_DRV_GIGASET='m') - default y + default !GIGASET_CAPI config GIGASET_DUMMYLL bool - default !GIGASET_I4L + default !GIGASET_CAPI&&!GIGASET_I4L config GIGASET_BASE tristate "Gigaset base station support"
drivers/isdn/gigaset/Makefile +1 -0
@@ -1,4 +1,5 @@ gigaset-y := common.o interface.o proc.o ev-layer.o asyncdata.o +gigaset-$(CONFIG_GIGASET_CAPI) += capi.o gigaset-$(CONFIG_GIGASET_I4L) += i4l.o gigaset-$(CONFIG_GIGASET_DUMMYLL) += dummyll.o usb_gigaset-y := usb-gigaset.o
drivers/isdn/gigaset/capi.c new file +1855 -0
1,855 lines not on this page · raw message
drivers/isdn/gigaset/common.c +19 -0
@@ -207,6 +207,25 @@ int gigaset_get_channel(struct bc_state *bcs)return 1 ; } +struct bc_state *gigaset_get_free_channel (struct cardstate *cs) +{ +unsigned long flags; +int i; + +spin_lock_irqsave (&cs->lock, flags); +for (i =0 ; i < cs->channels; ++i) +if (!cs->bcs[i].use_count) { + ++cs->bcs[i].use_count; + cs->bcs[i].busy =1 ; +spin_unlock_irqrestore (&cs->lock, flags); +gig_dbg (DEBUG_ANY ,"allocated channel %d" , i); +return cs->bcs + i; + } +spin_unlock_irqrestore (&cs->lock, flags); +gig_dbg (DEBUG_ANY ,"no free channel" ); +return NULL ; +} +void gigaset_free_channel (struct bc_state *bcs) {unsigned long flags;
drivers/isdn/gigaset/ev-layer.c +14 -12
@@ -291,21 +291,23 @@ struct reply_t gigaset_tab_cid[] = {RSP_OK, 602,602, -1, 603, 5, {ACT_CMD+AT_PROTO}}, {RSP_OK, 603,603, -1, 604, 5, {ACT_CMD+AT_TYPE}}, {RSP_OK, 604,604, -1, 605, 5, {ACT_CMD+AT_MSN}}, - {RSP_OK, 605,605, -1, 606, 5, {ACT_CMD+AT_ISO}}, - {RSP_NULL, 605,605, -1, 606, 5, {ACT_CMD+AT_ISO}}, - {RSP_OK, 606,606, -1, 607, 5, {0}, "+VLS=17\r"}, - {RSP_OK, 607,607, -1, 608,-1}, - {RSP_ZSAU, 608,608,ZSAU_PROCEEDING, 609, 5, {ACT_CMD+AT_DIAL}}, - {RSP_OK, 609,609, -1, 650, 0, {ACT_DIALING}}, - - {RSP_ERROR, 601,609, -1, 0, 0, {ACT_ABORTDIAL}}, - {EV_TIMEOUT, 601,609, -1, 0, 0, {ACT_ABORTDIAL}}, + {RSP_NULL, 605,605, -1, 606, 5, {ACT_CMD+AT_CLIP}}, + {RSP_OK, 605,605, -1, 606, 5, {ACT_CMD+AT_CLIP}}, + {RSP_NULL, 606,606, -1, 607, 5, {ACT_CMD+AT_ISO}}, + {RSP_OK, 606,606, -1, 607, 5, {ACT_CMD+AT_ISO}}, + {RSP_OK, 607,607, -1, 608, 5, {0}, "+VLS=17\r"}, + {RSP_OK, 608,608, -1, 609,-1}, + {RSP_ZSAU, 609,609,ZSAU_PROCEEDING, 610, 5, {ACT_CMD+AT_DIAL}}, + {RSP_OK, 610,610, -1, 650, 0, {ACT_DIALING}}, + + {RSP_ERROR, 601,610, -1, 0, 0, {ACT_ABORTDIAL}}, + {EV_TIMEOUT, 601,610, -1, 0, 0, {ACT_ABORTDIAL}},/* optional dialing responses */ {EV_BC_OPEN, 650,650, -1, 651,-1}, - {RSP_ZVLS, 608,651, 17, -1,-1, {ACT_DEBUG}}, - {RSP_ZCTP, 609,651, -1, -1,-1, {ACT_DEBUG}}, - {RSP_ZCPN, 609,651, -1, -1,-1, {ACT_DEBUG}}, + {RSP_ZVLS, 609,651, 17, -1,-1, {ACT_DEBUG}}, + {RSP_ZCTP, 610,651, -1, -1,-1, {ACT_DEBUG}}, + {RSP_ZCPN, 610,651, -1, -1,-1, {ACT_DEBUG}}, {RSP_ZSAU, 650,651,ZSAU_CALL_DELIVERED, -1,-1, {ACT_DEBUG}}, /* connect */
drivers/isdn/gigaset/gigaset.h +6 -1
@@ -191,7 +191,9 @@ void gigaset_dbg_buffer(enum debuglevel level, const unsigned char *msg,#define AT_PROTO 4#define AT_TYPE 5#define AT_HLC 6 -#define AT_NUM 7 +#define AT_CLIP 7 +/* total number */ +#define AT_NUM 8/* variables in struct at_state_t */ #define VAR_ZSAU 0
@@ -412,6 +414,8 @@ struct bc_state {struct usb_bc_state *usb;/* usb hardware driver (m105) */ struct bas_bc_state *bas;/* usb hardware driver (base) */ } hw; + +void *ap;/* LL application structure */ };struct cardstate {
@@ -725,6 +729,7 @@ void gigaset_bcs_reinit(struct bc_state *bcs);void gigaset_at_init (struct at_state_t *at_state,struct bc_state *bcs,struct cardstate *cs,int cid);int gigaset_get_channel (struct bc_state *bcs); +struct bc_state *gigaset_get_free_channel (struct cardstate *cs);void gigaset_free_channel (struct bc_state *bcs);int gigaset_get_channels (struct cardstate *cs);void gigaset_free_channels (struct cardstate *cs);
Signature · 1 line
1.6.2.1.214.ge986c
David Miller
maintainerFrom: Tilman Schmidt <[email protected]>
Date: Fri, 21 Aug 2009 19:21:34 +0200 (CEST)
Quoted 6 lines
the following set of six patches adds a configuration option to the Gigaset driver to interface to Kernel CAPI instead of the old ISDN4Linux subsystem. Although my unit test are not quite done yet I would appreciate comments.
From my nieve perspective these changes look good, I hope
the ISDN folks look at them soon :-)