aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/isdn/hisax/hfc_usb.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@ppc970.osdl.org>2005-04-16 18:20:36 -0400
committerLinus Torvalds <torvalds@ppc970.osdl.org>2005-04-16 18:20:36 -0400
commit1da177e4c3f41524e886b7f1b8a0c1fc7321cac2 (patch)
tree0bba044c4ce775e45a88a51686b5d9f90697ea9d /drivers/isdn/hisax/hfc_usb.c
Linux-2.6.12-rc2v2.6.12-rc2
Initial git repository build. I'm not bothering with the full history, even though we have it. We can create a separate "historical" git archive of that later if we want to, and in the meantime it's about 3.2GB when imported into git - space that would just make the early git days unnecessarily complicated, when we don't have a lot of good infrastructure for it. Let it rip!
Diffstat (limited to 'drivers/isdn/hisax/hfc_usb.c')
-rw-r--r--drivers/isdn/hisax/hfc_usb.c1828
1 files changed, 1828 insertions, 0 deletions
diff --git a/drivers/isdn/hisax/hfc_usb.c b/drivers/isdn/hisax/hfc_usb.c
new file mode 100644
index 000000000000..ffd74b84f502
--- /dev/null
+++ b/drivers/isdn/hisax/hfc_usb.c
@@ -0,0 +1,1828 @@
1/*
2 * hfc_usb.c
3 *
4 * $Id: hfc_usb.c,v 4.34 2005/01/26 17:25:53 martinb1 Exp $
5 *
6 * modular HiSax ISDN driver for Colognechip HFC-S USB chip
7 *
8 * Authors : Peter Sprenger (sprenger@moving-bytes.de)
9 * Martin Bachem (info@colognechip.com)
10 *
11 * based on the first hfc_usb driver of
12 * Werner Cornelius (werner@isdn-development.de)
13 *
14 * This program is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License as published by
16 * the Free Software Foundation; either version 2, or (at your option)
17 * any later version.
18 *
19 * This program is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU General Public License for more details.
23 *
24 * You should have received a copy of the GNU General Public License
25 * along with this program; if not, write to the Free Software
26 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
27 *
28 * See Version Histroy at the bottom of this file
29 *
30*/
31
32#include <linux/types.h>
33#include <linux/stddef.h>
34#include <linux/timer.h>
35#include <linux/config.h>
36#include <linux/init.h>
37#include <linux/module.h>
38#include <linux/kernel_stat.h>
39#include <linux/usb.h>
40#include <linux/kernel.h>
41#include <linux/smp_lock.h>
42#include <linux/sched.h>
43#include "hisax.h"
44#include "hisax_if.h"
45#include "hfc_usb.h"
46
47/*
48* Version Information
49* (do not modify the CVS Makros $Revision: 4.34 $ and $Date: 2005/01/26 17:25:53 $ !)
50*/
51static const char *hfcusb_revision =
52 "Revision: 4.34 $ Date: 2005/01/26 17:25:53 $ ";
53
54/* Hisax debug support
55* use "modprobe debug=x" where x is bitfield of USB_DBG & ISDN_DBG
56*/
57#ifdef CONFIG_HISAX_DEBUG
58#include <linux/moduleparam.h>
59#define __debug_variable hfc_debug
60#include "hisax_debug.h"
61static u_int debug;
62module_param(debug, uint, 0);
63int hfc_debug;
64#endif
65
66
67/****************************************/
68/* data defining the devices to be used */
69/****************************************/
70static struct usb_device_id hfc_usb_idtab[] = {
71 {USB_DEVICE(0x0959, 0x2bd0)}, /* Colognechip USB eval TA */
72 {USB_DEVICE(0x0675, 0x1688)}, /* DrayTek miniVigor 128 USB ISDN TA */
73 {USB_DEVICE(0x07b0, 0x0007)}, /* Billion USB TA 2 */
74 {USB_DEVICE(0x0742, 0x2008)}, /* Stollmann USB TA */
75 {USB_DEVICE(0x0742, 0x2009)}, /* Aceex USB ISDN TA */
76 {USB_DEVICE(0x0742, 0x200A)}, /* OEM USB ISDN TA */
77 {USB_DEVICE(0x08e3, 0x0301)}, /* OliTec ISDN USB */
78 {USB_DEVICE(0x07fa, 0x0846)}, /* Bewan ISDN USB TA */
79 {USB_DEVICE(0x07fa, 0x0847)}, /* Djinn Numeris USB */
80 {USB_DEVICE(0x07b0, 0x0006)}, /* Twister ISDN USB TA */
81 {} /* end with an all-zeroes entry */
82};
83
84/* driver internal device specific data:
85* VendorID, ProductID, Devicename, LED_SCHEME,
86* LED's BitMask in HFCUSB_P_DATA Register : LED_USB, LED_S0, LED_B1, LED_B2
87*/
88vendor_data vdata[] = {
89 /* CologneChip Eval TA */
90 {0x0959, 0x2bd0, "ISDN USB TA (Cologne Chip HFC-S USB based)",
91 LED_OFF, {4, 0, 2, 1}
92 }
93 ,
94 /* DrayTek miniVigor 128 USB ISDN TA */
95 {0x0675, 0x1688, "DrayTek miniVigor 128 USB ISDN TA",
96 LED_SCHEME1, {1, 2, 0, 0}
97 }
98 ,
99 /* Billion TA */
100 {0x07b0, 0x0007, "Billion tiny USB ISDN TA 128",
101 LED_SCHEME1, {0x80, -64, -32, -16}
102 }
103 ,
104 /* Stollmann TA */
105 {0x0742, 0x2008, "Stollmann USB TA",
106 LED_SCHEME1, {4, 0, 2, 1}
107 }
108 ,
109 /* Aceex USB ISDN TA */
110 {0x0742, 0x2009, "Aceex USB ISDN TA",
111 LED_SCHEME1, {4, 0, 2, 1}
112 }
113 ,
114 /* OEM USB ISDN TA */
115 {0x0742, 0x200A, "OEM USB ISDN TA",
116 LED_SCHEME1, {4, 0, 2, 1}
117 }
118 ,
119 /* Olitec TA */
120 {0x08e3, 0x0301, "Olitec USB RNIS",
121 LED_SCHEME1, {2, 0, 1, 4}
122 }
123 ,
124 /* Bewan TA */
125 {0x07fa, 0x0846, "Bewan Modem RNIS USB",
126 LED_SCHEME1, {0x80, -64, -32, -16}
127 }
128 ,
129 /* Bewan TA */
130 {0x07fa, 0x0847, "Djinn Numeris USB",
131 LED_SCHEME1, {0x80, -64, -32, -16}
132 }
133 ,
134 /* Twister ISDN TA */
135 {0x07b0, 0x0006, "Twister ISDN TA",
136 LED_SCHEME1, {0x80, -64, -32, -16}
137 }
138 ,
139 {0, 0, 0} /* EOL element */
140};
141
142/***************************************************************/
143/* structure defining input+output fifos (interrupt/bulk mode) */
144/***************************************************************/
145struct usb_fifo; /* forward definition */
146typedef struct iso_urb_struct {
147 struct urb *purb;
148 __u8 buffer[ISO_BUFFER_SIZE]; /* buffer incoming/outgoing data */
149 struct usb_fifo *owner_fifo; /* pointer to owner fifo */
150} iso_urb_struct;
151
152
153struct hfcusb_data; /* forward definition */
154typedef struct usb_fifo {
155 int fifonum; /* fifo index attached to this structure */
156 int active; /* fifo is currently active */
157 struct hfcusb_data *hfc; /* pointer to main structure */
158 int pipe; /* address of endpoint */
159 __u8 usb_packet_maxlen; /* maximum length for usb transfer */
160 unsigned int max_size; /* maximum size of receive/send packet */
161 __u8 intervall; /* interrupt interval */
162 struct sk_buff *skbuff; /* actual used buffer */
163 struct urb *urb; /* transfer structure for usb routines */
164 __u8 buffer[128]; /* buffer incoming/outgoing data */
165 int bit_line; /* how much bits are in the fifo? */
166
167 volatile __u8 usb_transfer_mode; /* switched between ISO and INT */
168 iso_urb_struct iso[2]; /* need two urbs to have one always for pending */
169 struct hisax_if *hif; /* hisax interface */
170 int delete_flg; /* only delete skbuff once */
171 int last_urblen; /* remember length of last packet */
172
173} usb_fifo;
174
175/*********************************************/
176/* structure holding all data for one device */
177/*********************************************/
178typedef struct hfcusb_data {
179 /* HiSax Interface for loadable Layer1 drivers */
180 struct hisax_d_if d_if; /* see hisax_if.h */
181 struct hisax_b_if b_if[2]; /* see hisax_if.h */
182 int protocol;
183
184 struct usb_device *dev; /* our device */
185 int if_used; /* used interface number */
186 int alt_used; /* used alternate config */
187 int ctrl_paksize; /* control pipe packet size */
188 int ctrl_in_pipe, ctrl_out_pipe; /* handles for control pipe */
189 int cfg_used; /* configuration index used */
190 int vend_idx; /* vendor found */
191 int b_mode[2]; /* B-channel mode */
192 int l1_activated; /* layer 1 activated */
193 int disc_flag; /* TRUE if device was disonnected to avoid some USB actions */
194 int packet_size, iso_packet_size;
195
196 /* control pipe background handling */
197 ctrl_buft ctrl_buff[HFC_CTRL_BUFSIZE]; /* buffer holding queued data */
198 volatile int ctrl_in_idx, ctrl_out_idx, ctrl_cnt; /* input/output pointer + count */
199 struct urb *ctrl_urb; /* transfer structure for control channel */
200
201 struct usb_ctrlrequest ctrl_write; /* buffer for control write request */
202 struct usb_ctrlrequest ctrl_read; /* same for read request */
203
204 __u8 old_led_state, led_state, led_new_data, led_b_active;
205
206 volatile __u8 threshold_mask; /* threshold actually reported */
207 volatile __u8 bch_enables; /* or mask for sctrl_r and sctrl register values */
208
209 usb_fifo fifos[HFCUSB_NUM_FIFOS]; /* structure holding all fifo data */
210
211 volatile __u8 l1_state; /* actual l1 state */
212 struct timer_list t3_timer; /* timer 3 for activation/deactivation */
213 struct timer_list t4_timer; /* timer 4 for activation/deactivation */
214 struct timer_list led_timer; /* timer flashing leds */
215
216} hfcusb_data;
217
218
219static void collect_rx_frame(usb_fifo * fifo, __u8 * data, int len,
220 int finish);
221
222
223static inline const char *
224symbolic(struct hfcusb_symbolic_list list[], const int num)
225{
226 int i;
227 for (i = 0; list[i].name != NULL; i++)
228 if (list[i].num == num)
229 return (list[i].name);
230 return "<unkown>";
231}
232
233
234/******************************************************/
235/* start next background transfer for control channel */
236/******************************************************/
237static void
238ctrl_start_transfer(hfcusb_data * hfc)
239{
240 if (hfc->ctrl_cnt) {
241 hfc->ctrl_urb->pipe = hfc->ctrl_out_pipe;
242 hfc->ctrl_urb->setup_packet = (u_char *) & hfc->ctrl_write;
243 hfc->ctrl_urb->transfer_buffer = NULL;
244 hfc->ctrl_urb->transfer_buffer_length = 0;
245 hfc->ctrl_write.wIndex =
246 hfc->ctrl_buff[hfc->ctrl_out_idx].hfc_reg;
247 hfc->ctrl_write.wValue =
248 hfc->ctrl_buff[hfc->ctrl_out_idx].reg_val;
249
250 usb_submit_urb(hfc->ctrl_urb, GFP_ATOMIC); /* start transfer */
251 }
252} /* ctrl_start_transfer */
253
254/************************************/
255/* queue a control transfer request */
256/* return 0 on success. */
257/************************************/
258static int
259queue_control_request(hfcusb_data * hfc, __u8 reg, __u8 val, int action)
260{
261 ctrl_buft *buf;
262
263 if (hfc->ctrl_cnt >= HFC_CTRL_BUFSIZE)
264 return (1); /* no space left */
265 buf = &hfc->ctrl_buff[hfc->ctrl_in_idx]; /* pointer to new index */
266 buf->hfc_reg = reg;
267 buf->reg_val = val;
268 buf->action = action;
269 if (++hfc->ctrl_in_idx >= HFC_CTRL_BUFSIZE)
270 hfc->ctrl_in_idx = 0; /* pointer wrap */
271 if (++hfc->ctrl_cnt == 1)
272 ctrl_start_transfer(hfc);
273 return (0);
274} /* queue_control_request */
275
276static int
277control_action_handler(hfcusb_data * hfc, int reg, int val, int action)
278{
279 if (!action)
280 return (1); /* no action defined */
281 return (0);
282}
283
284/***************************************************************/
285/* control completion routine handling background control cmds */
286/***************************************************************/
287static void
288ctrl_complete(struct urb *urb, struct pt_regs *regs)
289{
290 hfcusb_data *hfc = (hfcusb_data *) urb->context;
291 ctrl_buft *buf;
292
293 urb->dev = hfc->dev;
294 if (hfc->ctrl_cnt) {
295 buf = &hfc->ctrl_buff[hfc->ctrl_out_idx];
296 control_action_handler(hfc, buf->hfc_reg, buf->reg_val,
297 buf->action);
298
299 hfc->ctrl_cnt--; /* decrement actual count */
300 if (++hfc->ctrl_out_idx >= HFC_CTRL_BUFSIZE)
301 hfc->ctrl_out_idx = 0; /* pointer wrap */
302
303 ctrl_start_transfer(hfc); /* start next transfer */
304 }
305} /* ctrl_complete */
306
307/***************************************************/
308/* write led data to auxport & invert if necessary */
309/***************************************************/
310static void
311write_led(hfcusb_data * hfc, __u8 led_state)
312{
313 if (led_state != hfc->old_led_state) {
314 hfc->old_led_state = led_state;
315 queue_control_request(hfc, HFCUSB_P_DATA, led_state, 1);
316 }
317}
318
319/**************************/
320/* handle LED bits */
321/**************************/
322static void
323set_led_bit(hfcusb_data * hfc, signed short led_bits, int unset)
324{
325 if (unset) {
326 if (led_bits < 0)
327 hfc->led_state |= abs(led_bits);
328 else
329 hfc->led_state &= ~led_bits;
330 } else {
331 if (led_bits < 0)
332 hfc->led_state &= ~abs(led_bits);
333 else
334 hfc->led_state |= led_bits;
335 }
336}
337
338/******************************************/
339/* invert B-channel LEDs if data is sent */
340/******************************************/
341static void
342led_timer(hfcusb_data * hfc)
343{
344 static int cnt = 0;
345
346 if (cnt) {
347 if (hfc->led_b_active & 1)
348 set_led_bit(hfc, vdata[hfc->vend_idx].led_bits[2],
349 0);
350 if (hfc->led_b_active & 2)
351 set_led_bit(hfc, vdata[hfc->vend_idx].led_bits[3],
352 0);
353 } else {
354 if (!(hfc->led_b_active & 1) || hfc->led_new_data & 1)
355 set_led_bit(hfc, vdata[hfc->vend_idx].led_bits[2],
356 1);
357 if (!(hfc->led_b_active & 2) || hfc->led_new_data & 2)
358 set_led_bit(hfc, vdata[hfc->vend_idx].led_bits[3],
359 1);
360 }
361
362 write_led(hfc, hfc->led_state);
363 hfc->led_new_data = 0;
364
365 cnt = !cnt;
366
367 /* restart 4 hz timer */
368 if (!timer_pending(&hfc->led_timer)) {
369 add_timer(&hfc->led_timer);
370 hfc->led_timer.expires = jiffies + (LED_TIME * HZ) / 1000;
371 }
372}
373
374/**************************/
375/* handle LED requests */
376/**************************/
377static void
378handle_led(hfcusb_data * hfc, int event)
379{
380 /* if no scheme -> no LED action */
381 if (vdata[hfc->vend_idx].led_scheme == LED_OFF)
382 return;
383
384 switch (event) {
385 case LED_POWER_ON:
386 set_led_bit(hfc, vdata[hfc->vend_idx].led_bits[0],
387 0);
388 set_led_bit(hfc, vdata[hfc->vend_idx].led_bits[1],
389 1);
390 set_led_bit(hfc, vdata[hfc->vend_idx].led_bits[2],
391 1);
392 set_led_bit(hfc, vdata[hfc->vend_idx].led_bits[3],
393 1);
394 break;
395 case LED_POWER_OFF: /* no Power off handling */
396 break;
397 case LED_S0_ON:
398 set_led_bit(hfc, vdata[hfc->vend_idx].led_bits[1],
399 0);
400 break;
401 case LED_S0_OFF:
402 set_led_bit(hfc, vdata[hfc->vend_idx].led_bits[1],
403 1);
404 break;
405 case LED_B1_ON:
406 hfc->led_b_active |= 1;
407 break;
408 case LED_B1_OFF:
409 hfc->led_b_active &= ~1;
410 break;
411 case LED_B1_DATA:
412 hfc->led_new_data |= 1;
413 break;
414 case LED_B2_ON:
415 hfc->led_b_active |= 2;
416 break;
417 case LED_B2_OFF:
418 hfc->led_b_active &= ~2;
419 break;
420 case LED_B2_DATA:
421 hfc->led_new_data |= 2;
422 break;
423 }
424
425 write_led(hfc, hfc->led_state);
426}
427
428/********************************/
429/* called when timer t3 expires */
430/********************************/
431static void
432l1_timer_expire_t3(hfcusb_data * hfc)
433{
434 hfc->d_if.ifc.l1l2(&hfc->d_if.ifc, PH_DEACTIVATE | INDICATION,
435 NULL);
436#ifdef CONFIG_HISAX_DEBUG
437 DBG(ISDN_DBG,
438 "HFC-S USB: PH_DEACTIVATE | INDICATION sent (T3 expire)");
439#endif
440 hfc->l1_activated = FALSE;
441 handle_led(hfc, LED_S0_OFF);
442 /* deactivate : */
443 queue_control_request(hfc, HFCUSB_STATES, 0x10, 1);
444 queue_control_request(hfc, HFCUSB_STATES, 3, 1);
445}
446
447/********************************/
448/* called when timer t4 expires */
449/********************************/
450static void
451l1_timer_expire_t4(hfcusb_data * hfc)
452{
453 hfc->d_if.ifc.l1l2(&hfc->d_if.ifc, PH_DEACTIVATE | INDICATION,
454 NULL);
455#ifdef CONFIG_HISAX_DEBUG
456 DBG(ISDN_DBG,
457 "HFC-S USB: PH_DEACTIVATE | INDICATION sent (T4 expire)");
458#endif
459 hfc->l1_activated = FALSE;
460 handle_led(hfc, LED_S0_OFF);
461}
462
463/*****************************/
464/* handle S0 state changes */
465/*****************************/
466static void
467state_handler(hfcusb_data * hfc, __u8 state)
468{
469 __u8 old_state;
470
471 old_state = hfc->l1_state;
472 if (state == old_state || state < 1 || state > 8)
473 return;
474
475#ifdef CONFIG_HISAX_DEBUG
476 DBG(ISDN_DBG, "HFC-S USB: new S0 state:%d old_state:%d", state,
477 old_state);
478#endif
479 if (state < 4 || state == 7 || state == 8) {
480 if (timer_pending(&hfc->t3_timer))
481 del_timer(&hfc->t3_timer);
482#ifdef CONFIG_HISAX_DEBUG
483 DBG(ISDN_DBG, "HFC-S USB: T3 deactivated");
484#endif
485 }
486 if (state >= 7) {
487 if (timer_pending(&hfc->t4_timer))
488 del_timer(&hfc->t4_timer);
489#ifdef CONFIG_HISAX_DEBUG
490 DBG(ISDN_DBG, "HFC-S USB: T4 deactivated");
491#endif
492 }
493
494 if (state == 7 && !hfc->l1_activated) {
495 hfc->d_if.ifc.l1l2(&hfc->d_if.ifc,
496 PH_ACTIVATE | INDICATION, NULL);
497#ifdef CONFIG_HISAX_DEBUG
498 DBG(ISDN_DBG, "HFC-S USB: PH_ACTIVATE | INDICATION sent");
499#endif
500 hfc->l1_activated = TRUE;
501 handle_led(hfc, LED_S0_ON);
502 } else if (state <= 3 /* && activated */ ) {
503 if (old_state == 7 || old_state == 8) {
504#ifdef CONFIG_HISAX_DEBUG
505 DBG(ISDN_DBG, "HFC-S USB: T4 activated");
506#endif
507 if (!timer_pending(&hfc->t4_timer)) {
508 hfc->t4_timer.expires =
509 jiffies + (HFC_TIMER_T4 * HZ) / 1000;
510 add_timer(&hfc->t4_timer);
511 }
512 } else {
513 hfc->d_if.ifc.l1l2(&hfc->d_if.ifc,
514 PH_DEACTIVATE | INDICATION,
515 NULL);
516#ifdef CONFIG_HISAX_DEBUG
517 DBG(ISDN_DBG,
518 "HFC-S USB: PH_DEACTIVATE | INDICATION sent");
519#endif
520 hfc->l1_activated = FALSE;
521 handle_led(hfc, LED_S0_OFF);
522 }
523 }
524 hfc->l1_state = state;
525}
526
527/* prepare iso urb */
528static void
529fill_isoc_urb(struct urb *urb, struct usb_device *dev, unsigned int pipe,
530 void *buf, int num_packets, int packet_size, int interval,
531 usb_complete_t complete, void *context)
532{
533 int k;
534
535 spin_lock_init(&urb->lock);
536 urb->dev = dev;
537 urb->pipe = pipe;
538 urb->complete = complete;
539 urb->number_of_packets = num_packets;
540 urb->transfer_buffer_length = packet_size * num_packets;
541 urb->context = context;
542 urb->transfer_buffer = buf;
543 urb->transfer_flags = URB_ISO_ASAP;
544 urb->actual_length = 0;
545 urb->interval = interval;
546 for (k = 0; k < num_packets; k++) {
547 urb->iso_frame_desc[k].offset = packet_size * k;
548 urb->iso_frame_desc[k].length = packet_size;
549 urb->iso_frame_desc[k].actual_length = 0;
550 }
551}
552
553/* allocs urbs and start isoc transfer with two pending urbs to avoid
554 gaps in the transfer chain */
555static int
556start_isoc_chain(usb_fifo * fifo, int num_packets_per_urb,
557 usb_complete_t complete, int packet_size)
558{
559 int i, k, errcode;
560
561 printk(KERN_INFO "HFC-S USB: starting ISO-chain for Fifo %i\n",
562 fifo->fifonum);
563
564 /* allocate Memory for Iso out Urbs */
565 for (i = 0; i < 2; i++) {
566 if (!(fifo->iso[i].purb)) {
567 fifo->iso[i].purb =
568 usb_alloc_urb(num_packets_per_urb, GFP_KERNEL);
569 if (!(fifo->iso[i].purb)) {
570 printk(KERN_INFO
571 "alloc urb for fifo %i failed!!!",
572 fifo->fifonum);
573 }
574 fifo->iso[i].owner_fifo = (struct usb_fifo *) fifo;
575
576 /* Init the first iso */
577 if (ISO_BUFFER_SIZE >=
578 (fifo->usb_packet_maxlen *
579 num_packets_per_urb)) {
580 fill_isoc_urb(fifo->iso[i].purb,
581 fifo->hfc->dev, fifo->pipe,
582 fifo->iso[i].buffer,
583 num_packets_per_urb,
584 fifo->usb_packet_maxlen,
585 fifo->intervall, complete,
586 &fifo->iso[i]);
587 memset(fifo->iso[i].buffer, 0,
588 sizeof(fifo->iso[i].buffer));
589 /* defining packet delimeters in fifo->buffer */
590 for (k = 0; k < num_packets_per_urb; k++) {
591 fifo->iso[i].purb->
592 iso_frame_desc[k].offset =
593 k * packet_size;
594 fifo->iso[i].purb->
595 iso_frame_desc[k].length =
596 packet_size;
597 }
598 } else {
599 printk(KERN_INFO
600 "HFC-S USB: ISO Buffer size to small!\n");
601 }
602 }
603 fifo->bit_line = BITLINE_INF;
604
605 errcode = usb_submit_urb(fifo->iso[i].purb, GFP_KERNEL);
606 fifo->active = (errcode >= 0) ? 1 : 0;
607 if (errcode < 0) {
608 printk(KERN_INFO "HFC-S USB: %s URB nr:%d\n",
609 symbolic(urb_errlist, errcode), i);
610 };
611 }
612 return (fifo->active);
613}
614
615/* stops running iso chain and frees their pending urbs */
616static void
617stop_isoc_chain(usb_fifo * fifo)
618{
619 int i;
620
621 for (i = 0; i < 2; i++) {
622 if (fifo->iso[i].purb) {
623#ifdef CONFIG_HISAX_DEBUG
624 DBG(USB_DBG,
625 "HFC-S USB: Stopping iso chain for fifo %i.%i",
626 fifo->fifonum, i);
627#endif
628 usb_unlink_urb(fifo->iso[i].purb);
629 usb_free_urb(fifo->iso[i].purb);
630 fifo->iso[i].purb = NULL;
631 }
632 }
633 if (fifo->urb) {
634 usb_unlink_urb(fifo->urb);
635 usb_free_urb(fifo->urb);
636 fifo->urb = NULL;
637 }
638 fifo->active = 0;
639}
640
641/* defines how much ISO packets are handled in one URB */
642static int iso_packets[8] =
643 { ISOC_PACKETS_B, ISOC_PACKETS_B, ISOC_PACKETS_B, ISOC_PACKETS_B,
644 ISOC_PACKETS_D, ISOC_PACKETS_D, ISOC_PACKETS_D, ISOC_PACKETS_D
645};
646
647/*****************************************************/
648/* transmit completion routine for all ISO tx fifos */
649/*****************************************************/
650static void
651tx_iso_complete(struct urb *urb, struct pt_regs *regs)
652{
653 iso_urb_struct *context_iso_urb = (iso_urb_struct *) urb->context;
654 usb_fifo *fifo = context_iso_urb->owner_fifo;
655 hfcusb_data *hfc = fifo->hfc;
656 int k, tx_offset, num_isoc_packets, sink, len, current_len,
657 errcode;
658 int frame_complete, transp_mode, fifon, status;
659 __u8 threshbit;
660 __u8 threshtable[8] = { 1, 2, 4, 8, 0x10, 0x20, 0x40, 0x80 };
661
662 fifon = fifo->fifonum;
663 status = urb->status;
664
665 tx_offset = 0;
666
667 if (fifo->active && !status) {
668 transp_mode = 0;
669 if (fifon < 4 && hfc->b_mode[fifon / 2] == L1_MODE_TRANS)
670 transp_mode = TRUE;
671
672 /* is FifoFull-threshold set for our channel? */
673 threshbit = threshtable[fifon] & hfc->threshold_mask;
674 num_isoc_packets = iso_packets[fifon];
675
676 /* predict dataflow to avoid fifo overflow */
677 if (fifon >= HFCUSB_D_TX) {
678 sink = (threshbit) ? SINK_DMIN : SINK_DMAX;
679 } else {
680 sink = (threshbit) ? SINK_MIN : SINK_MAX;
681 }
682 fill_isoc_urb(urb, fifo->hfc->dev, fifo->pipe,
683 context_iso_urb->buffer, num_isoc_packets,
684 fifo->usb_packet_maxlen, fifo->intervall,
685 tx_iso_complete, urb->context);
686 memset(context_iso_urb->buffer, 0,
687 sizeof(context_iso_urb->buffer));
688 frame_complete = FALSE;
689 /* Generate next Iso Packets */
690 for (k = 0; k < num_isoc_packets; ++k) {
691 if (fifo->skbuff) {
692 len = fifo->skbuff->len;
693 /* we lower data margin every msec */
694 fifo->bit_line -= sink;
695 current_len = (0 - fifo->bit_line) / 8;
696 /* maximum 15 byte for every ISO packet makes our life easier */
697 if (current_len > 14)
698 current_len = 14;
699 current_len =
700 (len <=
701 current_len) ? len : current_len;
702 /* how much bit do we put on the line? */
703 fifo->bit_line += current_len * 8;
704
705 context_iso_urb->buffer[tx_offset] = 0;
706 if (current_len == len) {
707 if (!transp_mode) {
708 /* here frame completion */
709 context_iso_urb->
710 buffer[tx_offset] = 1;
711 /* add 2 byte flags and 16bit CRC at end of ISDN frame */
712 fifo->bit_line += 32;
713 }
714 frame_complete = TRUE;
715 }
716
717 memcpy(context_iso_urb->buffer +
718 tx_offset + 1, fifo->skbuff->data,
719 current_len);
720 skb_pull(fifo->skbuff, current_len);
721
722 /* define packet delimeters within the URB buffer */
723 urb->iso_frame_desc[k].offset = tx_offset;
724 urb->iso_frame_desc[k].length =
725 current_len + 1;
726
727 tx_offset += (current_len + 1);
728 if (!transp_mode) {
729 if (fifon == HFCUSB_B1_TX)
730 handle_led(hfc,
731 LED_B1_DATA);
732 if (fifon == HFCUSB_B2_TX)
733 handle_led(hfc,
734 LED_B2_DATA);
735 }
736 } else {
737 urb->iso_frame_desc[k].offset =
738 tx_offset++;
739
740 urb->iso_frame_desc[k].length = 1;
741 fifo->bit_line -= sink; /* we lower data margin every msec */
742
743 if (fifo->bit_line < BITLINE_INF) {
744 fifo->bit_line = BITLINE_INF;
745 }
746 }
747
748 if (frame_complete) {
749 fifo->delete_flg = TRUE;
750 fifo->hif->l1l2(fifo->hif,
751 PH_DATA | CONFIRM,
752 (void *) fifo->skbuff->
753 truesize);
754 if (fifo->skbuff && fifo->delete_flg) {
755 dev_kfree_skb_any(fifo->skbuff);
756 fifo->skbuff = NULL;
757 fifo->delete_flg = FALSE;
758 }
759 frame_complete = FALSE;
760 }
761 }
762 errcode = usb_submit_urb(urb, GFP_ATOMIC);
763 if (errcode < 0) {
764 printk(KERN_INFO
765 "HFC-S USB: error submitting ISO URB: %d \n",
766 errcode);
767 }
768 } else {
769 if (status && !hfc->disc_flag) {
770 printk(KERN_INFO
771 "HFC-S USB: tx_iso_complete : urb->status %s (%i), fifonum=%d\n",
772 symbolic(urb_errlist, status), status,
773 fifon);
774 }
775 }
776} /* tx_iso_complete */
777
778/*****************************************************/
779/* receive completion routine for all ISO tx fifos */
780/*****************************************************/
781static void
782rx_iso_complete(struct urb *urb, struct pt_regs *regs)
783{
784 iso_urb_struct *context_iso_urb = (iso_urb_struct *) urb->context;
785 usb_fifo *fifo = context_iso_urb->owner_fifo;
786 hfcusb_data *hfc = fifo->hfc;
787 int k, len, errcode, offset, num_isoc_packets, fifon, maxlen,
788 status;
789 unsigned int iso_status;
790 __u8 *buf;
791 static __u8 eof[8];
792#ifdef CONFIG_HISAX_DEBUG
793 __u8 i;
794#endif
795
796 fifon = fifo->fifonum;
797 status = urb->status;
798
799 if (urb->status == -EOVERFLOW) {
800#ifdef CONFIG_HISAX_DEBUG
801 DBG(USB_DBG,
802 "HFC-USB: ignoring USB DATAOVERRUN for fifo %i \n",
803 fifon);
804#endif
805 status = 0;
806 }
807 if (fifo->active && !status) {
808 num_isoc_packets = iso_packets[fifon];
809 maxlen = fifo->usb_packet_maxlen;
810 for (k = 0; k < num_isoc_packets; ++k) {
811 len = urb->iso_frame_desc[k].actual_length;
812 offset = urb->iso_frame_desc[k].offset;
813 buf = context_iso_urb->buffer + offset;
814 iso_status = urb->iso_frame_desc[k].status;
815#ifdef CONFIG_HISAX_DEBUG
816 if (iso_status && !hfc->disc_flag)
817 DBG(USB_DBG,
818 "HFC-S USB: ISO packet failure - status:%x",
819 iso_status);
820
821 if ((fifon == 5) && (debug > 1)) {
822 printk(KERN_INFO
823 "HFC-S USB: ISO-D-RX lst_urblen:%2d "
824 "act_urblen:%2d max-urblen:%2d "
825 "EOF:0x%0x DATA: ",
826 fifo->last_urblen, len, maxlen,
827 eof[5]);
828 for (i = 0; i < len; i++)
829 printk("%.2x ", buf[i]);
830 printk("\n");
831 }
832#endif
833 if (fifo->last_urblen != maxlen) {
834 /* the threshold mask is in the 2nd status byte */
835 hfc->threshold_mask = buf[1];
836 /* care for L1 state only for D-Channel
837 to avoid overlapped iso completions */
838 if (fifon == 5) {
839 /* the S0 state is in the upper half
840 of the 1st status byte */
841 state_handler(hfc, buf[0] >> 4);
842 }
843 eof[fifon] = buf[0] & 1;
844 if (len > 2)
845 collect_rx_frame(fifo, buf + 2,
846 len - 2,
847 (len <
848 maxlen) ?
849 eof[fifon] : 0);
850 } else {
851 collect_rx_frame(fifo, buf, len,
852 (len <
853 maxlen) ? eof[fifon] :
854 0);
855 }
856 fifo->last_urblen = len;
857 }
858
859 fill_isoc_urb(urb, fifo->hfc->dev, fifo->pipe,
860 context_iso_urb->buffer, num_isoc_packets,
861 fifo->usb_packet_maxlen, fifo->intervall,
862 rx_iso_complete, urb->context);
863 errcode = usb_submit_urb(urb, GFP_ATOMIC);
864 if (errcode < 0) {
865 printk(KERN_INFO
866 "HFC-S USB: error submitting ISO URB: %d \n",
867 errcode);
868 }
869 } else {
870 if (status && !hfc->disc_flag) {
871 printk(KERN_INFO
872 "HFC-S USB: rx_iso_complete : "
873 "urb->status %d, fifonum %d\n",
874 status, fifon);
875 }
876 }
877} /* rx_iso_complete */
878
879/*****************************************************/
880/* collect data from interrupt or isochron in */
881/*****************************************************/
882static void
883collect_rx_frame(usb_fifo * fifo, __u8 * data, int len, int finish)
884{
885 hfcusb_data *hfc = fifo->hfc;
886 int transp_mode, fifon;
887#ifdef CONFIG_HISAX_DEBUG
888 int i;
889#endif
890 fifon = fifo->fifonum;
891 transp_mode = 0;
892 if (fifon < 4 && hfc->b_mode[fifon / 2] == L1_MODE_TRANS)
893 transp_mode = TRUE;
894
895 if (!fifo->skbuff) {
896 fifo->skbuff = dev_alloc_skb(fifo->max_size + 3);
897 if (!fifo->skbuff) {
898 printk(KERN_INFO
899 "HFC-S USB: cannot allocate buffer (dev_alloc_skb) fifo:%d\n",
900 fifon);
901 return;
902 }
903 }
904 if (len) {
905 if (fifo->skbuff->len + len < fifo->max_size) {
906 memcpy(skb_put(fifo->skbuff, len), data, len);
907 } else {
908#ifdef CONFIG_HISAX_DEBUG
909 printk(KERN_INFO "HFC-S USB: ");
910 for (i = 0; i < 15; i++)
911 printk("%.2x ",
912 fifo->skbuff->data[fifo->skbuff->
913 len - 15 + i]);
914 printk("\n");
915#endif
916 printk(KERN_INFO
917 "HCF-USB: got frame exceeded fifo->max_size:%d on fifo:%d\n",
918 fifo->max_size, fifon);
919 }
920 }
921 if (transp_mode && fifo->skbuff->len >= 128) {
922 fifo->hif->l1l2(fifo->hif, PH_DATA | INDICATION,
923 fifo->skbuff);
924 fifo->skbuff = NULL;
925 return;
926 }
927 /* we have a complete hdlc packet */
928 if (finish) {
929 if ((!fifo->skbuff->data[fifo->skbuff->len - 1])
930 && (fifo->skbuff->len > 3)) {
931 /* remove CRC & status */
932 skb_trim(fifo->skbuff, fifo->skbuff->len - 3);
933 if (fifon == HFCUSB_PCM_RX) {
934 fifo->hif->l1l2(fifo->hif,
935 PH_DATA_E | INDICATION,
936 fifo->skbuff);
937 } else
938 fifo->hif->l1l2(fifo->hif,
939 PH_DATA | INDICATION,
940 fifo->skbuff);
941 fifo->skbuff = NULL; /* buffer was freed from upper layer */
942 } else {
943 if (fifo->skbuff->len > 3) {
944 printk(KERN_INFO
945 "HFC-S USB: got frame %d bytes but CRC ERROR on fifo:%d!!!\n",
946 fifo->skbuff->len, fifon);
947#ifdef CONFIG_HISAX_DEBUG
948 if (debug > 1) {
949 printk(KERN_INFO "HFC-S USB: ");
950 for (i = 0; i < 15; i++)
951 printk("%.2x ",
952 fifo->skbuff->
953 data[fifo->skbuff->
954 len - 15 + i]);
955 printk("\n");
956 }
957#endif
958 }
959#ifdef CONFIG_HISAX_DEBUG
960 else {
961 printk(KERN_INFO
962 "HFC-S USB: frame to small (%d bytes)!!!\n",
963 fifo->skbuff->len);
964 }
965#endif
966 skb_trim(fifo->skbuff, 0);
967 }
968 }
969
970 /* LED flashing only in HDLC mode */
971 if (!transp_mode) {
972 if (fifon == HFCUSB_B1_RX)
973 handle_led(hfc, LED_B1_DATA);
974 if (fifon == HFCUSB_B2_RX)
975 handle_led(hfc, LED_B2_DATA);
976 }
977}
978
979/***********************************************/
980/* receive completion routine for all rx fifos */
981/***********************************************/
982static void
983rx_complete(struct urb *urb, struct pt_regs *regs)
984{
985 int len;
986 int status;
987 __u8 *buf, maxlen, fifon;
988 usb_fifo *fifo = (usb_fifo *) urb->context;
989 hfcusb_data *hfc = fifo->hfc;
990 static __u8 eof[8];
991#ifdef CONFIG_HISAX_DEBUG
992 __u8 i;
993#endif
994
995 urb->dev = hfc->dev; /* security init */
996
997 fifon = fifo->fifonum;
998 if ((!fifo->active) || (urb->status)) {
999#ifdef CONFIG_HISAX_DEBUG
1000 DBG(USB_DBG, "HFC-S USB: RX-Fifo %i is going down (%i)",
1001 fifon, urb->status);
1002#endif
1003 fifo->urb->interval = 0; /* cancel automatic rescheduling */
1004 if (fifo->skbuff) {
1005 dev_kfree_skb_any(fifo->skbuff);
1006 fifo->skbuff = NULL;
1007 }
1008 return;
1009 }
1010 len = urb->actual_length;
1011 buf = fifo->buffer;
1012 maxlen = fifo->usb_packet_maxlen;
1013
1014#ifdef CONFIG_HISAX_DEBUG
1015 if ((fifon == 5) && (debug > 1)) {
1016 printk(KERN_INFO
1017 "HFC-S USB: INT-D-RX lst_urblen:%2d act_urblen:%2d max-urblen:%2d EOF:0x%0x DATA: ",
1018 fifo->last_urblen, len, maxlen, eof[5]);
1019 for (i = 0; i < len; i++)
1020 printk("%.2x ", buf[i]);
1021 printk("\n");
1022 }
1023#endif
1024
1025 if (fifo->last_urblen != fifo->usb_packet_maxlen) {
1026 /* the threshold mask is in the 2nd status byte */
1027 hfc->threshold_mask = buf[1];
1028 /* the S0 state is in the upper half of the 1st status byte */
1029 state_handler(hfc, buf[0] >> 4);
1030 eof[fifon] = buf[0] & 1;
1031 /* if we have more than the 2 status bytes -> collect data */
1032 if (len > 2)
1033 collect_rx_frame(fifo, buf + 2,
1034 urb->actual_length - 2,
1035 (len < maxlen) ? eof[fifon] : 0);
1036 } else {
1037 collect_rx_frame(fifo, buf, urb->actual_length,
1038 (len < maxlen) ? eof[fifon] : 0);
1039 }
1040 fifo->last_urblen = urb->actual_length;
1041 status = usb_submit_urb(urb, GFP_ATOMIC);
1042 if (status) {
1043 printk(KERN_INFO
1044 "HFC-S USB: error resubmitting URN at rx_complete...\n");
1045 }
1046} /* rx_complete */
1047
1048/***************************************************/
1049/* start the interrupt transfer for the given fifo */
1050/***************************************************/
1051static void
1052start_int_fifo(usb_fifo * fifo)
1053{
1054 int errcode;
1055
1056 printk(KERN_INFO "HFC-S USB: starting intr IN fifo:%d\n",
1057 fifo->fifonum);
1058
1059 if (!fifo->urb) {
1060 fifo->urb = usb_alloc_urb(0, GFP_KERNEL);
1061 if (!fifo->urb)
1062 return;
1063 }
1064 usb_fill_int_urb(fifo->urb, fifo->hfc->dev, fifo->pipe,
1065 fifo->buffer, fifo->usb_packet_maxlen,
1066 rx_complete, fifo, fifo->intervall);
1067 fifo->active = 1; /* must be marked active */
1068 errcode = usb_submit_urb(fifo->urb, GFP_KERNEL);
1069 if (errcode) {
1070 printk(KERN_INFO
1071 "HFC-S USB: submit URB error(start_int_info): status:%i\n",
1072 errcode);
1073 fifo->active = 0;
1074 fifo->skbuff = NULL;
1075 }
1076} /* start_int_fifo */
1077
1078/*****************************/
1079/* set the B-channel mode */
1080/*****************************/
1081static void
1082set_hfcmode(hfcusb_data * hfc, int channel, int mode)
1083{
1084 __u8 val, idx_table[2] = { 0, 2 };
1085
1086 if (hfc->disc_flag) {
1087 return;
1088 }
1089#ifdef CONFIG_HISAX_DEBUG
1090 DBG(ISDN_DBG, "HFC-S USB: setting channel %d to mode %d", channel,
1091 mode);
1092#endif
1093 hfc->b_mode[channel] = mode;
1094
1095 /* setup CON_HDLC */
1096 val = 0;
1097 if (mode != L1_MODE_NULL)
1098 val = 8; /* enable fifo? */
1099 if (mode == L1_MODE_TRANS)
1100 val |= 2; /* set transparent bit */
1101
1102 /* set FIFO to transmit register */
1103 queue_control_request(hfc, HFCUSB_FIFO, idx_table[channel], 1);
1104 queue_control_request(hfc, HFCUSB_CON_HDLC, val, 1);
1105 /* reset fifo */
1106 queue_control_request(hfc, HFCUSB_INC_RES_F, 2, 1);
1107 /* set FIFO to receive register */
1108 queue_control_request(hfc, HFCUSB_FIFO, idx_table[channel] + 1, 1);
1109 queue_control_request(hfc, HFCUSB_CON_HDLC, val, 1);
1110 /* reset fifo */
1111 queue_control_request(hfc, HFCUSB_INC_RES_F, 2, 1);
1112
1113 val = 0x40;
1114 if (hfc->b_mode[0])
1115 val |= 1;
1116 if (hfc->b_mode[1])
1117 val |= 2;
1118 queue_control_request(hfc, HFCUSB_SCTRL, val, 1);
1119
1120 val = 0;
1121 if (hfc->b_mode[0])
1122 val |= 1;
1123 if (hfc->b_mode[1])
1124 val |= 2;
1125 queue_control_request(hfc, HFCUSB_SCTRL_R, val, 1);
1126
1127 if (mode == L1_MODE_NULL) {
1128 if (channel)
1129 handle_led(hfc, LED_B2_OFF);
1130 else
1131 handle_led(hfc, LED_B1_OFF);
1132 } else {
1133 if (channel)
1134 handle_led(hfc, LED_B2_ON);
1135 else
1136 handle_led(hfc, LED_B1_ON);
1137 }
1138}
1139
1140void
1141hfc_usb_l2l1(struct hisax_if *my_hisax_if, int pr, void *arg)
1142{
1143 usb_fifo *fifo = my_hisax_if->priv;
1144 hfcusb_data *hfc = fifo->hfc;
1145
1146 switch (pr) {
1147 case PH_ACTIVATE | REQUEST:
1148 if (fifo->fifonum == HFCUSB_D_TX) {
1149#ifdef CONFIG_HISAX_DEBUG
1150 DBG(ISDN_DBG,
1151 "HFC_USB: hfc_usb_d_l2l1 D-chan: PH_ACTIVATE | REQUEST");
1152#endif
1153 if (hfc->l1_state != 3
1154 && hfc->l1_state != 7) {
1155 hfc->d_if.ifc.l1l2(&hfc->d_if.ifc,
1156 PH_DEACTIVATE |
1157 INDICATION,
1158 NULL);
1159#ifdef CONFIG_HISAX_DEBUG
1160 DBG(ISDN_DBG,
1161 "HFC-S USB: PH_DEACTIVATE | INDICATION sent (not state 3 or 7)");
1162#endif
1163 } else {
1164 if (hfc->l1_state == 7) { /* l1 already active */
1165 hfc->d_if.ifc.l1l2(&hfc->
1166 d_if.
1167 ifc,
1168 PH_ACTIVATE
1169 |
1170 INDICATION,
1171 NULL);
1172#ifdef CONFIG_HISAX_DEBUG
1173 DBG(ISDN_DBG,
1174 "HFC-S USB: PH_ACTIVATE | INDICATION sent again ;)");
1175#endif
1176 } else {
1177 /* force sending sending INFO1 */
1178 queue_control_request(hfc,
1179 HFCUSB_STATES,
1180 0x14,
1181 1);
1182 mdelay(1);
1183 /* start l1 activation */
1184 queue_control_request(hfc,
1185 HFCUSB_STATES,
1186 0x04,
1187 1);
1188 if (!timer_pending
1189 (&hfc->t3_timer)) {
1190 hfc->t3_timer.
1191 expires =
1192 jiffies +
1193 (HFC_TIMER_T3 *
1194 HZ) / 1000;
1195 add_timer(&hfc->
1196 t3_timer);
1197 }
1198 }
1199 }
1200 } else {
1201#ifdef CONFIG_HISAX_DEBUG
1202 DBG(ISDN_DBG,
1203 "HFC_USB: hfc_usb_d_l2l1 Bx-chan: PH_ACTIVATE | REQUEST");
1204#endif
1205 set_hfcmode(hfc,
1206 (fifo->fifonum ==
1207 HFCUSB_B1_TX) ? 0 : 1,
1208 (int) arg);
1209 fifo->hif->l1l2(fifo->hif,
1210 PH_ACTIVATE | INDICATION,
1211 NULL);
1212 }
1213 break;
1214 case PH_DEACTIVATE | REQUEST:
1215 if (fifo->fifonum == HFCUSB_D_TX) {
1216#ifdef CONFIG_HISAX_DEBUG
1217 DBG(ISDN_DBG,
1218 "HFC_USB: hfc_usb_d_l2l1 D-chan: PH_DEACTIVATE | REQUEST");
1219#endif
1220 printk(KERN_INFO
1221 "HFC-S USB: ISDN TE device should not deativate...\n");
1222 } else {
1223#ifdef CONFIG_HISAX_DEBUG
1224 DBG(ISDN_DBG,
1225 "HFC_USB: hfc_usb_d_l2l1 Bx-chan: PH_DEACTIVATE | REQUEST");
1226#endif
1227 set_hfcmode(hfc,
1228 (fifo->fifonum ==
1229 HFCUSB_B1_TX) ? 0 : 1,
1230 (int) L1_MODE_NULL);
1231 fifo->hif->l1l2(fifo->hif,
1232 PH_DEACTIVATE | INDICATION,
1233 NULL);
1234 }
1235 break;
1236 case PH_DATA | REQUEST:
1237 if (fifo->skbuff && fifo->delete_flg) {
1238 dev_kfree_skb_any(fifo->skbuff);
1239 fifo->skbuff = NULL;
1240 fifo->delete_flg = FALSE;
1241 }
1242 fifo->skbuff = arg; /* we have a new buffer */
1243 break;
1244 default:
1245 printk(KERN_INFO
1246 "HFC_USB: hfc_usb_d_l2l1: unkown state : %#x\n",
1247 pr);
1248 break;
1249 }
1250}
1251
1252/***************************************************************************/
1253/* usb_init is called once when a new matching device is detected to setup */
1254/* main parameters. It registers the driver at the main hisax module. */
1255/* on success 0 is returned. */
1256/***************************************************************************/
1257static int
1258usb_init(hfcusb_data * hfc)
1259{
1260 usb_fifo *fifo;
1261 int i, err;
1262 u_char b;
1263 struct hisax_b_if *p_b_if[2];
1264
1265 /* check the chip id */
1266 if (read_usb(hfc, HFCUSB_CHIP_ID, &b) != 1) {
1267 printk(KERN_INFO "HFC-USB: cannot read chip id\n");
1268 return (1);
1269 }
1270 if (b != HFCUSB_CHIPID) {
1271 printk(KERN_INFO "HFC-S USB: Invalid chip id 0x%02x\n", b);
1272 return (1);
1273 }
1274
1275 /* first set the needed config, interface and alternate */
1276 err = usb_set_interface(hfc->dev, hfc->if_used, hfc->alt_used);
1277
1278 /* do Chip reset */
1279 write_usb(hfc, HFCUSB_CIRM, 8);
1280 /* aux = output, reset off */
1281 write_usb(hfc, HFCUSB_CIRM, 0x10);
1282
1283 /* set USB_SIZE to match the the wMaxPacketSize for INT or BULK transfers */
1284 write_usb(hfc, HFCUSB_USB_SIZE,
1285 (hfc->packet_size / 8) | ((hfc->packet_size / 8) << 4));
1286
1287 /* set USB_SIZE_I to match the the wMaxPacketSize for ISO transfers */
1288 write_usb(hfc, HFCUSB_USB_SIZE_I, hfc->iso_packet_size);
1289
1290 /* enable PCM/GCI master mode */
1291 write_usb(hfc, HFCUSB_MST_MODE1, 0); /* set default values */
1292 write_usb(hfc, HFCUSB_MST_MODE0, 1); /* enable master mode */
1293
1294 /* init the fifos */
1295 write_usb(hfc, HFCUSB_F_THRES,
1296 (HFCUSB_TX_THRESHOLD /
1297 8) | ((HFCUSB_RX_THRESHOLD / 8) << 4));
1298
1299 fifo = hfc->fifos;
1300 for (i = 0; i < HFCUSB_NUM_FIFOS; i++) {
1301 write_usb(hfc, HFCUSB_FIFO, i); /* select the desired fifo */
1302 fifo[i].skbuff = NULL; /* init buffer pointer */
1303 fifo[i].max_size =
1304 (i <= HFCUSB_B2_RX) ? MAX_BCH_SIZE : MAX_DFRAME_LEN;
1305 fifo[i].last_urblen = 0;
1306 /* set 2 bit for D- & E-channel */
1307 write_usb(hfc, HFCUSB_HDLC_PAR,
1308 ((i <= HFCUSB_B2_RX) ? 0 : 2));
1309 /* rx hdlc, enable IFF for D-channel */
1310 write_usb(hfc, HFCUSB_CON_HDLC,
1311 ((i == HFCUSB_D_TX) ? 0x09 : 0x08));
1312 write_usb(hfc, HFCUSB_INC_RES_F, 2); /* reset the fifo */
1313 }
1314
1315 write_usb(hfc, HFCUSB_CLKDEL, 0x0f); /* clock delay value */
1316 write_usb(hfc, HFCUSB_STATES, 3 | 0x10); /* set deactivated mode */
1317 write_usb(hfc, HFCUSB_STATES, 3); /* enable state machine */
1318
1319 write_usb(hfc, HFCUSB_SCTRL_R, 0); /* disable both B receivers */
1320 write_usb(hfc, HFCUSB_SCTRL, 0x40); /* disable B transmitters + capacitive mode */
1321
1322 /* set both B-channel to not connected */
1323 hfc->b_mode[0] = L1_MODE_NULL;
1324 hfc->b_mode[1] = L1_MODE_NULL;
1325
1326 hfc->l1_activated = FALSE;
1327 hfc->disc_flag = FALSE;
1328 hfc->led_state = 0;
1329 hfc->led_new_data = 0;
1330 hfc->old_led_state = 0;
1331
1332 /* init the t3 timer */
1333 init_timer(&hfc->t3_timer);
1334 hfc->t3_timer.data = (long) hfc;
1335 hfc->t3_timer.function = (void *) l1_timer_expire_t3;
1336
1337 /* init the t4 timer */
1338 init_timer(&hfc->t4_timer);
1339 hfc->t4_timer.data = (long) hfc;
1340 hfc->t4_timer.function = (void *) l1_timer_expire_t4;
1341
1342 /* init the led timer */
1343 init_timer(&hfc->led_timer);
1344 hfc->led_timer.data = (long) hfc;
1345 hfc->led_timer.function = (void *) led_timer;
1346
1347 /* trigger 4 hz led timer */
1348 if (!timer_pending(&hfc->led_timer)) {
1349 hfc->led_timer.expires = jiffies + (LED_TIME * HZ) / 1000;
1350 add_timer(&hfc->led_timer);
1351 }
1352
1353 /* init the background machinery for control requests */
1354 hfc->ctrl_read.bRequestType = 0xc0;
1355 hfc->ctrl_read.bRequest = 1;
1356 hfc->ctrl_read.wLength = 1;
1357 hfc->ctrl_write.bRequestType = 0x40;
1358 hfc->ctrl_write.bRequest = 0;
1359 hfc->ctrl_write.wLength = 0;
1360 usb_fill_control_urb(hfc->ctrl_urb,
1361 hfc->dev,
1362 hfc->ctrl_out_pipe,
1363 (u_char *) & hfc->ctrl_write,
1364 NULL, 0, ctrl_complete, hfc);
1365 /* Init All Fifos */
1366 for (i = 0; i < HFCUSB_NUM_FIFOS; i++) {
1367 hfc->fifos[i].iso[0].purb = NULL;
1368 hfc->fifos[i].iso[1].purb = NULL;
1369 hfc->fifos[i].active = 0;
1370 }
1371 /* register Modul to upper Hisax Layers */
1372 hfc->d_if.owner = THIS_MODULE;
1373 hfc->d_if.ifc.priv = &hfc->fifos[HFCUSB_D_TX];
1374 hfc->d_if.ifc.l2l1 = hfc_usb_l2l1;
1375 for (i = 0; i < 2; i++) {
1376 hfc->b_if[i].ifc.priv = &hfc->fifos[HFCUSB_B1_TX + i * 2];
1377 hfc->b_if[i].ifc.l2l1 = hfc_usb_l2l1;
1378 p_b_if[i] = &hfc->b_if[i];
1379 }
1380 /* default Prot: EURO ISDN, should be a module_param */
1381 hfc->protocol = 2;
1382 hisax_register(&hfc->d_if, p_b_if, "hfc_usb", hfc->protocol);
1383
1384#ifdef CONFIG_HISAX_DEBUG
1385 hfc_debug = debug;
1386#endif
1387
1388 for (i = 0; i < 4; i++)
1389 hfc->fifos[i].hif = &p_b_if[i / 2]->ifc;
1390 for (i = 4; i < 8; i++)
1391 hfc->fifos[i].hif = &hfc->d_if.ifc;
1392
1393 /* 3 (+1) INT IN + 3 ISO OUT */
1394 if (hfc->cfg_used == CNF_3INT3ISO || hfc->cfg_used == CNF_4INT3ISO) {
1395 start_int_fifo(hfc->fifos + HFCUSB_D_RX);
1396 if (hfc->fifos[HFCUSB_PCM_RX].pipe)
1397 start_int_fifo(hfc->fifos + HFCUSB_PCM_RX);
1398 start_int_fifo(hfc->fifos + HFCUSB_B1_RX);
1399 start_int_fifo(hfc->fifos + HFCUSB_B2_RX);
1400 }
1401 /* 3 (+1) ISO IN + 3 ISO OUT */
1402 if (hfc->cfg_used == CNF_3ISO3ISO || hfc->cfg_used == CNF_4ISO3ISO) {
1403 start_isoc_chain(hfc->fifos + HFCUSB_D_RX, ISOC_PACKETS_D,
1404 rx_iso_complete, 16);
1405 if (hfc->fifos[HFCUSB_PCM_RX].pipe)
1406 start_isoc_chain(hfc->fifos + HFCUSB_PCM_RX,
1407 ISOC_PACKETS_D, rx_iso_complete,
1408 16);
1409 start_isoc_chain(hfc->fifos + HFCUSB_B1_RX, ISOC_PACKETS_B,
1410 rx_iso_complete, 16);
1411 start_isoc_chain(hfc->fifos + HFCUSB_B2_RX, ISOC_PACKETS_B,
1412 rx_iso_complete, 16);
1413 }
1414
1415 start_isoc_chain(hfc->fifos + HFCUSB_D_TX, ISOC_PACKETS_D,
1416 tx_iso_complete, 1);
1417 start_isoc_chain(hfc->fifos + HFCUSB_B1_TX, ISOC_PACKETS_B,
1418 tx_iso_complete, 1);
1419 start_isoc_chain(hfc->fifos + HFCUSB_B2_TX, ISOC_PACKETS_B,
1420 tx_iso_complete, 1);
1421
1422 handle_led(hfc, LED_POWER_ON);
1423
1424 return (0);
1425} /* usb_init */
1426
1427/*************************************************/
1428/* function called to probe a new plugged device */
1429/*************************************************/
1430static int
1431hfc_usb_probe(struct usb_interface *intf, const struct usb_device_id *id)
1432{
1433 struct usb_device *dev = interface_to_usbdev(intf);
1434 hfcusb_data *context;
1435 struct usb_host_interface *iface = intf->cur_altsetting;
1436 struct usb_host_interface *iface_used = NULL;
1437 struct usb_host_endpoint *ep;
1438 int ifnum = iface->desc.bInterfaceNumber;
1439 int i, idx, alt_idx, probe_alt_setting, vend_idx, cfg_used, *vcf,
1440 attr, cfg_found, cidx, ep_addr;
1441 int cmptbl[16], small_match, iso_packet_size, packet_size,
1442 alt_used = 0;
1443
1444 vend_idx = 0xffff;
1445 for (i = 0; vdata[i].vendor; i++) {
1446 if (dev->descriptor.idVendor == vdata[i].vendor
1447 && dev->descriptor.idProduct == vdata[i].prod_id)
1448 vend_idx = i;
1449 }
1450#ifdef CONFIG_HISAX_DEBUG
1451 DBG(USB_DBG,
1452 "HFC-USB: probing interface(%d) actalt(%d) minor(%d)\n", ifnum,
1453 iface->desc.bAlternateSetting, intf->minor);
1454#endif
1455 printk(KERN_INFO
1456 "HFC-S USB: probing interface(%d) actalt(%d) minor(%d)\n",
1457 ifnum, iface->desc.bAlternateSetting, intf->minor);
1458
1459 if (vend_idx != 0xffff) {
1460#ifdef CONFIG_HISAX_DEBUG
1461 DBG(USB_DBG, "HFC-S USB: found vendor idx:%d name:%s",
1462 vend_idx, vdata[vend_idx].vend_name);
1463#endif
1464 /* if vendor and product ID is OK, start probing alternate settings */
1465 alt_idx = 0;
1466 small_match = 0xffff;
1467
1468 /* default settings */
1469 iso_packet_size = 16;
1470 packet_size = 64;
1471
1472 while (alt_idx < intf->num_altsetting) {
1473 iface = intf->altsetting + alt_idx;
1474 probe_alt_setting = iface->desc.bAlternateSetting;
1475 cfg_used = 0;
1476
1477 /* check for config EOL element */
1478 while (validconf[cfg_used][0]) {
1479 cfg_found = TRUE;
1480 vcf = validconf[cfg_used];
1481 /* first endpoint descriptor */
1482 ep = iface->endpoint;
1483#ifdef CONFIG_HISAX_DEBUG
1484 DBG(USB_DBG,
1485 "HFC-S USB: (if=%d alt=%d cfg_used=%d)\n",
1486 ifnum, probe_alt_setting, cfg_used);
1487#endif
1488 memcpy(cmptbl, vcf, 16 * sizeof(int));
1489
1490 /* check for all endpoints in this alternate setting */
1491 for (i = 0; i < iface->desc.bNumEndpoints;
1492 i++) {
1493 ep_addr =
1494 ep->desc.bEndpointAddress;
1495 /* get endpoint base */
1496 idx = ((ep_addr & 0x7f) - 1) * 2;
1497 if (ep_addr & 0x80)
1498 idx++;
1499 attr = ep->desc.bmAttributes;
1500 if (cmptbl[idx] == EP_NUL) {
1501 cfg_found = FALSE;
1502 }
1503 if (attr == USB_ENDPOINT_XFER_INT
1504 && cmptbl[idx] == EP_INT)
1505 cmptbl[idx] = EP_NUL;
1506 if (attr == USB_ENDPOINT_XFER_BULK
1507 && cmptbl[idx] == EP_BLK)
1508 cmptbl[idx] = EP_NUL;
1509 if (attr == USB_ENDPOINT_XFER_ISOC
1510 && cmptbl[idx] == EP_ISO)
1511 cmptbl[idx] = EP_NUL;
1512
1513 /* check if all INT endpoints match minimum interval */
1514 if (attr == USB_ENDPOINT_XFER_INT
1515 && ep->desc.bInterval <
1516 vcf[17]) {
1517#ifdef CONFIG_HISAX_DEBUG
1518 if (cfg_found)
1519 DBG(USB_DBG,
1520 "HFC-S USB: Interrupt Endpoint interval < %d found - skipping config",
1521 vcf[17]);
1522#endif
1523 cfg_found = FALSE;
1524 }
1525 ep++;
1526 }
1527 for (i = 0; i < 16; i++) {
1528 /* all entries must be EP_NOP or EP_NUL for a valid config */
1529 if (cmptbl[i] != EP_NOP
1530 && cmptbl[i] != EP_NUL)
1531 cfg_found = FALSE;
1532 }
1533 if (cfg_found) {
1534 if (cfg_used < small_match) {
1535 small_match = cfg_used;
1536 alt_used =
1537 probe_alt_setting;
1538 iface_used = iface;
1539 }
1540#ifdef CONFIG_HISAX_DEBUG
1541 DBG(USB_DBG,
1542 "HFC-USB: small_match=%x %x\n",
1543 small_match, alt_used);
1544#endif
1545 }
1546 cfg_used++;
1547 }
1548 alt_idx++;
1549 } /* (alt_idx < intf->num_altsetting) */
1550
1551 /* found a valid USB Ta Endpint config */
1552 if (small_match != 0xffff) {
1553 iface = iface_used;
1554 if (!
1555 (context =
1556 kmalloc(sizeof(hfcusb_data), GFP_KERNEL)))
1557 return (-ENOMEM); /* got no mem */
1558 memset(context, 0, sizeof(hfcusb_data));
1559
1560 ep = iface->endpoint;
1561 vcf = validconf[small_match];
1562
1563 for (i = 0; i < iface->desc.bNumEndpoints; i++) {
1564 ep_addr = ep->desc.bEndpointAddress;
1565 /* get endpoint base */
1566 idx = ((ep_addr & 0x7f) - 1) * 2;
1567 if (ep_addr & 0x80)
1568 idx++;
1569 cidx = idx & 7;
1570 attr = ep->desc.bmAttributes;
1571
1572 /* init Endpoints */
1573 if (vcf[idx] != EP_NOP
1574 && vcf[idx] != EP_NUL) {
1575 switch (attr) {
1576 case USB_ENDPOINT_XFER_INT:
1577 context->
1578 fifos[cidx].
1579 pipe =
1580 usb_rcvintpipe
1581 (dev,
1582 ep->desc.
1583 bEndpointAddress);
1584 context->
1585 fifos[cidx].
1586 usb_transfer_mode
1587 = USB_INT;
1588 packet_size =
1589 ep->desc.
1590 wMaxPacketSize;
1591 break;
1592 case USB_ENDPOINT_XFER_BULK:
1593 if (ep_addr & 0x80)
1594 context->
1595 fifos
1596 [cidx].
1597 pipe =
1598 usb_rcvbulkpipe
1599 (dev,
1600 ep->
1601 desc.
1602 bEndpointAddress);
1603 else
1604 context->
1605 fifos
1606 [cidx].
1607 pipe =
1608 usb_sndbulkpipe
1609 (dev,
1610 ep->
1611 desc.
1612 bEndpointAddress);
1613 context->
1614 fifos[cidx].
1615 usb_transfer_mode
1616 = USB_BULK;
1617 packet_size =
1618 ep->desc.
1619 wMaxPacketSize;
1620 break;
1621 case USB_ENDPOINT_XFER_ISOC:
1622 if (ep_addr & 0x80)
1623 context->
1624 fifos
1625 [cidx].
1626 pipe =
1627 usb_rcvisocpipe
1628 (dev,
1629 ep->
1630 desc.
1631 bEndpointAddress);
1632 else
1633 context->
1634 fifos
1635 [cidx].
1636 pipe =
1637 usb_sndisocpipe
1638 (dev,
1639 ep->
1640 desc.
1641 bEndpointAddress);
1642 context->
1643 fifos[cidx].
1644 usb_transfer_mode
1645 = USB_ISOC;
1646 iso_packet_size =
1647 ep->desc.
1648 wMaxPacketSize;
1649 break;
1650 default:
1651 context->
1652 fifos[cidx].
1653 pipe = 0;
1654 } /* switch attribute */
1655
1656 if (context->fifos[cidx].pipe) {
1657 context->fifos[cidx].
1658 fifonum = cidx;
1659 context->fifos[cidx].hfc =
1660 context;
1661 context->fifos[cidx].
1662 usb_packet_maxlen =
1663 ep->desc.
1664 wMaxPacketSize;
1665 context->fifos[cidx].
1666 intervall =
1667 ep->desc.bInterval;
1668 context->fifos[cidx].
1669 skbuff = NULL;
1670 }
1671 }
1672 ep++;
1673 }
1674 context->dev = dev; /* save device */
1675 context->if_used = ifnum; /* save used interface */
1676 context->alt_used = alt_used; /* and alternate config */
1677 context->ctrl_paksize = dev->descriptor.bMaxPacketSize0; /* control size */
1678 context->cfg_used = vcf[16]; /* store used config */
1679 context->vend_idx = vend_idx; /* store found vendor */
1680 context->packet_size = packet_size;
1681 context->iso_packet_size = iso_packet_size;
1682
1683 /* create the control pipes needed for register access */
1684 context->ctrl_in_pipe =
1685 usb_rcvctrlpipe(context->dev, 0);
1686 context->ctrl_out_pipe =
1687 usb_sndctrlpipe(context->dev, 0);
1688 context->ctrl_urb = usb_alloc_urb(0, GFP_KERNEL);
1689
1690 printk(KERN_INFO
1691 "HFC-S USB: detected \"%s\"\n",
1692 vdata[vend_idx].vend_name);
1693#ifdef CONFIG_HISAX_DEBUG
1694 DBG(USB_DBG,
1695 "HFC-S USB: Endpoint-Config: %s (if=%d alt=%d)\n",
1696 conf_str[small_match], context->if_used,
1697 context->alt_used);
1698 printk(KERN_INFO
1699 "HFC-S USB: E-channel (\"ECHO:\") logging ");
1700 if (validconf[small_match][18])
1701 printk(" possible\n");
1702 else
1703 printk("NOT possible\n");
1704#endif
1705 /* init the chip and register the driver */
1706 if (usb_init(context)) {
1707 if (context->ctrl_urb) {
1708 usb_unlink_urb(context->ctrl_urb);
1709 usb_free_urb(context->ctrl_urb);
1710 context->ctrl_urb = NULL;
1711 }
1712 kfree(context);
1713 return (-EIO);
1714 }
1715 usb_set_intfdata(intf, context);
1716 return (0);
1717 }
1718 } else {
1719 printk(KERN_INFO
1720 "HFC-S USB: no valid vendor found in USB descriptor\n");
1721 }
1722 return (-EIO);
1723}
1724
1725/****************************************************/
1726/* function called when an active device is removed */
1727/****************************************************/
1728static void
1729hfc_usb_disconnect(struct usb_interface
1730 *intf)
1731{
1732 hfcusb_data *context = usb_get_intfdata(intf);
1733 int i;
1734 printk(KERN_INFO "HFC-S USB: device disconnect\n");
1735 context->disc_flag = TRUE;
1736 usb_set_intfdata(intf, NULL);
1737 if (!context)
1738 return;
1739 if (timer_pending(&context->t3_timer))
1740 del_timer(&context->t3_timer);
1741 if (timer_pending(&context->t4_timer))
1742 del_timer(&context->t4_timer);
1743 if (timer_pending(&context->led_timer))
1744 del_timer(&context->led_timer);
1745 /* tell all fifos to terminate */
1746 for (i = 0; i < HFCUSB_NUM_FIFOS; i++) {
1747 if (context->fifos[i].usb_transfer_mode == USB_ISOC) {
1748 if (context->fifos[i].active > 0) {
1749 stop_isoc_chain(&context->fifos[i]);
1750#ifdef CONFIG_HISAX_DEBUG
1751 DBG(USB_DBG,
1752 "HFC-S USB: hfc_usb_disconnect: stopping ISOC chain Fifo no %i",
1753 i);
1754#endif
1755 }
1756 } else {
1757 if (context->fifos[i].active > 0) {
1758 context->fifos[i].active = 0;
1759#ifdef CONFIG_HISAX_DEBUG
1760 DBG(USB_DBG,
1761 "HFC-S USB: hfc_usb_disconnect: unlinking URB for Fifo no %i",
1762 i);
1763#endif
1764 }
1765 if (context->fifos[i].urb) {
1766 usb_unlink_urb(context->fifos[i].urb);
1767 usb_free_urb(context->fifos[i].urb);
1768 context->fifos[i].urb = NULL;
1769 }
1770 }
1771 context->fifos[i].active = 0;
1772 }
1773 /* wait for all URBS to terminate */
1774 mdelay(10);
1775 if (context->ctrl_urb) {
1776 usb_unlink_urb(context->ctrl_urb);
1777 usb_free_urb(context->ctrl_urb);
1778 context->ctrl_urb = NULL;
1779 }
1780 hisax_unregister(&context->d_if);
1781 kfree(context); /* free our structure again */
1782} /* hfc_usb_disconnect */
1783
1784/************************************/
1785/* our driver information structure */
1786/************************************/
1787static struct usb_driver hfc_drv = {
1788 .owner = THIS_MODULE,.name =
1789 "hfc_usb",.id_table = hfc_usb_idtab,.probe =
1790 hfc_usb_probe,.disconnect = hfc_usb_disconnect,
1791};
1792static void __exit
1793hfc_usb_exit(void)
1794{
1795#ifdef CONFIG_HISAX_DEBUG
1796 DBG(USB_DBG, "HFC-S USB: calling \"hfc_usb_exit\" ...");
1797#endif
1798 usb_deregister(&hfc_drv); /* release our driver */
1799 printk(KERN_INFO "HFC-S USB: module removed\n");
1800}
1801
1802static int __init
1803hfc_usb_init(void)
1804{
1805#ifndef CONFIG_HISAX_DEBUG
1806 unsigned int debug = -1;
1807#endif
1808 char revstr[30], datestr[30], dummy[30];
1809 sscanf(hfcusb_revision,
1810 "%s %s $ %s %s %s $ ", dummy, revstr,
1811 dummy, datestr, dummy);
1812 printk(KERN_INFO
1813 "HFC-S USB: driver module revision %s date %s loaded, (debug=%i)\n",
1814 revstr, datestr, debug);
1815 if (usb_register(&hfc_drv)) {
1816 printk(KERN_INFO
1817 "HFC-S USB: Unable to register HFC-S USB module at usb stack\n");
1818 return (-1); /* unable to register */
1819 }
1820 return (0);
1821}
1822
1823module_init(hfc_usb_init);
1824module_exit(hfc_usb_exit);
1825MODULE_AUTHOR(DRIVER_AUTHOR);
1826MODULE_DESCRIPTION(DRIVER_DESC);
1827MODULE_LICENSE("GPL");
1828MODULE_DEVICE_TABLE(usb, hfc_usb_idtab);