Contenu | Rechercher | Menus

Annonce

Si vous avez des soucis pour rester connecté, déconnectez-vous puis reconnectez-vous depuis ce lien en cochant la case
Me connecter automatiquement lors de mes prochaines visites.

À propos de l'équipe du forum.

#26 Le 31/05/2005, à 17:01

Cab

Re : Dongle USB Irda

ok ok, je suis hs mais je continue, je clique une nouvelle fois sur le lien que tu m'as donné pour les paquets et je vais relire les explications encore une fois, j'espère que je les comprendrai cette fois çi, tu vois j'y met vraiment du   mien car ça me tient à coeur

Hors ligne

#27 Le 31/05/2005, à 17:09

laurent

Re : Dongle USB Irda

ok... et si tu comprends pas qqchose, demande... Ce sera plus simple et constructif que d'abandonner.

Et arrete de sautiller comme ça.....


Laurent, petit belge explorant la banquise

Hors ligne

#28 Le 31/05/2005, à 17:22

Cab

Re : Dongle USB Irda

bon Laurent j'ai flingué le gestionnaire de paquets sad
il s'ouvre avec une erreur maintenant, j'ai essayé de rajouter dedans ce que j'ai sur le bureau, c'est la cata...

pour arrêter de sautiller il faudrait que celui qui se trouve en dessous de l'écran arrête lui aussi wink

Hors ligne

#29 Le 31/05/2005, à 17:29

laurent

Re : Dongle USB Irda

Bon, je crois qu'effectivement, tu comprends pas tout:

Tu ne devais pas intégrer les paquets télécharger dans apt, ça n'a rien à voir.

Apt-get et synaptic (idem mais graphique) se connectent aux serveurs qui rassemblent l'ensemble des paquets pour ubuntu et puis téléchargent et installent tranquillement, ceux que tu indiques, pour autant que ces logiciels soient dans les dépots.

C'est aussi simple que ça.

ici, tu as télécharger des paquets toi meme et tu pourrais les installer mais apt gère les dépendances automatiquement et ce sera bien plus simple, crois-moi.

Bon, ce que tu vas faire, maintenant:

1. sudo gedit /etc/apt/sources.list
2. Tu effaces ce qu'il y a dans ton sources.list et tu mets ça à la place:

deb http://fr.archive.ubuntu.com/ubuntu hoary main restricted multiverse universe
deb http://fr.archive.ubuntu.com/ubuntu hoary-updates main restricted multiverse universe
deb http://security.ubuntu.com/ubuntu hoary-security main restricted multiverse universe

3. tu enregistres et tu quittes
4. sudo apt-get update
5. sudo apt-get insall irda-utils

Je peux pas faire plus simple, là.


Laurent, petit belge explorant la banquise

Hors ligne

#30 Le 31/05/2005, à 17:30

Cab

Re : Dongle USB Irda

Voici l'erreur et montre moi comment réparer et installer un paquet qui est sur le bureau car honnêtement j'en ai marre sad

la fenêtre des dépots est bloqués je n'arrive donc pas à supprimer ce que j'ai mis

E: Ligne 16 mal formée dans la liste de sources /etc/apt/sources.list (distribution)
E: Impossible de lire la liste des sources.
Vous pouvez essayer de corriger le problème en ouvrant la fenêtre des dépôts.

Mince j'avais oublié

Dernière modification par Cab (Le 31/05/2005, à 17:33)

Hors ligne

#31 Le 31/05/2005, à 17:31

laurent

Re : Dongle USB Irda

euh... ben je te donnes la réponse ci-dessus...

et tu ne me donnes pas l'erreur...


Laurent, petit belge explorant la banquise

Hors ligne

#32 Le 31/05/2005, à 17:38

Cab

Re : Dongle USB Irda

Voilà ce qu'il est y dans le fichier source:

deb http://archive.ubuntu.com/ubuntu hoary main restricted
deb-src http://archive.ubuntu.com/ubuntu hoary main restricted

## Uncomment the following two lines to add software from the 'universe'
## repository.
## N.B. software from this repository is ENTIRELY UNSUPPORTED by the Ubuntu
## team, and may not be under a free licence. Please satisfy yourself as to
## your rights to use the software. Also, please note that software in
## universe WILL NOT receive any review or updates from the Ubuntu security
## team.
# deb http://archive.ubuntu.com/ubuntu hoary universe
# deb-src http://archive.ubuntu.com/ubuntu hoary universe

deb http://security.ubuntu.com/ubuntu hoary-security main restricted
deb-src http://security.ubuntu.com/ubuntu hoary-security main restricted
deb file:///home/ubuntu/Desktop/irda-common_0.9.14-17_i386.deb
 hoary-updates main restricted universe multiverse

Hors ligne

#33 Le 31/05/2005, à 17:42

laurent

Re : Dongle USB Irda

Tu effaces tout et tu mets les lignes que je t'ai donné.... comme je t'ai dit plus haut...

forcément aussi, t'as coupé une ligne en 2 avec ton deb-file... soit. fais comme je t'ai dit, tout ira bien


Laurent, petit belge explorant la banquise

Hors ligne

#34 Le 31/05/2005, à 17:46

Cab

Re : Dongle USB Irda

Ca y'est Laurent enfin ça a fonctionné merci !

Il ne faut pas installer aussi irda-common ?

Hors ligne

#35 Le 31/05/2005, à 18:25

Cab

Re : Dongle USB Irda

Bon rien à faire ça ne marche pas, en tout cas je vous remercie, Linux c'est pas fait pour moi dommage j'aimais bien je retourne à mon XP et mon IE6. Malgré ce forum conséquent je ne m'en sort pas, on ne peut pas tout connaître, même s'il y a une rubrique débutant, je ne crois pas qu'il faut être si débutant que ça sad

Merci à tous
Cab

Dernière modification par Cab (Le 31/05/2005, à 18:26)

Hors ligne

#36 Le 31/05/2005, à 18:38

laurent

Re : Dongle USB Irda

bon, ben dommage.

Juste quelques réflexions sur ton départ, si jamais tu reviens:

1. Ok que tu veuilles retourner sous windows, mais utiliser IE6, ça non, pas question. Utilise au moins firefox!

2. Quand tu changes de gsm, au début tu as un peu de mal dans les menus etc. Et parfois tu dois te rabattre sur le mode d'emploi et au final, tu devras changer tes habitudes. (idem voiture, télévision, etc) Ben changer d'OS, c'est la meme chose, en plus compliqué, je te l'accorde: il faut lire un minimum et essayer de comprendre la logique qu'il y a la derrière. Je pense d'ailleurs que c'est ça le plus important.

3. Perso mes premières expériences linux fures infructueuses car je voulais trop faire le rapport à windows. Le monde linux me paraissait énorme et insurmontable... Puis à force d'essais, je trouve ça 1000X plus simple. En tout cas, je comprends ce que je fais et l'utilité de ce que je fais.


Laurent, petit belge explorant la banquise

Hors ligne

#37 Le 31/05/2005, à 18:55

Cab

Re : Dongle USB Irda

En fait j'utilisais Maxthon sous moteur Gecko mais oui pourquoi pas FireFox que je trouve très bien.

Faut l'avouer c'est tout de même vachement complexe tout de même Linux, moi qui était resté au DOS, pour moi un sudo apt-get install irda-utils n'a aucune logique à ce jour. Je le tape sans réflexe et sans en comprendre la signification et là ben j'ai du mal car j'aime bien comprendre ce que je fait un minimum, c'est plutôt ça qui m'exaspère. Le nombre des comandes aussi. Toutes les manips que tu m'as fait faire, je n'y au rien compris, elles fonctionnent, soit mais à quoi bon continuer si ma petite cervelle n'arrive pas à assimiler tout ça sad

