2 * Driver for ST5481 USB ISDN modem
5 * Copyright 2001 by Frode Isaksen <fisaksen@bewan.com>
6 * 2001 by Kai Germaschewski <kai.germaschewski@gmx.de>
8 * This software may be used and distributed according to the terms
9 * of the GNU General Public License, incorporated herein by reference.
13 #include <linux/init.h>
14 #include <linux/usb.h>
15 #include <linux/slab.h>
16 #include <linux/netdevice.h>
19 static inline void B_L1L2(struct st5481_bcs
*bcs
, int pr
, void *arg
)
21 struct hisax_if
*ifc
= (struct hisax_if
*) &bcs
->b_if
;
23 ifc
->l1l2(ifc
, pr
, arg
);
27 * Encode and transmit next frame.
29 static void usb_b_out(struct st5481_bcs
*bcs
,int buf_nr
)
31 struct st5481_b_out
*b_out
= &bcs
->b_out
;
32 struct st5481_adapter
*adapter
= bcs
->adapter
;
34 unsigned int packet_size
,offset
;
35 int len
,buf_size
,bytes_sent
;
39 if (test_and_set_bit(buf_nr
, &b_out
->busy
)) {
40 DBG(4,"ep %d urb %d busy",(bcs
->channel
+1)*2,buf_nr
);
43 urb
= b_out
->urb
[buf_nr
];
45 // Adjust isoc buffer size according to flow state
46 if(b_out
->flow_event
& (OUT_DOWN
| OUT_UNDERRUN
)) {
47 buf_size
= NUM_ISO_PACKETS_B
*SIZE_ISO_PACKETS_B_OUT
+ B_FLOW_ADJUST
;
48 packet_size
= SIZE_ISO_PACKETS_B_OUT
+ B_FLOW_ADJUST
;
49 DBG(4,"B%d,adjust flow,add %d bytes",bcs
->channel
+1,B_FLOW_ADJUST
);
50 } else if(b_out
->flow_event
& OUT_UP
){
51 buf_size
= NUM_ISO_PACKETS_B
*SIZE_ISO_PACKETS_B_OUT
- B_FLOW_ADJUST
;
52 packet_size
= SIZE_ISO_PACKETS_B_OUT
- B_FLOW_ADJUST
;
53 DBG(4,"B%d,adjust flow,remove %d bytes",bcs
->channel
+1,B_FLOW_ADJUST
);
55 buf_size
= NUM_ISO_PACKETS_B
*SIZE_ISO_PACKETS_B_OUT
;
58 b_out
->flow_event
= 0;
61 while (len
< buf_size
) {
62 if ((skb
= b_out
->tx_skb
)) {
64 DBG(4,"B%d,len=%d",bcs
->channel
+1,skb
->len
);
66 if (bcs
->mode
== L1_MODE_TRANS
) {
67 bytes_sent
= buf_size
- len
;
68 if (skb
->len
< bytes_sent
)
69 bytes_sent
= skb
->len
;
70 { /* swap tx bytes to get hearable audio data */
71 register unsigned char *src
= skb
->data
;
72 register unsigned char *dest
= urb
->transfer_buffer
+len
;
73 register unsigned int count
;
74 for (count
= 0; count
< bytes_sent
; count
++)
75 *dest
++ = isdnhdlc_bit_rev_tab
[*src
++];
79 len
+= isdnhdlc_encode(&b_out
->hdlc_state
,
80 skb
->data
, skb
->len
, &bytes_sent
,
81 urb
->transfer_buffer
+len
, buf_size
-len
);
84 skb_pull(skb
, bytes_sent
);
89 B_L1L2(bcs
, PH_DATA
| CONFIRM
, (void *) skb
->truesize
);
90 dev_kfree_skb_any(skb
);
92 /* if (!(bcs->tx_skb = skb_dequeue(&bcs->sq))) { */
93 /* st5481B_sched_event(bcs, B_XMTBUFREADY); */
97 if (bcs
->mode
== L1_MODE_TRANS
) {
98 memset(urb
->transfer_buffer
+len
, 0xff, buf_size
-len
);
102 len
+= isdnhdlc_encode(&b_out
->hdlc_state
,
103 NULL
, 0, &bytes_sent
,
104 urb
->transfer_buffer
+len
, buf_size
-len
);
110 for (i
= 0, offset
= 0; offset
< len
; i
++) {
111 urb
->iso_frame_desc
[i
].offset
= offset
;
112 urb
->iso_frame_desc
[i
].length
= packet_size
;
113 offset
+= packet_size
;
114 packet_size
= SIZE_ISO_PACKETS_B_OUT
;
116 urb
->transfer_buffer_length
= len
;
117 urb
->number_of_packets
= i
;
118 urb
->dev
= adapter
->usb_dev
;
120 DBG_ISO_PACKET(0x200,urb
);
122 SUBMIT_URB(urb
, GFP_NOIO
);
126 * Start transfering (flags or data) on the B channel, since
127 * FIFO counters has been set to a non-zero value.
129 static void st5481B_start_xfer(void *context
)
131 struct st5481_bcs
*bcs
= context
;
133 DBG(4,"B%d",bcs
->channel
+1);
135 // Start transmitting (flags or data) on B channel
142 * If the adapter has only 2 LEDs, the green
143 * LED will blink with a rate depending
144 * on the number of channels opened.
146 static void led_blink(struct st5481_adapter
*adapter
)
148 u_char leds
= adapter
->leds
;
150 // 50 frames/sec for each channel
151 if (++adapter
->led_counter
% 50) {
155 if (adapter
->led_counter
% 100) {
161 st5481_usb_device_ctrl_msg(adapter
, GPIO_OUT
, leds
, NULL
, NULL
);
164 static void usb_b_out_complete(struct urb
*urb
, struct pt_regs
*regs
)
166 struct st5481_bcs
*bcs
= urb
->context
;
167 struct st5481_b_out
*b_out
= &bcs
->b_out
;
168 struct st5481_adapter
*adapter
= bcs
->adapter
;
171 buf_nr
= get_buf_nr(b_out
->urb
, urb
);
172 test_and_clear_bit(buf_nr
, &b_out
->busy
);
174 if (unlikely(urb
->status
< 0)) {
175 switch (urb
->status
) {
179 DBG(4,"urb killed status %d", urb
->status
);
182 WARN("urb status %d",urb
->status
);
183 if (b_out
->busy
== 0) {
184 st5481_usb_pipe_reset(adapter
, (bcs
->channel
+1)*2 | USB_DIR_OUT
, NULL
, NULL
);
190 usb_b_out(bcs
,buf_nr
);
192 if (adapter
->number_of_leds
== 2)
197 * Start or stop the transfer on the B channel.
199 static void st5481B_mode(struct st5481_bcs
*bcs
, int mode
)
201 struct st5481_b_out
*b_out
= &bcs
->b_out
;
202 struct st5481_adapter
*adapter
= bcs
->adapter
;
204 DBG(4,"B%d,mode=%d", bcs
->channel
+ 1, mode
);
206 if (bcs
->mode
== mode
)
211 // Cancel all USB transfers on this B channel
212 usb_unlink_urb(b_out
->urb
[0]);
213 usb_unlink_urb(b_out
->urb
[1]);
216 st5481_in_mode(&bcs
->b_in
, mode
);
217 if (bcs
->mode
!= L1_MODE_NULL
) {
218 // Open the B channel
219 if (bcs
->mode
!= L1_MODE_TRANS
) {
220 isdnhdlc_out_init(&b_out
->hdlc_state
, 0, bcs
->mode
== L1_MODE_HDLC_56K
);
222 st5481_usb_pipe_reset(adapter
, (bcs
->channel
+1)*2, NULL
, NULL
);
224 // Enable B channel interrupts
225 st5481_usb_device_ctrl_msg(adapter
, FFMSK_B1
+(bcs
->channel
*2),
226 OUT_UP
+OUT_DOWN
+OUT_UNDERRUN
, NULL
, NULL
);
228 // Enable B channel FIFOs
229 st5481_usb_device_ctrl_msg(adapter
, OUT_B1_COUNTER
+(bcs
->channel
*2), 32, st5481B_start_xfer
, bcs
);
230 if (adapter
->number_of_leds
== 4) {
231 if (bcs
->channel
== 0) {
232 adapter
->leds
|= B1_LED
;
234 adapter
->leds
|= B2_LED
;
238 // Disble B channel interrupts
239 st5481_usb_device_ctrl_msg(adapter
, FFMSK_B1
+(bcs
->channel
*2), 0, NULL
, NULL
);
241 // Disable B channel FIFOs
242 st5481_usb_device_ctrl_msg(adapter
, OUT_B1_COUNTER
+(bcs
->channel
*2), 0, NULL
, NULL
);
244 if (adapter
->number_of_leds
== 4) {
245 if (bcs
->channel
== 0) {
246 adapter
->leds
&= ~B1_LED
;
248 adapter
->leds
&= ~B2_LED
;
251 st5481_usb_device_ctrl_msg(adapter
, GPIO_OUT
, adapter
->leds
, NULL
, NULL
);
254 dev_kfree_skb_any(b_out
->tx_skb
);
255 b_out
->tx_skb
= NULL
;
261 static int st5481_setup_b_out(struct st5481_bcs
*bcs
)
263 struct usb_device
*dev
= bcs
->adapter
->usb_dev
;
264 struct usb_interface
*intf
;
265 struct usb_host_interface
*altsetting
= NULL
;
266 struct usb_host_endpoint
*endpoint
;
267 struct st5481_b_out
*b_out
= &bcs
->b_out
;
271 intf
= usb_ifnum_to_if(dev
, 0);
273 altsetting
= usb_altnum_to_altsetting(intf
, 3);
277 // Allocate URBs and buffers for the B channel out
278 endpoint
= &altsetting
->endpoint
[EP_B1_OUT
- 1 + bcs
->channel
* 2];
280 DBG(4,"endpoint address=%02x,packet size=%d",
281 endpoint
->desc
.bEndpointAddress
, le16_to_cpu(endpoint
->desc
.wMaxPacketSize
));
283 // Allocate memory for 8000bytes/sec + extra bytes if underrun
284 return st5481_setup_isocpipes(b_out
->urb
, dev
,
285 usb_sndisocpipe(dev
, endpoint
->desc
.bEndpointAddress
),
286 NUM_ISO_PACKETS_B
, SIZE_ISO_PACKETS_B_OUT
,
287 NUM_ISO_PACKETS_B
* SIZE_ISO_PACKETS_B_OUT
+ B_FLOW_ADJUST
,
288 usb_b_out_complete
, bcs
);
291 static void st5481_release_b_out(struct st5481_bcs
*bcs
)
293 struct st5481_b_out
*b_out
= &bcs
->b_out
;
297 st5481_release_isocpipes(b_out
->urb
);
300 int st5481_setup_b(struct st5481_bcs
*bcs
)
306 retval
= st5481_setup_b_out(bcs
);
309 bcs
->b_in
.bufsize
= HSCX_BUFMAX
;
310 bcs
->b_in
.num_packets
= NUM_ISO_PACKETS_B
;
311 bcs
->b_in
.packet_size
= SIZE_ISO_PACKETS_B_IN
;
312 bcs
->b_in
.ep
= (bcs
->channel
? EP_B2_IN
: EP_B1_IN
) | USB_DIR_IN
;
313 bcs
->b_in
.counter
= bcs
->channel
? IN_B2_COUNTER
: IN_B1_COUNTER
;
314 bcs
->b_in
.adapter
= bcs
->adapter
;
315 bcs
->b_in
.hisax_if
= &bcs
->b_if
.ifc
;
316 retval
= st5481_setup_in(&bcs
->b_in
);
324 st5481_release_b_out(bcs
);
330 * Release buffers and URBs for the B channels
332 void st5481_release_b(struct st5481_bcs
*bcs
)
336 st5481_release_in(&bcs
->b_in
);
337 st5481_release_b_out(bcs
);
341 * st5481_b_l2l1 is the entry point for upper layer routines that want to
342 * transmit on the B channel. PH_DATA | REQUEST is a normal packet that
343 * we either start transmitting (if idle) or queue (if busy).
344 * PH_PULL | REQUEST can be called to request a callback message
345 * (PH_PULL | CONFIRM)
346 * once the link is idle. After a "pull" callback, the upper layer
347 * routines can use PH_PULL | INDICATION to send data.
349 void st5481_b_l2l1(struct hisax_if
*ifc
, int pr
, void *arg
)
351 struct st5481_bcs
*bcs
= ifc
->priv
;
352 struct sk_buff
*skb
= arg
;
358 case PH_DATA
| REQUEST
:
359 if (bcs
->b_out
.tx_skb
)
362 bcs
->b_out
.tx_skb
= skb
;
364 case PH_ACTIVATE
| REQUEST
:
366 DBG(4,"B%d,PH_ACTIVATE_REQUEST %d", bcs
->channel
+ 1, mode
);
367 st5481B_mode(bcs
, mode
);
368 B_L1L2(bcs
, PH_ACTIVATE
| INDICATION
, NULL
);
370 case PH_DEACTIVATE
| REQUEST
:
371 DBG(4,"B%d,PH_DEACTIVATE_REQUEST", bcs
->channel
+ 1);
372 st5481B_mode(bcs
, L1_MODE_NULL
);
373 B_L1L2(bcs
, PH_DEACTIVATE
| INDICATION
, NULL
);
376 WARN("pr %#x\n", pr
);