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>
17 #include <linux/bitrev.h>
20 static inline void B_L1L2(struct st5481_bcs
*bcs
, int pr
, void *arg
)
22 struct hisax_if
*ifc
= (struct hisax_if
*) &bcs
->b_if
;
24 ifc
->l1l2(ifc
, pr
, arg
);
28 * Encode and transmit next frame.
30 static void usb_b_out(struct st5481_bcs
*bcs
,int buf_nr
)
32 struct st5481_b_out
*b_out
= &bcs
->b_out
;
33 struct st5481_adapter
*adapter
= bcs
->adapter
;
35 unsigned int packet_size
,offset
;
36 int len
,buf_size
,bytes_sent
;
40 if (test_and_set_bit(buf_nr
, &b_out
->busy
)) {
41 DBG(4,"ep %d urb %d busy",(bcs
->channel
+1)*2,buf_nr
);
44 urb
= b_out
->urb
[buf_nr
];
46 // Adjust isoc buffer size according to flow state
47 if(b_out
->flow_event
& (OUT_DOWN
| OUT_UNDERRUN
)) {
48 buf_size
= NUM_ISO_PACKETS_B
*SIZE_ISO_PACKETS_B_OUT
+ B_FLOW_ADJUST
;
49 packet_size
= SIZE_ISO_PACKETS_B_OUT
+ B_FLOW_ADJUST
;
50 DBG(4,"B%d,adjust flow,add %d bytes",bcs
->channel
+1,B_FLOW_ADJUST
);
51 } else if(b_out
->flow_event
& OUT_UP
){
52 buf_size
= NUM_ISO_PACKETS_B
*SIZE_ISO_PACKETS_B_OUT
- B_FLOW_ADJUST
;
53 packet_size
= SIZE_ISO_PACKETS_B_OUT
- B_FLOW_ADJUST
;
54 DBG(4,"B%d,adjust flow,remove %d bytes",bcs
->channel
+1,B_FLOW_ADJUST
);
56 buf_size
= NUM_ISO_PACKETS_B
*SIZE_ISO_PACKETS_B_OUT
;
59 b_out
->flow_event
= 0;
62 while (len
< buf_size
) {
63 if ((skb
= b_out
->tx_skb
)) {
65 DBG(4,"B%d,len=%d",bcs
->channel
+1,skb
->len
);
67 if (bcs
->mode
== L1_MODE_TRANS
) {
68 bytes_sent
= buf_size
- len
;
69 if (skb
->len
< bytes_sent
)
70 bytes_sent
= skb
->len
;
71 { /* swap tx bytes to get hearable audio data */
72 register unsigned char *src
= skb
->data
;
73 register unsigned char *dest
= urb
->transfer_buffer
+len
;
74 register unsigned int count
;
75 for (count
= 0; count
< bytes_sent
; count
++)
76 *dest
++ = bitrev8(*src
++);
80 len
+= isdnhdlc_encode(&b_out
->hdlc_state
,
81 skb
->data
, skb
->len
, &bytes_sent
,
82 urb
->transfer_buffer
+len
, buf_size
-len
);
85 skb_pull(skb
, bytes_sent
);
90 B_L1L2(bcs
, PH_DATA
| CONFIRM
, (void *)(unsigned long) skb
->truesize
);
91 dev_kfree_skb_any(skb
);
93 /* if (!(bcs->tx_skb = skb_dequeue(&bcs->sq))) { */
94 /* st5481B_sched_event(bcs, B_XMTBUFREADY); */
98 if (bcs
->mode
== L1_MODE_TRANS
) {
99 memset(urb
->transfer_buffer
+len
, 0xff, buf_size
-len
);
103 len
+= isdnhdlc_encode(&b_out
->hdlc_state
,
104 NULL
, 0, &bytes_sent
,
105 urb
->transfer_buffer
+len
, buf_size
-len
);
111 for (i
= 0, offset
= 0; offset
< len
; i
++) {
112 urb
->iso_frame_desc
[i
].offset
= offset
;
113 urb
->iso_frame_desc
[i
].length
= packet_size
;
114 offset
+= packet_size
;
115 packet_size
= SIZE_ISO_PACKETS_B_OUT
;
117 urb
->transfer_buffer_length
= len
;
118 urb
->number_of_packets
= i
;
119 urb
->dev
= adapter
->usb_dev
;
121 DBG_ISO_PACKET(0x200,urb
);
123 SUBMIT_URB(urb
, GFP_NOIO
);
127 * Start transfering (flags or data) on the B channel, since
128 * FIFO counters has been set to a non-zero value.
130 static void st5481B_start_xfer(void *context
)
132 struct st5481_bcs
*bcs
= context
;
134 DBG(4,"B%d",bcs
->channel
+1);
136 // Start transmitting (flags or data) on B channel
143 * If the adapter has only 2 LEDs, the green
144 * LED will blink with a rate depending
145 * on the number of channels opened.
147 static void led_blink(struct st5481_adapter
*adapter
)
149 u_char leds
= adapter
->leds
;
151 // 50 frames/sec for each channel
152 if (++adapter
->led_counter
% 50) {
156 if (adapter
->led_counter
% 100) {
162 st5481_usb_device_ctrl_msg(adapter
, GPIO_OUT
, leds
, NULL
, NULL
);
165 static void usb_b_out_complete(struct urb
*urb
)
167 struct st5481_bcs
*bcs
= urb
->context
;
168 struct st5481_b_out
*b_out
= &bcs
->b_out
;
169 struct st5481_adapter
*adapter
= bcs
->adapter
;
172 buf_nr
= get_buf_nr(b_out
->urb
, urb
);
173 test_and_clear_bit(buf_nr
, &b_out
->busy
);
175 if (unlikely(urb
->status
< 0)) {
176 switch (urb
->status
) {
180 DBG(4,"urb killed status %d", urb
->status
);
183 WARN("urb status %d",urb
->status
);
184 if (b_out
->busy
== 0) {
185 st5481_usb_pipe_reset(adapter
, (bcs
->channel
+1)*2 | USB_DIR_OUT
, NULL
, NULL
);
191 usb_b_out(bcs
,buf_nr
);
193 if (adapter
->number_of_leds
== 2)
198 * Start or stop the transfer on the B channel.
200 static void st5481B_mode(struct st5481_bcs
*bcs
, int mode
)
202 struct st5481_b_out
*b_out
= &bcs
->b_out
;
203 struct st5481_adapter
*adapter
= bcs
->adapter
;
205 DBG(4,"B%d,mode=%d", bcs
->channel
+ 1, mode
);
207 if (bcs
->mode
== mode
)
212 // Cancel all USB transfers on this B channel
213 usb_unlink_urb(b_out
->urb
[0]);
214 usb_unlink_urb(b_out
->urb
[1]);
217 st5481_in_mode(&bcs
->b_in
, mode
);
218 if (bcs
->mode
!= L1_MODE_NULL
) {
219 // Open the B channel
220 if (bcs
->mode
!= L1_MODE_TRANS
) {
221 isdnhdlc_out_init(&b_out
->hdlc_state
, 0, bcs
->mode
== L1_MODE_HDLC_56K
);
223 st5481_usb_pipe_reset(adapter
, (bcs
->channel
+1)*2, NULL
, NULL
);
225 // Enable B channel interrupts
226 st5481_usb_device_ctrl_msg(adapter
, FFMSK_B1
+(bcs
->channel
*2),
227 OUT_UP
+OUT_DOWN
+OUT_UNDERRUN
, NULL
, NULL
);
229 // Enable B channel FIFOs
230 st5481_usb_device_ctrl_msg(adapter
, OUT_B1_COUNTER
+(bcs
->channel
*2), 32, st5481B_start_xfer
, bcs
);
231 if (adapter
->number_of_leds
== 4) {
232 if (bcs
->channel
== 0) {
233 adapter
->leds
|= B1_LED
;
235 adapter
->leds
|= B2_LED
;
239 // Disble B channel interrupts
240 st5481_usb_device_ctrl_msg(adapter
, FFMSK_B1
+(bcs
->channel
*2), 0, NULL
, NULL
);
242 // Disable B channel FIFOs
243 st5481_usb_device_ctrl_msg(adapter
, OUT_B1_COUNTER
+(bcs
->channel
*2), 0, NULL
, NULL
);
245 if (adapter
->number_of_leds
== 4) {
246 if (bcs
->channel
== 0) {
247 adapter
->leds
&= ~B1_LED
;
249 adapter
->leds
&= ~B2_LED
;
252 st5481_usb_device_ctrl_msg(adapter
, GPIO_OUT
, adapter
->leds
, NULL
, NULL
);
255 dev_kfree_skb_any(b_out
->tx_skb
);
256 b_out
->tx_skb
= NULL
;
262 static int st5481_setup_b_out(struct st5481_bcs
*bcs
)
264 struct usb_device
*dev
= bcs
->adapter
->usb_dev
;
265 struct usb_interface
*intf
;
266 struct usb_host_interface
*altsetting
= NULL
;
267 struct usb_host_endpoint
*endpoint
;
268 struct st5481_b_out
*b_out
= &bcs
->b_out
;
272 intf
= usb_ifnum_to_if(dev
, 0);
274 altsetting
= usb_altnum_to_altsetting(intf
, 3);
278 // Allocate URBs and buffers for the B channel out
279 endpoint
= &altsetting
->endpoint
[EP_B1_OUT
- 1 + bcs
->channel
* 2];
281 DBG(4,"endpoint address=%02x,packet size=%d",
282 endpoint
->desc
.bEndpointAddress
, le16_to_cpu(endpoint
->desc
.wMaxPacketSize
));
284 // Allocate memory for 8000bytes/sec + extra bytes if underrun
285 return st5481_setup_isocpipes(b_out
->urb
, dev
,
286 usb_sndisocpipe(dev
, endpoint
->desc
.bEndpointAddress
),
287 NUM_ISO_PACKETS_B
, SIZE_ISO_PACKETS_B_OUT
,
288 NUM_ISO_PACKETS_B
* SIZE_ISO_PACKETS_B_OUT
+ B_FLOW_ADJUST
,
289 usb_b_out_complete
, bcs
);
292 static void st5481_release_b_out(struct st5481_bcs
*bcs
)
294 struct st5481_b_out
*b_out
= &bcs
->b_out
;
298 st5481_release_isocpipes(b_out
->urb
);
301 int st5481_setup_b(struct st5481_bcs
*bcs
)
307 retval
= st5481_setup_b_out(bcs
);
310 bcs
->b_in
.bufsize
= HSCX_BUFMAX
;
311 bcs
->b_in
.num_packets
= NUM_ISO_PACKETS_B
;
312 bcs
->b_in
.packet_size
= SIZE_ISO_PACKETS_B_IN
;
313 bcs
->b_in
.ep
= (bcs
->channel
? EP_B2_IN
: EP_B1_IN
) | USB_DIR_IN
;
314 bcs
->b_in
.counter
= bcs
->channel
? IN_B2_COUNTER
: IN_B1_COUNTER
;
315 bcs
->b_in
.adapter
= bcs
->adapter
;
316 bcs
->b_in
.hisax_if
= &bcs
->b_if
.ifc
;
317 retval
= st5481_setup_in(&bcs
->b_in
);
325 st5481_release_b_out(bcs
);
331 * Release buffers and URBs for the B channels
333 void st5481_release_b(struct st5481_bcs
*bcs
)
337 st5481_release_in(&bcs
->b_in
);
338 st5481_release_b_out(bcs
);
342 * st5481_b_l2l1 is the entry point for upper layer routines that want to
343 * transmit on the B channel. PH_DATA | REQUEST is a normal packet that
344 * we either start transmitting (if idle) or queue (if busy).
345 * PH_PULL | REQUEST can be called to request a callback message
346 * (PH_PULL | CONFIRM)
347 * once the link is idle. After a "pull" callback, the upper layer
348 * routines can use PH_PULL | INDICATION to send data.
350 void st5481_b_l2l1(struct hisax_if
*ifc
, int pr
, void *arg
)
352 struct st5481_bcs
*bcs
= ifc
->priv
;
353 struct sk_buff
*skb
= arg
;
359 case PH_DATA
| REQUEST
:
360 BUG_ON(bcs
->b_out
.tx_skb
);
361 bcs
->b_out
.tx_skb
= skb
;
363 case PH_ACTIVATE
| REQUEST
:
365 DBG(4,"B%d,PH_ACTIVATE_REQUEST %ld", bcs
->channel
+ 1, mode
);
366 st5481B_mode(bcs
, mode
);
367 B_L1L2(bcs
, PH_ACTIVATE
| INDICATION
, NULL
);
369 case PH_DEACTIVATE
| REQUEST
:
370 DBG(4,"B%d,PH_DEACTIVATE_REQUEST", bcs
->channel
+ 1);
371 st5481B_mode(bcs
, L1_MODE_NULL
);
372 B_L1L2(bcs
, PH_DEACTIVATE
| INDICATION
, NULL
);
375 WARN("pr %#x\n", pr
);