Non il faudrait un site pour le plus nul que nul avec comme exemple le montage d'un PC de A à Z avec exemple y compris l'irda qui maintenant est entré dans nos machines. Ce que tu fais une fois, soit tu le comprends peut-être pas en le recopiant, mais si tu t'y intéresse et si c'est surtout à ta portée, alors là tu persévère et je pense que tu fini par comprendre.

Par contre si tu patauges, tu finis à un moment par ne plus avoir goût pour ce que tu fais surtout si tu ne comprends pas ce que tu fais.

Non, mon choix de revenir à XP n'est pas définitif si je trouve le moyend e rester à Linux en "comprenant" et hélas je ne lis pas l'anglais et tous les sites que j'ai pu voir sont simple peut-être mais pas assez documenté pour moi bien sur.

Voilà Laurent mais quoi qu'il en soit, j'ai beaucoup de merci à vous dire car j'ai tout de même approché ce monde un peu particulier. wink

Hors ligne

#38 Le 31/05/2005, à 19:00

laurent

Re : Dongle USB Irda

pas de prob, je peux comprendre.

Mais je te ferais juste remarquer que sous win, je me débrouille pas mal, mais franchement, à part cliquer sur des fichiers exe, je comprends rien en fait. (je caricature, moi aussi je viens du dos).

Bon, quelques liens "de la dernière chance", alors... Que tu pourras lire tranquillement meme sous xp:

1. Le site linux pour les noobs:
http://www.trustonme.net/

et je te conseille au départ cette rubrique sur debian, dont ubuntu est adapté:
http://www.trustonme.net/categorie.php?id=18

2. la doc du site (pas assez mise en évidence à cause du forum qui marche vraiment bien. Soit):
http://www.ubuntu-fr.org/articles/

3. lea-linux:
http://www.lea-linux.org/

Bonne lecture et à bientôt


Laurent, petit belge explorant la banquise

Hors ligne

#39 Le 31/05/2005, à 19:24

Cab

Re : Dongle USB Irda

Merci Laurent,

Oui c'est vrai cliquer sur des exe n'est pas bandant en parlant vulgairement et c'est bien pour cela que j'ai été attiré par Linux.

Mais je le voyais comme une sorte de commandes DOS un peu plus élaborées mais c'est plus élaborées qu'elles sont les syntaxes, c'est carrément titanesques big_smile

En fait tu vois je me mettais à la place d'un conducteur de voiture. Pour utiliser un nouveau véhicule que tu ne connais pas tu ne démontes pas le moteur, tu ne cherches pas à savoir quel taux de compressions ont les cylindres, tu montes dedans et tu l'essayes en premier lieu, si elle t'emballe, alors il y a fort à parier que je chercherai à comprendre comment elle fonctionne.

Mais si je reste en première avec des sauts de puces parce que je ne comprends pas son fonctonnement, il est aussi fort à parier que soit je demanderai de l'aide, soit j'essayerai un autre modèle, soit j'en serai dégoûté.

Voilà quelle était mon idée en essayent Linux.

Allez un dernier essai, j'y passe la nuit s'il le faut et je me fait une idée définitive et je reviens te dire très honnêtement mon opinion.

Soit sur que tes liens seront visités et disséqués wink

Merci Laurent smile

Hors ligne

#40 Le 31/05/2005, à 20:26

racoon97

Re : Dongle USB Irda

Et bien c'est bien dommage d'abandonner si près du but, d'autant plus que tu avais l'air motivé  et plutot débrouillard pour un débutant.
Les lignes commandes des logiciels sont ce qu'il y a de plus logique au monde, il suffit de lire la doc existante, cela ne fais que quelques jours que tu t'y es mis, il y en a qui y sont depuis des années et qui ne maitrisent toujours pas tout.
Si c'étais moi  je critiquerais un peu plus ceux qui ont conçu ton systeme de clé USB infrarouge pour qu'il marche facilement sur MS Windows et qui n'ont fait aucun effort pour Linux, n'oublie que ce n'est que ce petit détail qui t'empéche de passer de l'autre coté du mur pour trouver l'espoir d'un monde meilleur. wink


Pas de logiciel de montage vidéo professionnel sous Linux ? Demandez à Sony son portage de Vegas Pro sous Linux... ou attendez Lightworks ;)

Hors ligne

#41 Le 31/05/2005, à 20:32

laurent

Re : Dongle USB Irda

racoon97 a écrit :

il y en a qui y sont depuis des années et qui ne maitrisent toujours pas tout.

t'es sûr que ça va le motiver, ça? wink

lol


Laurent, petit belge explorant la banquise

Hors ligne

#42 Le 31/05/2005, à 21:58

Cab

Re : Dongle USB Irda

Coucou, je viens vous faire une visite entre deux pages de lecture (j'en ai mal au crane). Racoon97, c'est gentil ce que tu me dis et j'appécie beaucoup mais j'ai absolument besoin de ma connexion irda pour sauter le pas. wink et c'est tout de même incroyable que depuis deux jours rien mais rien n'est dit la dessus. La seule commande qui fonctionne est celle de Laurent (aucun message d'erreur et la clé est reconnue) mais elle n'est pas démarrée et je ne trouve pas comment le faire.

Bon j'y retourne, je me suis donné jusqu'à demain (et bien j'en aurai lu des pages...)

à tout à l'heure wink

Hors ligne

#43 Le 31/05/2005, à 23:04

Cab

Re : Dongle USB Irda

C'est mal parti, je viens d'écumer les sites donnés et je n'y ai rien trouvé, vous en avez d'autres ?

Si cela peut aider j'ai trouvé cette commande:

ubuntu@ubuntu:~$ lsusb
Bus 011 Device 005: ID 413c:4001 Dell Computer Corp.
Bus 011 Device 001: ID 0000:0000
Bus 010 Device 002: ID 03f0:1e11 Hewlett-Packard PSC-950
Bus 010 Device 001: ID 0000:0000
Bus 009 Device 002: ID 046d:0901 Logitech, Inc. ClickSmart 510
Bus 009 Device 001: ID 0000:0000
Bus 008 Device 001: ID 0000:0000
Bus 007 Device 001: ID 0000:0000
Bus 006 Device 005: ID 0ea0:2168 Ours Technology, Inc. Transcend JetFlash 2.0
Bus 006 Device 004: ID 066f:4200 SigmaTel, Inc. STIr4200 IrDA Bridge
Bus 006 Device 002: ID 04b4:6560 Cypress Semiconductor Corp. CY7C65640 USB-2.0 "TetraHub"
Bus 006 Device 001: ID 0000:0000
Bus 005 Device 001: ID 0000:0000
Bus 004 Device 001: ID 0000:0000
Bus 003 Device 001: ID 0000:0000
Bus 002 Device 001: ID 0000:0000
Bus 001 Device 001: ID 0000:0000

Dell Computer: c'est mon PDA (Pocket PC)
Hewlett-Packard PSC-950: c'est mon imrpimante /scanner
Logitech Clicksmart: c'est ma Webcam
Ours Technology: c'est ma clé USB 2.0
Sigmatel STir4200: c'est ma clé usb IRDA
Cypress Semiconductor: c'est mon HUB 2.0

Seule ma clé USB fonctionne

Dernière modification par Cab (Le 31/05/2005, à 23:08)

Hors ligne

#44 Le 31/05/2005, à 23:22

racoon97

Re : Dongle USB Irda

je viens de trouver cette page : http://www.linux.com/howtos/Infrared-HOWTO/infrared-howto-s-irda-usb.shtml
C'est bien expliqué (en anglais mais facile d'accès quand même). Ca va nous permettre d'avancer un peu ...

Fais juste un

ifconfig

pour voir et vois si tu y trouve irda quelque part, si oui c'est quasiment résolu à mon avis. Je commence à piger le fonctionnement de ton périphérique schmilblick ...

Dernière modification par racoon97 (Le 31/05/2005, à 23:32)


Pas de logiciel de montage vidéo professionnel sous Linux ? Demandez à Sony son portage de Vegas Pro sous Linux... ou attendez Lightworks ;)

Hors ligne

#45 Le 31/05/2005, à 23:56

Cab

Re : Dongle USB Irda

Voici, mais j'ai l'impression que... voir en dessous hmm

ubuntu@ubuntu:~$ ifconfig
eth0      Lien encap:Ethernet  HWaddr 00:0B:6A:8D:51:C8
          adr inet6: fe80::20b:6aff:fe8d:51c8/64 Scope:Lien
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:21739 errors:0 dropped:0 overruns:0 frame:0
          TX packets:20445 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 lg file transmission:1000
          RX bytes:21419433 (20.4 MiB)  TX bytes:2515836 (2.3 MiB)
          Interruption:23 Adresse de base:0xd000

lo        Lien encap:Boucle locale
          inet adr:127.0.0.1  Masque:255.255.255.255
          adr inet6: ::1/128 Scope:Hôte
          UP LOOPBACK RUNNING  MTU:16436  Metric:1
          RX packets:174735 errors:0 dropped:0 overruns:0 frame:0
          TX packets:174735 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 lg file transmission:0
          RX bytes:15869208 (15.1 MiB)  TX bytes:15869208 (15.1 MiB)

ppp0      Lien encap:Protocole Point-à-Point
          inet adr:80.11.208.172  P-t-P:80.11.208.129  Masque:255.255.255.255
          UP POINTOPOINT RUNNING NOARP MULTICAST  MTU:1492  Metric:1
          RX packets:19257 errors:0 dropped:0 overruns:0 frame:0
          TX packets:17956 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 lg file transmission:3
          RX bytes:20846757 (19.8 MiB)  TX bytes:2045247 (1.9 MiB)

http://www.faqs.org/docs/Linux-HOWTO/In … onnections

Chapitre 3.1.4 hmm

Mais, il y a ça aussi qui pourrait faire fonctionner irda dongle mais ça dépasse mes compétences:

http://66.102.9.104/search?q=cache:2Xqo … nt=firefox

http://tuxmobil.org/Infrared-HOWTO/infr … #id2878405

http://66.102.9.104/search?q=cache:VHYp … nt=firefox

Il semblerait que cela soit possible mais en recompilant, je ne sais même pas ce que ça veut dire.

J'ai également récupéré un driver stir4200.tgz et usbirda.tgz

Donc pour moi j'en arrête là, si quelqu'un à une solution qu'il n'hésite pas à me dire ce qu'il faut faire et ce sera avec un grand plaisir que cette fois je dirai adieu définitivement à windaube smile

Le dernier lien exactement la clé USB Irda que j'ai wink

Dernière modification par Cab (Le 01/06/2005, à 00:51)

Hors ligne

#46 Le 01/06/2005, à 06:02

Cab

Re : Dongle USB Irda

Ca y'est j'ai trouvé un driver stir4200.c qui fonctionne, qui pourrait me le compiler et me dire comment l'installer ?

Merci smile

1 /*****************************************************************************
  2 *
  3 * Filename:      stir4200.c
  4 * Version:       0.4
  5 * Description:   Irda SigmaTel USB Dongle
  6 * Status:        Experimental
  7 * Author:        Stephen Hemminger <shemminger@osdl.org>
  8 *
  9 *       Based on earlier driver by Paul Stewart <stewart@parc.com>
 10 *
 11 *       Copyright (C) 2000, Roman Weissgaerber <weissg@vienna.at>
 12 *       Copyright (C) 2001, Dag Brattli <dag@brattli.net>
 13 *       Copyright (C) 2001, Jean Tourrilhes <jt@hpl.hp.com>
 14 *       Copyright (C) 2004, Stephen Hemminger <shemminger@osdl.org>
 15 *
 16 *       This program is free software; you can redistribute it and/or modify
 17 *       it under the terms of the GNU General Public License as published by
 18 *       the Free Software Foundation; either version 2 of the License, or
 19 *       (at your option) any later version.
 20 *
 21 *       This program is distributed in the hope that it will be useful,
 22 *       but WITHOUT ANY WARRANTY; without even the implied warranty of
 23 *       MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 24 *       GNU General Public License for more details.
 25 *
 26 *       You should have received a copy of the GNU General Public License
 27 *       along with this program; if not, write to the Free Software
 28 *       Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 29 *
 30 *****************************************************************************/
 31 
 32 /*
 33  * This dongle does no framing, and requires polling to receive the
 34  * data.  The STIr4200 has bulk in and out endpoints just like
 35  * usr-irda devices, but the data it sends and receives is raw; like
 36  * irtty, it needs to call the wrap and unwrap functions to add and
 37  * remove SOF/BOF and escape characters to/from the frame.
 38  */
 39 
 40 #include <linux/module.h>
 41 #include <linux/moduleparam.h>
 42 
 43 #include <linux/kernel.h>
 44 #include <linux/types.h>
 45 #include <linux/init.h>
 46 #include <linux/time.h>
 47 #include <linux/skbuff.h>
 48 #include <linux/netdevice.h>
 49 #include <linux/suspend.h>
 50 #include <linux/slab.h>
 51 #include <linux/usb.h>
 52 #include <linux/crc32.h>
 53 #include <net/irda/irda.h>
 54 #include <net/irda/irlap.h>
 55 #include <net/irda/irda_device.h>
 56 #include <net/irda/wrapper.h>
 57 #include <net/irda/crc.h>
 58 #include <asm/byteorder.h>
 59 #include <asm/unaligned.h>
 60 
 61 MODULE_AUTHOR("Stephen Hemminger <shemminger@osdl.org>");
 62 MODULE_DESCRIPTION("IrDA-USB Dongle Driver for SigmaTel STIr4200");
 63 MODULE_LICENSE("GPL");
 64 
 65 static int qos_mtt_bits = 0x07; /* 1 ms or more */
 66 module_param(qos_mtt_bits, int, 0);
 67 MODULE_PARM_DESC(qos_mtt_bits, "Minimum Turn Time");
 68 
 69 static int rx_sensitivity = 1;  /* FIR 0..4, SIR 0..6 */
 70 module_param(rx_sensitivity, int, 0);
 71 MODULE_PARM_DESC(rx_sensitivity, "Set Receiver sensitivity (0-6, 0 is most sensitive)");
 72 
 73 static int tx_power = 0;        /* 0 = highest ... 3 = lowest */
 74 module_param(tx_power, int, 0);
 75 MODULE_PARM_DESC(tx_power, "Set Transmitter power (0-3, 0 is highest power)");
 76 
 77 #define STIR_IRDA_HEADER        4
 78 #define CTRL_TIMEOUT            100        /* milliseconds */
 79 #define TRANSMIT_TIMEOUT        200        /* milliseconds */
 80 #define STIR_FIFO_SIZE          4096
 81 #define FIFO_REGS_SIZE          3
 82 
 83 enum FirChars {
 84         FIR_CE   = 0x7d,
 85         FIR_XBOF = 0x7f,
 86         FIR_EOF  = 0x7e,
 87 };
 88 
 89 enum StirRequests {
 90         REQ_WRITE_REG =         0x00,
 91         REQ_READ_REG =          0x01,
 92         REQ_READ_ROM =          0x02,
 93         REQ_WRITE_SINGLE =      0x03,
 94 };
 95 
 96 /* Register offsets */
 97 enum StirRegs {
 98         REG_RSVD=0,
 99         REG_MODE,
100         REG_PDCLK,
101         REG_CTRL1,
102         REG_CTRL2,
103         REG_FIFOCTL,
104         REG_FIFOLSB,
105         REG_FIFOMSB,
106         REG_DPLL,
107         REG_IRDIG,
108         REG_TEST=15,
109 };
110 
111 enum StirModeMask {
112         MODE_FIR = 0x80,
113         MODE_SIR = 0x20,
114         MODE_ASK = 0x10,
115         MODE_FASTRX = 0x08,
116         MODE_FFRSTEN = 0x04,
117         MODE_NRESET = 0x02,
118         MODE_2400 = 0x01,
119 };
120 
121 enum StirPdclkMask {
122         PDCLK_4000000 = 0x02,
123         PDCLK_115200 = 0x09,
124         PDCLK_57600 = 0x13,
125         PDCLK_38400 = 0x1D,
126         PDCLK_19200 = 0x3B,
127         PDCLK_9600 = 0x77,
128         PDCLK_2400 = 0xDF,
129 };
130 
131 enum StirCtrl1Mask {
132         CTRL1_SDMODE = 0x80,
133         CTRL1_RXSLOW = 0x40,
134         CTRL1_TXPWD = 0x10,
135         CTRL1_RXPWD = 0x08,
136         CTRL1_SRESET = 0x01,
137 };
138 
139 enum StirCtrl2Mask {
140         CTRL2_SPWIDTH = 0x08,
141         CTRL2_REVID = 0x03,
142 };
143 
144 enum StirFifoCtlMask {
145         FIFOCTL_EOF = 0x80,
146         FIFOCTL_UNDER = 0x40,
147         FIFOCTL_OVER = 0x20,
148         FIFOCTL_DIR = 0x10,
149         FIFOCTL_CLR = 0x08,
150         FIFOCTL_EMPTY = 0x04,
151         FIFOCTL_RXERR = 0x02,
152         FIFOCTL_TXERR = 0x01,
153 };
154 
155 enum StirDiagMask {
156         IRDIG_RXHIGH = 0x80,
157         IRDIG_RXLOW = 0x40,
158 };
159 
160 enum StirTestMask {
161         TEST_PLLDOWN = 0x80,
162         TEST_LOOPIR = 0x40,
163         TEST_LOOPUSB = 0x20,
164         TEST_TSTENA = 0x10,
165         TEST_TSTOSC = 0x0F,
166 };
167 
168 struct stir_cb {
169         struct usb_device *usbdev;      /* init: probe_irda */
170         struct net_device *netdev;      /* network layer */
171         struct irlap_cb   *irlap;       /* The link layer we are binded to */
172         struct net_device_stats stats;  /* network statistics */
173         struct qos_info   qos;
174         unsigned          speed;        /* Current speed */
175 
176         wait_queue_head_t thr_wait;     /* transmit thread wakeup */
177         struct completion thr_exited;
178         pid_t             thr_pid;
179 
180         struct sk_buff    *tx_pending;
181         void              *io_buf;      /* transmit/receive buffer */
182         __u8              *fifo_status;
183 
184         iobuff_t          rx_buff;      /* receive unwrap state machine */
185         struct timeval    rx_time;
186         int               receiving;
187         struct urb       *rx_urb;
188 };
189 
190 
191 /* These are the currently known USB ids */
192 static struct usb_device_id dongles[] = {
193     /* SigmaTel, Inc,  STIr4200 IrDA/USB Bridge */
194     { USB_DEVICE(0x066f, 0x4200) },
195     { }
196 };
197 
198 MODULE_DEVICE_TABLE(usb, dongles);
199 
200 /* Send control message to set dongle register */
201 static int write_reg(struct stir_cb *stir, __u16 reg, __u8 value)
202 {
203         struct usb_device *dev = stir->usbdev;
204 
205         pr_debug("%s: write reg %d = 0x%x\n",
206                  stir->netdev->name, reg, value);
207         return usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
208                                REQ_WRITE_SINGLE,
209                                USB_DIR_OUT|USB_TYPE_VENDOR|USB_RECIP_DEVICE,
210                                value, reg, NULL, 0,
211                                MSECS_TO_JIFFIES(CTRL_TIMEOUT));
212 }
213 
214 /* Send control message to read multiple registers */
215 static inline int read_reg(struct stir_cb *stir, __u16 reg,
216                     __u8 *data, __u16 count)
217 {
218         struct usb_device *dev = stir->usbdev;
219 
220         return usb_control_msg(dev, usb_rcvctrlpipe(dev, 0),
221                                REQ_READ_REG,
222                                USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
223                                0, reg, data, count,
224                                MSECS_TO_JIFFIES(CTRL_TIMEOUT));
225 }
226 
227 static inline int isfir(u32 speed)
228 {
229         return (speed == 4000000);
230 }
231 
232 /*
233  * Prepare a FIR IrDA frame for transmission to the USB dongle.  The
234  * FIR transmit frame is documented in the datasheet.  It consists of
235  * a two byte 0x55 0xAA sequence, two little-endian length bytes, a
236  * sequence of exactly 16 XBOF bytes of 0x7E, two BOF bytes of 0x7E,
237  * then the data escaped as follows:
238  *
239  *    0x7D -> 0x7D 0x5D
240  *    0x7E -> 0x7D 0x5E
241  *    0x7F -> 0x7D 0x5F
242  *
243  * Then, 4 bytes of little endian (stuffed) FCS follow, then two
244  * trailing EOF bytes of 0x7E.
245  */
246 static inline __u8 *stuff_fir(__u8 *p, __u8 c)
247 {
248         switch(c) {
249         case 0x7d:
250         case 0x7e:
251         case 0x7f:
252                 *p++ = 0x7d;
253                 c ^= IRDA_TRANS;
254                 /* fall through */
255         default:
256                 *p++ = c;
257         }
258         return p;
259 }
260 
261 /* Take raw data in skb and put it wrapped into buf */
262 static unsigned wrap_fir_skb(const struct sk_buff *skb, __u8 *buf)
263 {
264         __u8 *ptr = buf;
265         __u32 fcs = ~(crc32_le(~0, skb->data, skb->len));
266         __u16 wraplen;
267         int i;
268 
269         /* Header */
270         buf[0] = 0x55;
271         buf[1] = 0xAA;
272 
273         ptr = buf + STIR_IRDA_HEADER;
274         memset(ptr, 0x7f, 16);
275         ptr += 16;
276 
277         /* BOF */
278         *ptr++  = 0x7e;
279         *ptr++  = 0x7e;
280 
281         /* Address / Control / Information */
282         for (i = 0; i < skb->len; i++)
283                 ptr = stuff_fir(ptr, skb->data[i]);
284 
285         /* FCS */
286         ptr = stuff_fir(ptr, fcs & 0xff);
287         ptr = stuff_fir(ptr, (fcs >> 8) & 0xff);
288         ptr = stuff_fir(ptr, (fcs >> 16) & 0xff);
289         ptr = stuff_fir(ptr, (fcs >> 24) & 0xff);
290 
291         /* EOFs */
292         *ptr++ = 0x7e;
293         *ptr++ = 0x7e;
294 
295         /* Total length, minus the header */
296         wraplen = (ptr - buf) - STIR_IRDA_HEADER;
297         buf[2] = wraplen & 0xff;
298         buf[3] = (wraplen >> 8) & 0xff;
299 
300         return wraplen + STIR_IRDA_HEADER;
301 }
302 
303 static unsigned wrap_sir_skb(struct sk_buff *skb, __u8 *buf)
304 {
305         __u16 wraplen;
306 
307         wraplen = async_wrap_skb(skb, buf + STIR_IRDA_HEADER,
308                                  STIR_FIFO_SIZE - STIR_IRDA_HEADER);
309         buf[0] = 0x55;
310         buf[1] = 0xAA;
311         buf[2] = wraplen & 0xff;
312         buf[3] = (wraplen >> 8) & 0xff;
313 
314         return wraplen + STIR_IRDA_HEADER;
315 }
316 
317 /*
318  * Frame is fully formed in the rx_buff so check crc
319  * and pass up to irlap
320  * setup for next receive
321  */
322 static void fir_eof(struct stir_cb *stir)
323 {
324         iobuff_t *rx_buff = &stir->rx_buff;
325         int len = rx_buff->len - 4;
326         struct sk_buff *skb, *nskb;
327         __u32 fcs;
328 
329         if (unlikely(len <= 0)) {
330                 pr_debug("%s: short frame len %d\n",
331                          stir->netdev->name, len);
332 
333                 ++stir->stats.rx_errors;
334                 ++stir->stats.rx_length_errors;
335                 return;
336         }
337 
338         fcs = ~(crc32_le(~0, rx_buff->data, len));
339         if (fcs != le32_to_cpu(get_unaligned((u32 *)(rx_buff->data+len)))) {
340                 pr_debug("crc error calc 0x%x len %d\n", fcs, len);
341                 stir->stats.rx_errors++;
342                 stir->stats.rx_crc_errors++;
343                 return;
344         }
345 
346         /* if frame is short then just copy it */
347         if (len < IRDA_RX_COPY_THRESHOLD) {
348                 nskb = dev_alloc_skb(len + 1);
349                 if (unlikely(!nskb)) {
350                         ++stir->stats.rx_dropped;
351                         return;
352                 }
353                 skb_reserve(nskb, 1);
354                 skb = nskb;
355                 memcpy(nskb->data, rx_buff->data, len);
356         } else {
357                 nskb = dev_alloc_skb(rx_buff->truesize);
358                 if (unlikely(!nskb)) {
359                         ++stir->stats.rx_dropped;
360                         return;
361                 }
362                 skb_reserve(nskb, 1);
363                 skb = rx_buff->skb;
364                 rx_buff->skb = nskb;
365                 rx_buff->head = nskb->data;
366         }
367 
368         skb_put(skb, len);
369 
370         skb->mac.raw  = skb->data;
371         skb->protocol = htons(ETH_P_IRDA);
372         skb->dev = stir->netdev;
373 
374         netif_rx(skb);
375 
376         stir->stats.rx_packets++;
377         stir->stats.rx_bytes += len;
378 
379         rx_buff->data = rx_buff->head;
380         rx_buff->len = 0;
381 }
382 
383 /* Unwrap FIR stuffed data and bump it to IrLAP */
384 static void stir_fir_chars(struct stir_cb *stir,
385                             const __u8 *bytes, int len)
386 {
387         iobuff_t *rx_buff = &stir->rx_buff;
388         int     i;
389 
390         for (i = 0; i < len; i++) {
391                 __u8    byte = bytes[i];
392 
393                 switch(rx_buff->state) {
394                 case OUTSIDE_FRAME:
395                         /* ignore garbage till start of frame */
396                         if (unlikely(byte != FIR_EOF))
397                                 continue;
398                         /* Now receiving frame */
399                         rx_buff->state = BEGIN_FRAME;
400 
401                         /* Time to initialize receive buffer */
402                         rx_buff->data = rx_buff->head;
403                         rx_buff->len = 0;
404                         continue;
405 
406                 case LINK_ESCAPE:
407                         if (byte == FIR_EOF) {
408                                 pr_debug("%s: got EOF after escape\n",
409                                          stir->netdev->name);
410                                 goto frame_error;
411                         }
412                         rx_buff->state = INSIDE_FRAME;
413                         byte ^= IRDA_TRANS;
414                         break;
415 
416                 case BEGIN_FRAME:
417                         /* ignore multiple BOF/EOF */
418                         if (byte == FIR_EOF)
419                                 continue;
420                         rx_buff->state = INSIDE_FRAME;
421                         rx_buff->in_frame = TRUE;
422 
423                         /* fall through */
424                 case INSIDE_FRAME:
425                         switch(byte) {
426                         case FIR_CE:
427                                 rx_buff->state = LINK_ESCAPE;
428                                 continue;
429                         case FIR_XBOF:
430                                 /* 0x7f is not used in this framing */
431                                 pr_debug("%s: got XBOF without escape\n",
432                                          stir->netdev->name);
433                                 goto frame_error;
434                         case FIR_EOF:
435                                 rx_buff->state = OUTSIDE_FRAME;
436                                 rx_buff->in_frame = FALSE;
437                                 fir_eof(stir);
438                                 continue;
439                         }
440                         break;
441                 }
442 
443                 /* add byte to rx buffer */
444                 if (unlikely(rx_buff->len >= rx_buff->truesize)) {
445                         pr_debug("%s: fir frame exceeds %d\n",
446                                  stir->netdev->name, rx_buff->truesize);
447                         ++stir->stats.rx_over_errors;
448                         goto error_recovery;
449                 }
450 
451                 rx_buff->data[rx_buff->len++] = byte;
452                 continue;
453 
454         frame_error:
455                 ++stir->stats.rx_frame_errors;
456 
457         error_recovery:
458                 ++stir->stats.rx_errors;
459                 rx_buff->state = OUTSIDE_FRAME;
460                 rx_buff->in_frame = FALSE;
461         }
462 }
463 
464 /* Unwrap SIR stuffed data and bump it up to IrLAP */
465 static void stir_sir_chars(struct stir_cb *stir,
466                             const __u8 *bytes, int len)
467 {
468         int i;
469 
470         for (i = 0; i < len; i++)
471                 async_unwrap_char(stir->netdev, &stir->stats,
472                                   &stir->rx_buff, bytes[i]);
473 }
474 
475 static inline void unwrap_chars(struct stir_cb *stir,
476                                 const __u8 *bytes, int length)
477 {
478         if (isfir(stir->speed))
479                 stir_fir_chars(stir, bytes, length);
480         else
481                 stir_sir_chars(stir, bytes, length);
482 }
483 
484 /* Mode parameters for each speed */
485 static const struct {
486         unsigned speed;
487         __u8 pdclk;
488 } stir_modes[] = {
489         { 2400,    PDCLK_2400 },
490         { 9600,    PDCLK_9600 },
491         { 19200,   PDCLK_19200 },
492         { 38400,   PDCLK_38400 },
493         { 57600,   PDCLK_57600 },
494         { 115200,  PDCLK_115200 },
495         { 4000000, PDCLK_4000000 },
496 };
497 
498 
499 /*
500  * Setup chip for speed.
501  *  Called at startup to initialize the chip
502  *  and on speed changes.
503  *
504  * Note: Write multiple registers doesn't appear to work
505  */
506 static int change_speed(struct stir_cb *stir, unsigned speed)
507 {
508         int i, err;
509         __u8 mode;
510 
511         for (i = 0; i < ARRAY_SIZE(stir_modes); ++i) {
512                 if (speed == stir_modes[i].speed)
513                         goto found;
514         }
515 
516         warn("%s: invalid speed %d", stir->netdev->name, speed);
517         return -EINVAL;
518 
519  found:
520         pr_debug("speed change from %d to %d\n", stir->speed, speed);
521 
522         /* sometimes needed to get chip out of stuck state */
523         err = usb_reset_device(stir->usbdev);
524         if (err)
525                 goto out;
526 
527         /* Reset modulator */
528         err = write_reg(stir, REG_CTRL1, CTRL1_SRESET);
529         if (err)
530                 goto out;
531 
532         /* Undocumented magic to tweak the DPLL */
533         err = write_reg(stir, REG_DPLL, 0x15);
534         if (err)
535                 goto out;
536 
537         /* Set clock */
538         err = write_reg(stir, REG_PDCLK, stir_modes[i].pdclk);
539         if (err)
540                 goto out;
541 
542         mode = MODE_NRESET | MODE_FASTRX;
543         if (isfir(speed))
544                 mode |= MODE_FIR | MODE_FFRSTEN;
545         else
546                 mode |= MODE_SIR;
547 
548         if (speed == 2400)
549                 mode |= MODE_2400;
550 
551         err = write_reg(stir, REG_MODE, mode);
552         if (err)
553                 goto out;
554 
555         /* This resets TEMIC style transceiver if any. */
556         err = write_reg(stir, REG_CTRL1,
557                         CTRL1_SDMODE | (tx_power & 3) << 1);
558         if (err)
559                 goto out;
560 
561         err = write_reg(stir, REG_CTRL1, (tx_power & 3) << 1);
562         if (err)
563                 goto out;
564 
565         /* Reset sensitivity */
566         err = write_reg(stir, REG_CTRL2, (rx_sensitivity & 7) << 5);
567  out:
568         stir->speed = speed;
569         return err;
570 }
571 
572 /*
573  * Called from net/core when new frame is available.
574  */
575 static int stir_hard_xmit(struct sk_buff *skb, struct net_device *netdev)
576 {
577         struct stir_cb *stir = netdev->priv;
578 
579         netif_stop_queue(netdev);
580 
581         /* the IRDA wrapping routines don't deal with non linear skb */
582         SKB_LINEAR_ASSERT(skb);
583 
584         skb = xchg(&stir->tx_pending, skb);
585         wake_up(&stir->thr_wait);
586         
587         /* this should never happen unless stop/wakeup problem */
588         if (unlikely(skb)) {
589                 WARN_ON(1);
590                 dev_kfree_skb(skb);
591         }
592 
593         return 0;
594 }
595 
596 /*
597  * Wait for the transmit FIFO to have space for next data
598  *
599  * If space < 0 then wait till FIFO completely drains.
600  * FYI: can take up to 13 seconds at 2400baud.
601  */
602 static int fifo_txwait(struct stir_cb *stir, int space)
603 {
604         int err;
605         unsigned long count, status;
606 
607         /* Read FIFO status and count */
608         for(;;) {
609                 err = read_reg(stir, REG_FIFOCTL, stir->fifo_status, 
610                                    FIFO_REGS_SIZE);
611                 if (unlikely(err != FIFO_REGS_SIZE)) {
612                         warn("%s: FIFO register read error: %d", 
613                              stir->netdev->name, err);
614 
615                         return err;
616                 }
617 
618                 status = stir->fifo_status[0];
619                 count = (unsigned)(stir->fifo_status[2] & 0x1f) << 8 
620                         | stir->fifo_status[1];
621 
622                 pr_debug("fifo status 0x%lx count %lu\n", status, count);
623 
624                 /* error when receive/transmit fifo gets confused */
625                 if (status & FIFOCTL_RXERR) {
626                         stir->stats.rx_fifo_errors++;
627                         stir->stats.rx_errors++;
628                         break;
629                 }
630 
631                 if (status & FIFOCTL_TXERR) {
632                         stir->stats.tx_fifo_errors++;
633                         stir->stats.tx_errors++;
634                         break;
635                 }
636 
637                 /* is fifo receiving already, or empty */
638                 if (!(status & FIFOCTL_DIR)
639                     || (status & FIFOCTL_EMPTY))
640                         return 0;
641 
642                 if (signal_pending(current))
643                         return -EINTR;
644 
645                 /* shutting down? */
646                 if (!netif_running(stir->netdev)
647                     || !netif_device_present(stir->netdev))
648                         return -ESHUTDOWN;
649 
650                 /* only waiting for some space */
651                 if (space >= 0 && STIR_FIFO_SIZE - 4 > space + count)
652                         return 0;
653 
654                 /* estimate transfer time for remaining chars */
655                 wait_ms((count * 8000) / stir->speed);
656         }
657                         
658         err = write_reg(stir, REG_FIFOCTL, FIFOCTL_CLR);
659         if (err) 
660                 return err;
661         err = write_reg(stir, REG_FIFOCTL, 0);
662         if (err)
663                 return err;
664 
665         return 0;
666 }
667 
668 
669 /* Wait for turnaround delay before starting transmit.  */
670 static void turnaround_delay(const struct stir_cb *stir, long us)
671 {
672         long ticks;
673         struct timeval now;
674 
675         if (us <= 0)
676                 return;
677 
678         do_gettimeofday(&now);
679         us -= (now.tv_sec - stir->rx_time.tv_sec) * USEC_PER_SEC;
680         us -= now.tv_usec - stir->rx_time.tv_usec;
681         if (us < 10)
682                 return;
683 
684         ticks = us / (1000000 / HZ);
685         if (ticks > 0) {
686                 current->state = TASK_INTERRUPTIBLE;
687                 schedule_timeout(1 + ticks);
688         } else
689                 udelay(us);
690 }
691 
692 /*
693  * Start receiver by submitting a request to the receive pipe.
694  * If nothing is available it will return after rx_interval.
695  */
696 static int receive_start(struct stir_cb *stir)
697 {
698         /* reset state */
699         stir->receiving = 1;
700 
701         stir->rx_buff.in_frame = FALSE;
702         stir->rx_buff.state = OUTSIDE_FRAME;
703 
704         stir->rx_urb->status = 0;
705         return usb_submit_urb(stir->rx_urb, GFP_KERNEL);
706 }
707 
708 /* Stop all pending receive Urb's */
709 static void receive_stop(struct stir_cb *stir)
710 {
711         stir->receiving = 0;
712         usb_unlink_urb(stir->rx_urb);
713 
714         if (stir->rx_buff.in_frame) 
715                 stir->stats.collisions++;
716 }
717 /*
718  * Wrap data in socket buffer and send it.
719  */
720 static void stir_send(struct stir_cb *stir, struct sk_buff *skb)
721 {
722         unsigned wraplen;
723         int first_frame = 0;
724 
725         /* if receiving, need to turnaround */
726         if (stir->receiving) {
727                 receive_stop(stir);
728                 turnaround_delay(stir, irda_get_mtt(skb));
729                 first_frame = 1;
730         }
731 
732         if (isfir(stir->speed))
733                 wraplen = wrap_fir_skb(skb, stir->io_buf);
734         else
735                 wraplen = wrap_sir_skb(skb, stir->io_buf);
736                 
737         /* check for space available in fifo */
738         if (!first_frame)
739                 fifo_txwait(stir, wraplen);
740 
741         stir->stats.tx_packets++;
742         stir->stats.tx_bytes += skb->len;
743         stir->netdev->trans_start = jiffies;
744         pr_debug("send %d (%d)\n", skb->len, wraplen);
745 
746         if (usb_bulk_msg(stir->usbdev, usb_sndbulkpipe(stir->usbdev, 1),
747                          stir->io_buf, wraplen,
748                          NULL, MSECS_TO_JIFFIES(TRANSMIT_TIMEOUT))) 
749                 stir->stats.tx_errors++;
750 }
751 
752 /*
753  * Transmit state machine thread
754  */
755 static int stir_transmit_thread(void *arg)
756 {
757         struct stir_cb *stir = arg;
758         struct net_device *dev = stir->netdev;
759         struct sk_buff *skb;
760 
761         daemonize("%s", dev->name);
762         allow_signal(SIGTERM);
763 
764         while (netif_running(dev)
765                && netif_device_present(dev)
766                && !signal_pending(current))
767         {
768                 /* if suspending, then power off and wait */
769                 if (current->flags & PF_FREEZE) {
770                         if (stir->receiving)
771                                 receive_stop(stir);
772                         else
773                                 fifo_txwait(stir, -1);
774 
775                         write_reg(stir, REG_CTRL1, CTRL1_TXPWD|CTRL1_RXPWD);
776 
777                         refrigerator(PF_IOTHREAD);
778 
779                         if (change_speed(stir, stir->speed))
780                                 break;
781                 }
782 
783                 /* if something to send? */
784                 skb = xchg(&stir->tx_pending, NULL);
785                 if (skb) {
786                         unsigned new_speed = irda_get_next_speed(skb);
787                         netif_wake_queue(dev);
788 
789                         if (skb->len > 0)
790                                 stir_send(stir, skb);
791                         dev_kfree_skb(skb);
792 
793                         if (stir->speed != new_speed) {
794                                 if (fifo_txwait(stir, -1) ||
795                                     change_speed(stir, new_speed))
796                                         break;
797                         }
798                         continue;
799                 }
800 
801                 /* nothing to send? start receiving */
802                 if (!stir->receiving 
803                     && irda_device_txqueue_empty(dev)) {
804                         /* Wait otherwise chip gets confused. */
805                         if (fifo_txwait(stir, -1))
806                                 break;
807 
808                         if (unlikely(receive_start(stir))) {
809                                 if (net_ratelimit())
810                                         info("%s: receive usb submit failed",
811                                              stir->netdev->name);
812                                 stir->receiving = 0;
813                                 wait_ms(10);
814                                 continue;
815                         }
816                 }
817 
818                 /* sleep if nothing to send */
819                 wait_event_interruptible(stir->thr_wait, stir->tx_pending);
820         }
821 
822         complete_and_exit (&stir->thr_exited, 0);
823 }
824 
825 
826 /*
827  * USB bulk receive completion callback.
828  * Wakes up every ms (usb round trip) with wrapped 
829  * data.
830  */
831 static void stir_rcv_irq(struct urb *urb, struct pt_regs *regs)
832 {
833         struct stir_cb *stir = urb->context;
834         int err;
835 
836         /* in process of stopping, just drop data */
837         if (!netif_running(stir->netdev))
838                 return;
839 
840         /* unlink, shutdown, unplug, other nasties */
841         if (urb->status != 0) 
842                 return;
843 
844         if (urb->actual_length > 0) {
845                 pr_debug("receive %d\n", urb->actual_length);
846                 unwrap_chars(stir, urb->transfer_buffer,
847                              urb->actual_length);
848                 
849                 stir->netdev->last_rx = jiffies;
850                 do_gettimeofday(&stir->rx_time);
851         }
852 
853         /* kernel thread is stopping receiver don't resubmit */
854         if (!stir->receiving)
855                 return;
856 
857         /* resubmit existing urb */
858         err = usb_submit_urb(urb, GFP_ATOMIC);
859 
860         /* in case of error, the kernel thread will restart us */
861         if (err) {
862                 warn("%s: usb receive submit error: %d",
863                         stir->netdev->name, err);
864                 stir->receiving = 0;
865                 wake_up(&stir->thr_wait);
866         }
867 }
868 
869 /*
870  * Function stir_net_open (dev)
871  *
872  *    Network device is taken up. Usually this is done by "ifconfig irda0 up"
873  */
874 static int stir_net_open(struct net_device *netdev)
875 {
876         struct stir_cb *stir = netdev->priv;
877         int err;
878         char hwname[16];
879 
880         err = usb_clear_halt(stir->usbdev, usb_sndbulkpipe(stir->usbdev, 1));
881         if (err)
882                 goto err_out1;
883         err = usb_clear_halt(stir->usbdev, usb_rcvbulkpipe(stir->usbdev, 2));
884         if (err)
885                 goto err_out1;
886 
887         err = change_speed(stir, 9600);
888         if (err)
889                 goto err_out1;
890 
891         err = -ENOMEM;
892 
893         /* Initialize for SIR/FIR to copy data directly into skb.  */
894         stir->receiving = 0;
895         stir->rx_buff.truesize = IRDA_SKB_MAX_MTU;
896         stir->rx_buff.skb = dev_alloc_skb(IRDA_SKB_MAX_MTU);
897         if (!stir->rx_buff.skb) 
898                 goto err_out1;
899 
900         skb_reserve(stir->rx_buff.skb, 1);
901         stir->rx_buff.head = stir->rx_buff.skb->data;
902         do_gettimeofday(&stir->rx_time);
903 
904         stir->rx_urb = usb_alloc_urb(0, GFP_KERNEL);
905         if (!stir->rx_urb) 
906                 goto err_out2;
907 
908         stir->io_buf = kmalloc(STIR_FIFO_SIZE, GFP_KERNEL);
909         if (!stir->io_buf)
910                 goto err_out3;
911 
912         usb_fill_bulk_urb(stir->rx_urb, stir->usbdev,
913                           usb_rcvbulkpipe(stir->usbdev, 2),
914                           stir->io_buf, STIR_FIFO_SIZE,
915                           stir_rcv_irq, stir);
916 
917         stir->fifo_status = kmalloc(FIFO_REGS_SIZE, GFP_KERNEL);
918         if (!stir->fifo_status) 
919                 goto err_out4;
920                 
921         /*
922          * Now that everything should be initialized properly,
923          * Open new IrLAP layer instance to take care of us...
924          * Note : will send immediately a speed change...
925          */
926         sprintf(hwname, "usb#%d", stir->usbdev->devnum);
927         stir->irlap = irlap_open(netdev, &stir->qos, hwname);
928         if (!stir->irlap) {
929                 err("irlap_open failed");
930                 goto err_out5;
931         }
932 
933         /** Start kernel thread for transmit.  */
934         stir->thr_pid = kernel_thread(stir_transmit_thread, stir,
935                                       CLONE_FS|CLONE_FILES);
936         if (stir->thr_pid < 0) {
937                 err = stir->thr_pid;
938                 err("unable to start kernel thread");
939                 goto err_out6;
940         }
941 
942         netif_start_queue(netdev);
943 
944         return 0;
945 
946  err_out6:
947         irlap_close(stir->irlap);
948  err_out5:
949         kfree(stir->fifo_status);
950  err_out4:
951         kfree(stir->io_buf);
952  err_out3:
953         usb_free_urb(stir->rx_urb);
954  err_out2:
955         kfree_skb(stir->rx_buff.skb);
956  err_out1:
957         return err;
958 }
959 
960 /*
961  * Function stir_net_close (stir)
962  *
963  *    Network device is taken down. Usually this is done by
964  *    "ifconfig irda0 down"
965  */
966 static int stir_net_close(struct net_device *netdev)
967 {
968         struct stir_cb *stir = netdev->priv;
969 
970         /* Stop transmit processing */
971         netif_stop_queue(netdev);
972 
973         /* Kill transmit thread */
974         kill_proc(stir->thr_pid, SIGTERM, 1);
975         wait_for_completion(&stir->thr_exited);
976         kfree(stir->fifo_status);
977 
978         /* Mop up receive urb's */
979         usb_unlink_urb(stir->rx_urb);
980         
981         kfree(stir->io_buf);
982         usb_free_urb(stir->rx_urb);
983         kfree_skb(stir->rx_buff.skb);
984 
985         /* Stop and remove instance of IrLAP */
986         if (stir->irlap)
987                 irlap_close(stir->irlap);
988 
989         stir->irlap = NULL;
990 
991         return 0;
992 }
993 
994 /*
995  * IOCTLs : Extra out-of-band network commands...
996  */
997 static int stir_net_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
998 {
999         struct if_irda_req *irq = (struct if_irda_req *) rq;
1000         struct stir_cb *stir = dev->priv;
1001         int ret = 0;
1002 
1003         switch (cmd) {
1004         case SIOCSBANDWIDTH: /* Set bandwidth */
1005                 if (!capable(CAP_NET_ADMIN))
1006                         return -EPERM;
1007 
1008                 /* Check if the device is still there */
1009                 if (netif_device_present(stir->netdev))
1010                         ret = change_speed(stir, irq->ifr_baudrate);
1011                 break;
1012 
1013         case SIOCSMEDIABUSY: /* Set media busy */
1014                 if (!capable(CAP_NET_ADMIN))
1015                         return -EPERM;
1016 
1017                 /* Check if the IrDA stack is still there */
1018                 if (netif_running(stir->netdev))
1019                         irda_device_set_media_busy(stir->netdev, TRUE);
1020                 break;
1021 
1022         case SIOCGRECEIVING:
1023                 /* Only approximately true */
1024                 irq->ifr_receiving = stir->receiving;
1025                 break;
1026 
1027         default:
1028                 ret = -EOPNOTSUPP;
1029         }
1030 
1031         return ret;
1032 }
1033 
1034 /*
1035  * Get device stats (for /proc/net/dev and ifconfig)
1036  */
1037 static struct net_device_stats *stir_net_get_stats(struct net_device *dev)
1038 {
1039         struct stir_cb *stir = dev->priv;
1040         return &stir->stats;
1041 }
1042 
1043 /*
1044  * This routine is called by the USB subsystem for each new device
1045  * in the system. We need to check if the device is ours, and in
1046  * this case start handling it.
1047  * Note : it might be worth protecting this function by a global
1048  * spinlock... Or not, because maybe USB already deal with that...
1049  */
1050 static int stir_probe(struct usb_interface *intf,
1051                       const struct usb_device_id *id)
1052 {
1053         struct usb_device *dev = interface_to_usbdev(intf);
1054         struct stir_cb *stir = NULL;
1055         struct net_device *net;
1056         int ret = -ENOMEM;
1057 
1058         /* Allocate network device container. */
1059         net = alloc_irdadev(sizeof(*stir));
1060         if(!net)
1061                 goto err_out1;
1062 
1063         SET_MODULE_OWNER(net);
1064         SET_NETDEV_DEV(net, &intf->dev);
1065         stir = net->priv;
1066         stir->netdev = net;
1067         stir->usbdev = dev;
1068 
1069         ret = usb_reset_configuration(dev);
1070         if (ret != 0) {
1071                 err("usb reset configuration failed");
1072                 goto err_out2;
1073         }
1074 
1075         printk(KERN_INFO "SigmaTel STIr4200 IRDA/USB found at address %d, "
1076                 "Vendor: %x, Product: %x\n",
1077                dev->devnum, dev->descriptor.idVendor,
1078                dev->descriptor.idProduct);
1079 
1080         /* Initialize QoS for this device */
1081         irda_init_max_qos_capabilies(&stir->qos);
1082 
1083         /* That's the Rx capability. */
1084         stir->qos.baud_rate.bits       &= IR_2400 | IR_9600 | IR_19200 |
1085                                          IR_38400 | IR_57600 | IR_115200 |
1086                                          (IR_4000000 << 8);
1087         stir->qos.min_turn_time.bits   &= qos_mtt_bits;
1088         irda_qos_bits_to_value(&stir->qos);
1089 
1090         init_completion (&stir->thr_exited);
1091         init_waitqueue_head (&stir->thr_wait);
1092 
1093         /* Override the network functions we need to use */
1094         net->hard_start_xmit = stir_hard_xmit;
1095         net->open            = stir_net_open;
1096         net->stop            = stir_net_close;
1097         net->get_stats       = stir_net_get_stats;
1098         net->do_ioctl        = stir_net_ioctl;
1099 
1100         ret = register_netdev(net);
1101         if (ret != 0)
1102                 goto err_out2;
1103 
1104         MESSAGE("IrDA: Registered SigmaTel device %s\n", net->name);
1105 
1106         usb_set_intfdata(intf, stir);
1107 
1108         return 0;
1109 
1110 err_out2:
1111         free_netdev(net);
1112 err_out1:
1113         return ret;
1114 }
1115 
1116 /*
1117  * The current device is removed, the USB layer tell us to shut it down...
1118  */
1119 static void stir_disconnect(struct usb_interface *intf)
1120 {
1121         struct stir_cb *stir = usb_get_intfdata(intf);
1122 
1123         if (!stir)
1124                 return;
1125 
1126         unregister_netdev(stir->netdev);
1127         free_netdev(stir->netdev);
1128 
1129         usb_set_intfdata(intf, NULL);
1130 }
1131 
1132 
1133 /* Power management suspend, so power off the transmitter/receiver */
1134 static int stir_suspend(struct usb_interface *intf, u32 state)
1135 {
1136         struct stir_cb *stir = usb_get_intfdata(intf);
1137 
1138         netif_device_detach(stir->netdev);
1139         return 0;
1140 }
1141 
1142 /* Coming out of suspend, so reset hardware */
1143 static int stir_resume(struct usb_interface *intf)
1144 {
1145         struct stir_cb *stir = usb_get_intfdata(intf);
1146 
1147         netif_device_attach(stir->netdev);
1148 
1149         /* receiver restarted when send thread wakes up */
1150         return 0;
1151 }
1152 
1153 /*
1154  * USB device callbacks
1155  */
1156 static struct usb_driver irda_driver = {
1157         .owner          = THIS_MODULE,
1158         .name           = "stir4200",
1159         .probe          = stir_probe,
1160         .disconnect     = stir_disconnect,
1161         .id_table       = dongles,
1162         .suspend        = stir_suspend,
1163         .resume         = stir_resume,
1164 };
1165 
1166 /*
1167  * Module insertion
1168  */
1169 static int __init stir_init(void)
1170 {
1171         if (usb_register(&irda_driver) < 0)
1172                 return -1;
1173 
1174         MESSAGE("SigmaTel support registered\n");
1175         return 0;
1176 }
1177 module_init(stir_init);
1178 
1179 /*
1180  * Module removal
1181  */
1182 static void __exit stir_cleanup(void)
1183 {
1184         /* Deregister the driver and remove all pending instances */
1185         usb_deregister(&irda_driver);
1186 }
1187 module_exit(stir_cleanup);
1188

Hors ligne

#47 Le 01/06/2005, à 19:58

Cab

Re : Dongle USB Irda

Pas de réponse ? et bien merci de votre aide et à bientôt
Cab

Hors ligne