irnet_irda.c 55 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866
  1. /*
  2. * IrNET protocol module : Synchronous PPP over an IrDA socket.
  3. *
  4. * Jean II - HPL `00 - <jt@hpl.hp.com>
  5. *
  6. * This file implement the IRDA interface of IrNET.
  7. * Basically, we sit on top of IrTTP. We set up IrTTP, IrIAS properly,
  8. * and exchange frames with IrTTP.
  9. */
  10. #include "irnet_irda.h" /* Private header */
  11. /************************* CONTROL CHANNEL *************************/
  12. /*
  13. * When ppp is not active, /dev/irnet act as a control channel.
  14. * Writing allow to set up the IrDA destination of the IrNET channel,
  15. * and any application may be read events happening on IrNET...
  16. */
  17. /*------------------------------------------------------------------*/
  18. /*
  19. * Post an event to the control channel...
  20. * Put the event in the log, and then wait all process blocked on read
  21. * so they can read the log...
  22. */
  23. static void
  24. irnet_post_event(irnet_socket * ap,
  25. irnet_event event,
  26. __u32 saddr,
  27. __u32 daddr,
  28. char * name,
  29. __u16 hints)
  30. {
  31. int index; /* In the log */
  32. DENTER(CTRL_TRACE, "(ap=0x%p, event=%d, daddr=%08x, name=``%s'')\n",
  33. ap, event, daddr, name);
  34. /* Protect this section via spinlock.
  35. * Note : as we are the only event producer, we only need to exclude
  36. * ourself when touching the log, which is nice and easy.
  37. */
  38. spin_lock_bh(&irnet_events.spinlock);
  39. /* Copy the event in the log */
  40. index = irnet_events.index;
  41. irnet_events.log[index].event = event;
  42. irnet_events.log[index].daddr = daddr;
  43. irnet_events.log[index].saddr = saddr;
  44. /* Try to copy IrDA nickname */
  45. if(name)
  46. strcpy(irnet_events.log[index].name, name);
  47. else
  48. irnet_events.log[index].name[0] = '\0';
  49. /* Copy hints */
  50. irnet_events.log[index].hints.word = hints;
  51. /* Try to get ppp unit number */
  52. if((ap != (irnet_socket *) NULL) && (ap->ppp_open))
  53. irnet_events.log[index].unit = ppp_unit_number(&ap->chan);
  54. else
  55. irnet_events.log[index].unit = -1;
  56. /* Increment the index
  57. * Note that we increment the index only after the event is written,
  58. * to make sure that the readers don't get garbage... */
  59. irnet_events.index = (index + 1) % IRNET_MAX_EVENTS;
  60. DEBUG(CTRL_INFO, "New event index is %d\n", irnet_events.index);
  61. /* Spin lock end */
  62. spin_unlock_bh(&irnet_events.spinlock);
  63. /* Now : wake up everybody waiting for events... */
  64. wake_up_interruptible_all(&irnet_events.rwait);
  65. DEXIT(CTRL_TRACE, "\n");
  66. }
  67. /************************* IRDA SUBROUTINES *************************/
  68. /*
  69. * These are a bunch of subroutines called from other functions
  70. * down there, mostly common code or to improve readability...
  71. *
  72. * Note : we duplicate quite heavily some routines of af_irda.c,
  73. * because our input structure (self) is quite different
  74. * (struct irnet instead of struct irda_sock), which make sharing
  75. * the same code impossible (at least, without templates).
  76. */
  77. /*------------------------------------------------------------------*/
  78. /*
  79. * Function irda_open_tsap (self)
  80. *
  81. * Open local Transport Service Access Point (TSAP)
  82. *
  83. * Create a IrTTP instance for us and set all the IrTTP callbacks.
  84. */
  85. static inline int
  86. irnet_open_tsap(irnet_socket * self)
  87. {
  88. notify_t notify; /* Callback structure */
  89. DENTER(IRDA_SR_TRACE, "(self=0x%p)\n", self);
  90. DABORT(self->tsap != NULL, -EBUSY, IRDA_SR_ERROR, "Already busy !\n");
  91. /* Initialize IrTTP callbacks to be used by the IrDA stack */
  92. irda_notify_init(&notify);
  93. notify.connect_confirm = irnet_connect_confirm;
  94. notify.connect_indication = irnet_connect_indication;
  95. notify.disconnect_indication = irnet_disconnect_indication;
  96. notify.data_indication = irnet_data_indication;
  97. /*notify.udata_indication = NULL;*/
  98. notify.flow_indication = irnet_flow_indication;
  99. notify.status_indication = irnet_status_indication;
  100. notify.instance = self;
  101. strlcpy(notify.name, IRNET_NOTIFY_NAME, sizeof(notify.name));
  102. /* Open an IrTTP instance */
  103. self->tsap = irttp_open_tsap(LSAP_ANY, DEFAULT_INITIAL_CREDIT,
  104. &notify);
  105. DABORT(self->tsap == NULL, -ENOMEM,
  106. IRDA_SR_ERROR, "Unable to allocate TSAP !\n");
  107. /* Remember which TSAP selector we actually got */
  108. self->stsap_sel = self->tsap->stsap_sel;
  109. DEXIT(IRDA_SR_TRACE, " - tsap=0x%p, sel=0x%X\n",
  110. self->tsap, self->stsap_sel);
  111. return 0;
  112. }
  113. /*------------------------------------------------------------------*/
  114. /*
  115. * Function irnet_ias_to_tsap (self, result, value)
  116. *
  117. * Examine an IAS object and extract TSAP
  118. *
  119. * We do an IAP query to find the TSAP associated with the IrNET service.
  120. * When IrIAP pass us the result of the query, this function look at
  121. * the return values to check for failures and extract the TSAP if
  122. * possible.
  123. * Also deallocate value
  124. * The failure is in self->errno
  125. * Return TSAP or -1
  126. */
  127. static inline __u8
  128. irnet_ias_to_tsap(irnet_socket * self,
  129. int result,
  130. struct ias_value * value)
  131. {
  132. __u8 dtsap_sel = 0; /* TSAP we are looking for */
  133. DENTER(IRDA_SR_TRACE, "(self=0x%p)\n", self);
  134. /* By default, no error */
  135. self->errno = 0;
  136. /* Check if request succeeded */
  137. switch(result)
  138. {
  139. /* Standard errors : service not available */
  140. case IAS_CLASS_UNKNOWN:
  141. case IAS_ATTRIB_UNKNOWN:
  142. DEBUG(IRDA_SR_INFO, "IAS object doesn't exist ! (%d)\n", result);
  143. self->errno = -EADDRNOTAVAIL;
  144. break;
  145. /* Other errors, most likely IrDA stack failure */
  146. default :
  147. DEBUG(IRDA_SR_INFO, "IAS query failed ! (%d)\n", result);
  148. self->errno = -EHOSTUNREACH;
  149. break;
  150. /* Success : we got what we wanted */
  151. case IAS_SUCCESS:
  152. break;
  153. }
  154. /* Check what was returned to us */
  155. if(value != NULL)
  156. {
  157. /* What type of argument have we got ? */
  158. switch(value->type)
  159. {
  160. case IAS_INTEGER:
  161. DEBUG(IRDA_SR_INFO, "result=%d\n", value->t.integer);
  162. if(value->t.integer != -1)
  163. /* Get the remote TSAP selector */
  164. dtsap_sel = value->t.integer;
  165. else
  166. self->errno = -EADDRNOTAVAIL;
  167. break;
  168. default:
  169. self->errno = -EADDRNOTAVAIL;
  170. DERROR(IRDA_SR_ERROR, "bad type ! (0x%X)\n", value->type);
  171. break;
  172. }
  173. /* Cleanup */
  174. irias_delete_value(value);
  175. }
  176. else /* value == NULL */
  177. {
  178. /* Nothing returned to us - usually result != SUCCESS */
  179. if(!(self->errno))
  180. {
  181. DERROR(IRDA_SR_ERROR,
  182. "IrDA bug : result == SUCCESS && value == NULL\n");
  183. self->errno = -EHOSTUNREACH;
  184. }
  185. }
  186. DEXIT(IRDA_SR_TRACE, "\n");
  187. /* Return the TSAP */
  188. return(dtsap_sel);
  189. }
  190. /*------------------------------------------------------------------*/
  191. /*
  192. * Function irnet_find_lsap_sel (self)
  193. *
  194. * Try to lookup LSAP selector in remote LM-IAS
  195. *
  196. * Basically, we start a IAP query, and then go to sleep. When the query
  197. * return, irnet_getvalue_confirm will wake us up, and we can examine the
  198. * result of the query...
  199. * Note that in some case, the query fail even before we go to sleep,
  200. * creating some races...
  201. */
  202. static inline int
  203. irnet_find_lsap_sel(irnet_socket * self)
  204. {
  205. DENTER(IRDA_SR_TRACE, "(self=0x%p)\n", self);
  206. /* This should not happen */
  207. DABORT(self->iriap, -EBUSY, IRDA_SR_ERROR, "busy with a previous query.\n");
  208. /* Create an IAP instance, will be closed in irnet_getvalue_confirm() */
  209. self->iriap = iriap_open(LSAP_ANY, IAS_CLIENT, self,
  210. irnet_getvalue_confirm);
  211. /* Treat unexpected signals as disconnect */
  212. self->errno = -EHOSTUNREACH;
  213. /* Query remote LM-IAS */
  214. iriap_getvaluebyclass_request(self->iriap, self->rsaddr, self->daddr,
  215. IRNET_SERVICE_NAME, IRNET_IAS_VALUE);
  216. /* The above request is non-blocking.
  217. * After a while, IrDA will call us back in irnet_getvalue_confirm()
  218. * We will then call irnet_ias_to_tsap() and finish the
  219. * connection procedure */
  220. DEXIT(IRDA_SR_TRACE, "\n");
  221. return 0;
  222. }
  223. /*------------------------------------------------------------------*/
  224. /*
  225. * Function irnet_connect_tsap (self)
  226. *
  227. * Initialise the TTP socket and initiate TTP connection
  228. *
  229. */
  230. static inline int
  231. irnet_connect_tsap(irnet_socket * self)
  232. {
  233. int err;
  234. DENTER(IRDA_SR_TRACE, "(self=0x%p)\n", self);
  235. /* Open a local TSAP (an IrTTP instance) */
  236. err = irnet_open_tsap(self);
  237. if(err != 0)
  238. {
  239. clear_bit(0, &self->ttp_connect);
  240. DERROR(IRDA_SR_ERROR, "connect aborted!\n");
  241. return(err);
  242. }
  243. /* Connect to remote device */
  244. err = irttp_connect_request(self->tsap, self->dtsap_sel,
  245. self->rsaddr, self->daddr, NULL,
  246. self->max_sdu_size_rx, NULL);
  247. if(err != 0)
  248. {
  249. clear_bit(0, &self->ttp_connect);
  250. DERROR(IRDA_SR_ERROR, "connect aborted!\n");
  251. return(err);
  252. }
  253. /* The above call is non-blocking.
  254. * After a while, the IrDA stack will either call us back in
  255. * irnet_connect_confirm() or irnet_disconnect_indication()
  256. * See you there ;-) */
  257. DEXIT(IRDA_SR_TRACE, "\n");
  258. return(err);
  259. }
  260. /*------------------------------------------------------------------*/
  261. /*
  262. * Function irnet_discover_next_daddr (self)
  263. *
  264. * Query the IrNET TSAP of the next device in the log.
  265. *
  266. * Used in the TSAP discovery procedure.
  267. */
  268. static inline int
  269. irnet_discover_next_daddr(irnet_socket * self)
  270. {
  271. /* Close the last instance of IrIAP, and open a new one.
  272. * We can't reuse the IrIAP instance in the IrIAP callback */
  273. if(self->iriap)
  274. {
  275. iriap_close(self->iriap);
  276. self->iriap = NULL;
  277. }
  278. /* Create a new IAP instance */
  279. self->iriap = iriap_open(LSAP_ANY, IAS_CLIENT, self,
  280. irnet_discovervalue_confirm);
  281. if(self->iriap == NULL)
  282. return -ENOMEM;
  283. /* Next discovery - before the call to avoid races */
  284. self->disco_index++;
  285. /* Check if we have one more address to try */
  286. if(self->disco_index < self->disco_number)
  287. {
  288. /* Query remote LM-IAS */
  289. iriap_getvaluebyclass_request(self->iriap,
  290. self->discoveries[self->disco_index].saddr,
  291. self->discoveries[self->disco_index].daddr,
  292. IRNET_SERVICE_NAME, IRNET_IAS_VALUE);
  293. /* The above request is non-blocking.
  294. * After a while, IrDA will call us back in irnet_discovervalue_confirm()
  295. * We will then call irnet_ias_to_tsap() and come back here again... */
  296. return(0);
  297. }
  298. else
  299. return(1);
  300. }
  301. /*------------------------------------------------------------------*/
  302. /*
  303. * Function irnet_discover_daddr_and_lsap_sel (self)
  304. *
  305. * This try to find a device with the requested service.
  306. *
  307. * Initiate a TSAP discovery procedure.
  308. * It basically look into the discovery log. For each address in the list,
  309. * it queries the LM-IAS of the device to find if this device offer
  310. * the requested service.
  311. * If there is more than one node supporting the service, we complain
  312. * to the user (it should move devices around).
  313. * If we find one node which have the requested TSAP, we connect to it.
  314. *
  315. * This function just start the whole procedure. It request the discovery
  316. * log and submit the first IAS query.
  317. * The bulk of the job is handled in irnet_discovervalue_confirm()
  318. *
  319. * Note : this procedure fails if there is more than one device in range
  320. * on the same dongle, because IrLMP doesn't disconnect the LAP when the
  321. * last LSAP is closed. Moreover, we would need to wait the LAP
  322. * disconnection...
  323. */
  324. static inline int
  325. irnet_discover_daddr_and_lsap_sel(irnet_socket * self)
  326. {
  327. int ret;
  328. DENTER(IRDA_SR_TRACE, "(self=0x%p)\n", self);
  329. /* Ask lmp for the current discovery log */
  330. self->discoveries = irlmp_get_discoveries(&self->disco_number, self->mask,
  331. DISCOVERY_DEFAULT_SLOTS);
  332. /* Check if the we got some results */
  333. if(self->discoveries == NULL)
  334. {
  335. self->disco_number = -1;
  336. clear_bit(0, &self->ttp_connect);
  337. DRETURN(-ENETUNREACH, IRDA_SR_INFO, "No Cachelog...\n");
  338. }
  339. DEBUG(IRDA_SR_INFO, "Got the log (0x%p), size is %d\n",
  340. self->discoveries, self->disco_number);
  341. /* Start with the first discovery */
  342. self->disco_index = -1;
  343. self->daddr = DEV_ADDR_ANY;
  344. /* This will fail if the log is empty - this is non-blocking */
  345. ret = irnet_discover_next_daddr(self);
  346. if(ret)
  347. {
  348. /* Close IAP */
  349. if(self->iriap)
  350. iriap_close(self->iriap);
  351. self->iriap = NULL;
  352. /* Cleanup our copy of the discovery log */
  353. kfree(self->discoveries);
  354. self->discoveries = NULL;
  355. clear_bit(0, &self->ttp_connect);
  356. DRETURN(-ENETUNREACH, IRDA_SR_INFO, "Cachelog empty...\n");
  357. }
  358. /* Follow me in irnet_discovervalue_confirm() */
  359. DEXIT(IRDA_SR_TRACE, "\n");
  360. return(0);
  361. }
  362. /*------------------------------------------------------------------*/
  363. /*
  364. * Function irnet_dname_to_daddr (self)
  365. *
  366. * Convert an IrDA nickname to a valid IrDA address
  367. *
  368. * It basically look into the discovery log until there is a match.
  369. */
  370. static inline int
  371. irnet_dname_to_daddr(irnet_socket * self)
  372. {
  373. struct irda_device_info *discoveries; /* Copy of the discovery log */
  374. int number; /* Number of nodes in the log */
  375. int i;
  376. DENTER(IRDA_SR_TRACE, "(self=0x%p)\n", self);
  377. /* Ask lmp for the current discovery log */
  378. discoveries = irlmp_get_discoveries(&number, 0xffff,
  379. DISCOVERY_DEFAULT_SLOTS);
  380. /* Check if the we got some results */
  381. if(discoveries == NULL)
  382. DRETURN(-ENETUNREACH, IRDA_SR_INFO, "Cachelog empty...\n");
  383. /*
  384. * Now, check all discovered devices (if any), and connect
  385. * client only about the services that the client is
  386. * interested in...
  387. */
  388. for(i = 0; i < number; i++)
  389. {
  390. /* Does the name match ? */
  391. if(!strncmp(discoveries[i].info, self->rname, NICKNAME_MAX_LEN))
  392. {
  393. /* Yes !!! Get it.. */
  394. self->daddr = discoveries[i].daddr;
  395. DEBUG(IRDA_SR_INFO, "discovered device ``%s'' at address 0x%08x.\n",
  396. self->rname, self->daddr);
  397. kfree(discoveries);
  398. DEXIT(IRDA_SR_TRACE, "\n");
  399. return 0;
  400. }
  401. }
  402. /* No luck ! */
  403. DEBUG(IRDA_SR_INFO, "cannot discover device ``%s'' !!!\n", self->rname);
  404. kfree(discoveries);
  405. return(-EADDRNOTAVAIL);
  406. }
  407. /************************* SOCKET ROUTINES *************************/
  408. /*
  409. * This are the main operations on IrNET sockets, basically to create
  410. * and destroy IrNET sockets. These are called from the PPP part...
  411. */
  412. /*------------------------------------------------------------------*/
  413. /*
  414. * Create a IrNET instance : just initialise some parameters...
  415. */
  416. int
  417. irda_irnet_create(irnet_socket * self)
  418. {
  419. DENTER(IRDA_SOCK_TRACE, "(self=0x%p)\n", self);
  420. self->magic = IRNET_MAGIC; /* Paranoia */
  421. self->ttp_open = 0; /* Prevent higher layer from accessing IrTTP */
  422. self->ttp_connect = 0; /* Not connecting yet */
  423. self->rname[0] = '\0'; /* May be set via control channel */
  424. self->rdaddr = DEV_ADDR_ANY; /* May be set via control channel */
  425. self->rsaddr = DEV_ADDR_ANY; /* May be set via control channel */
  426. self->daddr = DEV_ADDR_ANY; /* Until we get connected */
  427. self->saddr = DEV_ADDR_ANY; /* Until we get connected */
  428. self->max_sdu_size_rx = TTP_SAR_UNBOUND;
  429. /* Register as a client with IrLMP */
  430. self->ckey = irlmp_register_client(0, NULL, NULL, NULL);
  431. #ifdef DISCOVERY_NOMASK
  432. self->mask = 0xffff; /* For W2k compatibility */
  433. #else /* DISCOVERY_NOMASK */
  434. self->mask = irlmp_service_to_hint(S_LAN);
  435. #endif /* DISCOVERY_NOMASK */
  436. self->tx_flow = FLOW_START; /* Flow control from IrTTP */
  437. DEXIT(IRDA_SOCK_TRACE, "\n");
  438. return(0);
  439. }
  440. /*------------------------------------------------------------------*/
  441. /*
  442. * Connect to the other side :
  443. * o convert device name to an address
  444. * o find the socket number (dlsap)
  445. * o Establish the connection
  446. *
  447. * Note : We no longer mimic af_irda. The IAS query for finding the TSAP
  448. * is done asynchronously, like the TTP connection. This allow us to
  449. * call this function from any context (not only process).
  450. * The downside is that following what's happening in there is tricky
  451. * because it involve various functions all over the place...
  452. */
  453. int
  454. irda_irnet_connect(irnet_socket * self)
  455. {
  456. int err;
  457. DENTER(IRDA_SOCK_TRACE, "(self=0x%p)\n", self);
  458. /* Check if we are already trying to connect.
  459. * Because irda_irnet_connect() can be called directly by pppd plus
  460. * packet retries in ppp_generic and connect may take time, plus we may
  461. * race with irnet_connect_indication(), we need to be careful there... */
  462. if(test_and_set_bit(0, &self->ttp_connect))
  463. DRETURN(-EBUSY, IRDA_SOCK_INFO, "Already connecting...\n");
  464. if((self->iriap != NULL) || (self->tsap != NULL))
  465. DERROR(IRDA_SOCK_ERROR, "Socket not cleaned up...\n");
  466. /* Insert ourselves in the hashbin so that the IrNET server can find us.
  467. * Notes : 4th arg is string of 32 char max and must be null terminated
  468. * When 4th arg is used (string), 3rd arg isn't (int)
  469. * Can't re-insert (MUST remove first) so check for that... */
  470. if((irnet_server.running) && (self->q.q_next == NULL))
  471. {
  472. spin_lock_bh(&irnet_server.spinlock);
  473. hashbin_insert(irnet_server.list, (irda_queue_t *) self, 0, self->rname);
  474. spin_unlock_bh(&irnet_server.spinlock);
  475. DEBUG(IRDA_SOCK_INFO, "Inserted ``%s'' in hashbin...\n", self->rname);
  476. }
  477. /* If we don't have anything (no address, no name) */
  478. if((self->rdaddr == DEV_ADDR_ANY) && (self->rname[0] == '\0'))
  479. {
  480. /* Try to find a suitable address */
  481. if((err = irnet_discover_daddr_and_lsap_sel(self)) != 0)
  482. DRETURN(err, IRDA_SOCK_INFO, "auto-connect failed!\n");
  483. /* In most cases, the call above is non-blocking */
  484. }
  485. else
  486. {
  487. /* If we have only the name (no address), try to get an address */
  488. if(self->rdaddr == DEV_ADDR_ANY)
  489. {
  490. if((err = irnet_dname_to_daddr(self)) != 0)
  491. DRETURN(err, IRDA_SOCK_INFO, "name connect failed!\n");
  492. }
  493. else
  494. /* Use the requested destination address */
  495. self->daddr = self->rdaddr;
  496. /* Query remote LM-IAS to find LSAP selector */
  497. irnet_find_lsap_sel(self);
  498. /* The above call is non blocking */
  499. }
  500. /* At this point, we are waiting for the IrDA stack to call us back,
  501. * or we have already failed.
  502. * We will finish the connection procedure in irnet_connect_tsap().
  503. */
  504. DEXIT(IRDA_SOCK_TRACE, "\n");
  505. return(0);
  506. }
  507. /*------------------------------------------------------------------*/
  508. /*
  509. * Function irda_irnet_destroy(self)
  510. *
  511. * Destroy irnet instance
  512. *
  513. * Note : this need to be called from a process context.
  514. */
  515. void
  516. irda_irnet_destroy(irnet_socket * self)
  517. {
  518. DENTER(IRDA_SOCK_TRACE, "(self=0x%p)\n", self);
  519. if(self == NULL)
  520. return;
  521. /* Remove ourselves from hashbin (if we are queued in hashbin)
  522. * Note : `irnet_server.running' protect us from calls in hashbin_delete() */
  523. if((irnet_server.running) && (self->q.q_next != NULL))
  524. {
  525. struct irnet_socket * entry;
  526. DEBUG(IRDA_SOCK_INFO, "Removing from hash..\n");
  527. spin_lock_bh(&irnet_server.spinlock);
  528. entry = hashbin_remove_this(irnet_server.list, (irda_queue_t *) self);
  529. self->q.q_next = NULL;
  530. spin_unlock_bh(&irnet_server.spinlock);
  531. DASSERT(entry == self, , IRDA_SOCK_ERROR, "Can't remove from hash.\n");
  532. }
  533. /* If we were connected, post a message */
  534. if(test_bit(0, &self->ttp_open))
  535. {
  536. /* Note : as the disconnect comes from ppp_generic, the unit number
  537. * doesn't exist anymore when we post the event, so we need to pass
  538. * NULL as the first arg... */
  539. irnet_post_event(NULL, IRNET_DISCONNECT_TO,
  540. self->saddr, self->daddr, self->rname, 0);
  541. }
  542. /* Prevent various IrDA callbacks from messing up things
  543. * Need to be first */
  544. clear_bit(0, &self->ttp_connect);
  545. /* Prevent higher layer from accessing IrTTP */
  546. clear_bit(0, &self->ttp_open);
  547. /* Unregister with IrLMP */
  548. irlmp_unregister_client(self->ckey);
  549. /* Unregister with LM-IAS */
  550. if(self->iriap)
  551. {
  552. iriap_close(self->iriap);
  553. self->iriap = NULL;
  554. }
  555. /* Cleanup eventual discoveries from connection attempt or control channel */
  556. if(self->discoveries != NULL)
  557. {
  558. /* Cleanup our copy of the discovery log */
  559. kfree(self->discoveries);
  560. self->discoveries = NULL;
  561. }
  562. /* Close our IrTTP connection */
  563. if(self->tsap)
  564. {
  565. DEBUG(IRDA_SOCK_INFO, "Closing our TTP connection.\n");
  566. irttp_disconnect_request(self->tsap, NULL, P_NORMAL);
  567. irttp_close_tsap(self->tsap);
  568. self->tsap = NULL;
  569. }
  570. self->stsap_sel = 0;
  571. DEXIT(IRDA_SOCK_TRACE, "\n");
  572. return;
  573. }
  574. /************************** SERVER SOCKET **************************/
  575. /*
  576. * The IrNET service is composed of one server socket and a variable
  577. * number of regular IrNET sockets. The server socket is supposed to
  578. * handle incoming connections and redirect them to one IrNET sockets.
  579. * It's a superset of the regular IrNET socket, but has a very distinct
  580. * behaviour...
  581. */
  582. /*------------------------------------------------------------------*/
  583. /*
  584. * Function irnet_daddr_to_dname (self)
  585. *
  586. * Convert an IrDA address to a IrDA nickname
  587. *
  588. * It basically look into the discovery log until there is a match.
  589. */
  590. static inline int
  591. irnet_daddr_to_dname(irnet_socket * self)
  592. {
  593. struct irda_device_info *discoveries; /* Copy of the discovery log */
  594. int number; /* Number of nodes in the log */
  595. int i;
  596. DENTER(IRDA_SERV_TRACE, "(self=0x%p)\n", self);
  597. /* Ask lmp for the current discovery log */
  598. discoveries = irlmp_get_discoveries(&number, 0xffff,
  599. DISCOVERY_DEFAULT_SLOTS);
  600. /* Check if the we got some results */
  601. if (discoveries == NULL)
  602. DRETURN(-ENETUNREACH, IRDA_SERV_INFO, "Cachelog empty...\n");
  603. /* Now, check all discovered devices (if any) */
  604. for(i = 0; i < number; i++)
  605. {
  606. /* Does the name match ? */
  607. if(discoveries[i].daddr == self->daddr)
  608. {
  609. /* Yes !!! Get it.. */
  610. strlcpy(self->rname, discoveries[i].info, sizeof(self->rname));
  611. self->rname[sizeof(self->rname) - 1] = '\0';
  612. DEBUG(IRDA_SERV_INFO, "Device 0x%08x is in fact ``%s''.\n",
  613. self->daddr, self->rname);
  614. kfree(discoveries);
  615. DEXIT(IRDA_SERV_TRACE, "\n");
  616. return 0;
  617. }
  618. }
  619. /* No luck ! */
  620. DEXIT(IRDA_SERV_INFO, ": cannot discover device 0x%08x !!!\n", self->daddr);
  621. kfree(discoveries);
  622. return(-EADDRNOTAVAIL);
  623. }
  624. /*------------------------------------------------------------------*/
  625. /*
  626. * Function irda_find_socket (self)
  627. *
  628. * Find the correct IrNET socket
  629. *
  630. * Look into the list of IrNET sockets and finds one with the right
  631. * properties...
  632. */
  633. static inline irnet_socket *
  634. irnet_find_socket(irnet_socket * self)
  635. {
  636. irnet_socket * new = (irnet_socket *) NULL;
  637. int err;
  638. DENTER(IRDA_SERV_TRACE, "(self=0x%p)\n", self);
  639. /* Get the addresses of the requester */
  640. self->daddr = irttp_get_daddr(self->tsap);
  641. self->saddr = irttp_get_saddr(self->tsap);
  642. /* Try to get the IrDA nickname of the requester */
  643. err = irnet_daddr_to_dname(self);
  644. /* Protect access to the instance list */
  645. spin_lock_bh(&irnet_server.spinlock);
  646. /* So now, try to get an socket having specifically
  647. * requested that nickname */
  648. if(err == 0)
  649. {
  650. new = (irnet_socket *) hashbin_find(irnet_server.list,
  651. 0, self->rname);
  652. if(new)
  653. DEBUG(IRDA_SERV_INFO, "Socket 0x%p matches rname ``%s''.\n",
  654. new, new->rname);
  655. }
  656. /* If no name matches, try to find an socket by the destination address */
  657. /* It can be either the requested destination address (set via the
  658. * control channel), or the current destination address if the
  659. * socket is in the middle of a connection request */
  660. if(new == (irnet_socket *) NULL)
  661. {
  662. new = (irnet_socket *) hashbin_get_first(irnet_server.list);
  663. while(new !=(irnet_socket *) NULL)
  664. {
  665. /* Does it have the same address ? */
  666. if((new->rdaddr == self->daddr) || (new->daddr == self->daddr))
  667. {
  668. /* Yes !!! Get it.. */
  669. DEBUG(IRDA_SERV_INFO, "Socket 0x%p matches daddr %#08x.\n",
  670. new, self->daddr);
  671. break;
  672. }
  673. new = (irnet_socket *) hashbin_get_next(irnet_server.list);
  674. }
  675. }
  676. /* If we don't have any socket, get the first unconnected socket */
  677. if(new == (irnet_socket *) NULL)
  678. {
  679. new = (irnet_socket *) hashbin_get_first(irnet_server.list);
  680. while(new !=(irnet_socket *) NULL)
  681. {
  682. /* Is it available ? */
  683. if(!(test_bit(0, &new->ttp_open)) && (new->rdaddr == DEV_ADDR_ANY) &&
  684. (new->rname[0] == '\0') && (new->ppp_open))
  685. {
  686. /* Yes !!! Get it.. */
  687. DEBUG(IRDA_SERV_INFO, "Socket 0x%p is free.\n",
  688. new);
  689. break;
  690. }
  691. new = (irnet_socket *) hashbin_get_next(irnet_server.list);
  692. }
  693. }
  694. /* Spin lock end */
  695. spin_unlock_bh(&irnet_server.spinlock);
  696. DEXIT(IRDA_SERV_TRACE, " - new = 0x%p\n", new);
  697. return new;
  698. }
  699. /*------------------------------------------------------------------*/
  700. /*
  701. * Function irda_connect_socket (self)
  702. *
  703. * Connect an incoming connection to the socket
  704. *
  705. */
  706. static inline int
  707. irnet_connect_socket(irnet_socket * server,
  708. irnet_socket * new,
  709. struct qos_info * qos,
  710. __u32 max_sdu_size,
  711. __u8 max_header_size)
  712. {
  713. DENTER(IRDA_SERV_TRACE, "(server=0x%p, new=0x%p)\n",
  714. server, new);
  715. /* Now attach up the new socket */
  716. new->tsap = irttp_dup(server->tsap, new);
  717. DABORT(new->tsap == NULL, -1, IRDA_SERV_ERROR, "dup failed!\n");
  718. /* Set up all the relevant parameters on the new socket */
  719. new->stsap_sel = new->tsap->stsap_sel;
  720. new->dtsap_sel = new->tsap->dtsap_sel;
  721. new->saddr = irttp_get_saddr(new->tsap);
  722. new->daddr = irttp_get_daddr(new->tsap);
  723. new->max_header_size = max_header_size;
  724. new->max_sdu_size_tx = max_sdu_size;
  725. new->max_data_size = max_sdu_size;
  726. #ifdef STREAM_COMPAT
  727. /* If we want to receive "stream sockets" */
  728. if(max_sdu_size == 0)
  729. new->max_data_size = irttp_get_max_seg_size(new->tsap);
  730. #endif /* STREAM_COMPAT */
  731. /* Clean up the original one to keep it in listen state */
  732. irttp_listen(server->tsap);
  733. /* Send a connection response on the new socket */
  734. irttp_connect_response(new->tsap, new->max_sdu_size_rx, NULL);
  735. /* Allow PPP to send its junk over the new socket... */
  736. set_bit(0, &new->ttp_open);
  737. /* Not connecting anymore, and clean up last possible remains
  738. * of connection attempts on the socket */
  739. clear_bit(0, &new->ttp_connect);
  740. if(new->iriap)
  741. {
  742. iriap_close(new->iriap);
  743. new->iriap = NULL;
  744. }
  745. if(new->discoveries != NULL)
  746. {
  747. kfree(new->discoveries);
  748. new->discoveries = NULL;
  749. }
  750. #ifdef CONNECT_INDIC_KICK
  751. /* As currently we don't block packets in ppp_irnet_send() while passive,
  752. * this is not really needed...
  753. * Also, not doing it give IrDA a chance to finish the setup properly
  754. * before being swamped with packets... */
  755. ppp_output_wakeup(&new->chan);
  756. #endif /* CONNECT_INDIC_KICK */
  757. /* Notify the control channel */
  758. irnet_post_event(new, IRNET_CONNECT_FROM,
  759. new->saddr, new->daddr, server->rname, 0);
  760. DEXIT(IRDA_SERV_TRACE, "\n");
  761. return 0;
  762. }
  763. /*------------------------------------------------------------------*/
  764. /*
  765. * Function irda_disconnect_server (self)
  766. *
  767. * Cleanup the server socket when the incoming connection abort
  768. *
  769. */
  770. static inline void
  771. irnet_disconnect_server(irnet_socket * self,
  772. struct sk_buff *skb)
  773. {
  774. DENTER(IRDA_SERV_TRACE, "(self=0x%p)\n", self);
  775. /* Put the received packet in the black hole */
  776. kfree_skb(skb);
  777. #ifdef FAIL_SEND_DISCONNECT
  778. /* Tell the other party we don't want to be connected */
  779. /* Hum... Is it the right thing to do ? And do we need to send
  780. * a connect response before ? It looks ok without this... */
  781. irttp_disconnect_request(self->tsap, NULL, P_NORMAL);
  782. #endif /* FAIL_SEND_DISCONNECT */
  783. /* Notify the control channel (see irnet_find_socket()) */
  784. irnet_post_event(NULL, IRNET_REQUEST_FROM,
  785. self->saddr, self->daddr, self->rname, 0);
  786. /* Clean up the server to keep it in listen state */
  787. irttp_listen(self->tsap);
  788. DEXIT(IRDA_SERV_TRACE, "\n");
  789. return;
  790. }
  791. /*------------------------------------------------------------------*/
  792. /*
  793. * Function irda_setup_server (self)
  794. *
  795. * Create a IrTTP server and set it up...
  796. *
  797. * Register the IrLAN hint bit, create a IrTTP instance for us,
  798. * set all the IrTTP callbacks and create an IrIAS entry...
  799. */
  800. static inline int
  801. irnet_setup_server(void)
  802. {
  803. __u16 hints;
  804. DENTER(IRDA_SERV_TRACE, "()\n");
  805. /* Initialise the regular socket part of the server */
  806. irda_irnet_create(&irnet_server.s);
  807. /* Open a local TSAP (an IrTTP instance) for the server */
  808. irnet_open_tsap(&irnet_server.s);
  809. /* PPP part setup */
  810. irnet_server.s.ppp_open = 0;
  811. irnet_server.s.chan.private = NULL;
  812. irnet_server.s.file = NULL;
  813. /* Get the hint bit corresponding to IrLAN */
  814. /* Note : we overload the IrLAN hint bit. As it is only a "hint", and as
  815. * we provide roughly the same functionality as IrLAN, this is ok.
  816. * In fact, the situation is similar as JetSend overloading the Obex hint
  817. */
  818. hints = irlmp_service_to_hint(S_LAN);
  819. #ifdef ADVERTISE_HINT
  820. /* Register with IrLMP as a service (advertise our hint bit) */
  821. irnet_server.skey = irlmp_register_service(hints);
  822. #endif /* ADVERTISE_HINT */
  823. /* Register with LM-IAS (so that people can connect to us) */
  824. irnet_server.ias_obj = irias_new_object(IRNET_SERVICE_NAME, jiffies);
  825. irias_add_integer_attrib(irnet_server.ias_obj, IRNET_IAS_VALUE,
  826. irnet_server.s.stsap_sel, IAS_KERNEL_ATTR);
  827. irias_insert_object(irnet_server.ias_obj);
  828. #ifdef DISCOVERY_EVENTS
  829. /* Tell IrLMP we want to be notified of newly discovered nodes */
  830. irlmp_update_client(irnet_server.s.ckey, hints,
  831. irnet_discovery_indication, irnet_expiry_indication,
  832. (void *) &irnet_server.s);
  833. #endif
  834. DEXIT(IRDA_SERV_TRACE, " - self=0x%p\n", &irnet_server.s);
  835. return 0;
  836. }
  837. /*------------------------------------------------------------------*/
  838. /*
  839. * Function irda_destroy_server (self)
  840. *
  841. * Destroy the IrTTP server...
  842. *
  843. * Reverse of the previous function...
  844. */
  845. static inline void
  846. irnet_destroy_server(void)
  847. {
  848. DENTER(IRDA_SERV_TRACE, "()\n");
  849. #ifdef ADVERTISE_HINT
  850. /* Unregister with IrLMP */
  851. irlmp_unregister_service(irnet_server.skey);
  852. #endif /* ADVERTISE_HINT */
  853. /* Unregister with LM-IAS */
  854. if(irnet_server.ias_obj)
  855. irias_delete_object(irnet_server.ias_obj);
  856. /* Cleanup the socket part */
  857. irda_irnet_destroy(&irnet_server.s);
  858. DEXIT(IRDA_SERV_TRACE, "\n");
  859. return;
  860. }
  861. /************************ IRDA-TTP CALLBACKS ************************/
  862. /*
  863. * When we create a IrTTP instance, we pass to it a set of callbacks
  864. * that IrTTP will call in case of various events.
  865. * We take care of those events here.
  866. */
  867. /*------------------------------------------------------------------*/
  868. /*
  869. * Function irnet_data_indication (instance, sap, skb)
  870. *
  871. * Received some data from TinyTP. Just queue it on the receive queue
  872. *
  873. */
  874. static int
  875. irnet_data_indication(void * instance,
  876. void * sap,
  877. struct sk_buff *skb)
  878. {
  879. irnet_socket * ap = (irnet_socket *) instance;
  880. unsigned char * p;
  881. int code = 0;
  882. DENTER(IRDA_TCB_TRACE, "(self/ap=0x%p, skb=0x%p)\n",
  883. ap, skb);
  884. DASSERT(skb != NULL, 0, IRDA_CB_ERROR, "skb is NULL !!!\n");
  885. /* Check is ppp is ready to receive our packet */
  886. if(!ap->ppp_open)
  887. {
  888. DERROR(IRDA_CB_ERROR, "PPP not ready, dropping packet...\n");
  889. /* When we return error, TTP will need to requeue the skb and
  890. * will stop the sender. IrTTP will stall until we send it a
  891. * flow control request... */
  892. return -ENOMEM;
  893. }
  894. /* strip address/control field if present */
  895. p = skb->data;
  896. if((p[0] == PPP_ALLSTATIONS) && (p[1] == PPP_UI))
  897. {
  898. /* chop off address/control */
  899. if(skb->len < 3)
  900. goto err_exit;
  901. p = skb_pull(skb, 2);
  902. }
  903. /* decompress protocol field if compressed */
  904. if(p[0] & 1)
  905. {
  906. /* protocol is compressed */
  907. skb_push(skb, 1)[0] = 0;
  908. }
  909. else
  910. if(skb->len < 2)
  911. goto err_exit;
  912. /* pass to generic ppp layer */
  913. /* Note : how do I know if ppp can accept or not the packet ? This is
  914. * essential if I want to manage flow control smoothly... */
  915. ppp_input(&ap->chan, skb);
  916. DEXIT(IRDA_TCB_TRACE, "\n");
  917. return 0;
  918. err_exit:
  919. DERROR(IRDA_CB_ERROR, "Packet too small, dropping...\n");
  920. kfree_skb(skb);
  921. ppp_input_error(&ap->chan, code);
  922. return 0; /* Don't return an error code, only for flow control... */
  923. }
  924. /*------------------------------------------------------------------*/
  925. /*
  926. * Function irnet_disconnect_indication (instance, sap, reason, skb)
  927. *
  928. * Connection has been closed. Chech reason to find out why
  929. *
  930. * Note : there are many cases where we come here :
  931. * o attempted to connect, timeout
  932. * o connected, link is broken, LAP has timeout
  933. * o connected, other side close the link
  934. * o connection request on the server not handled
  935. */
  936. static void
  937. irnet_disconnect_indication(void * instance,
  938. void * sap,
  939. LM_REASON reason,
  940. struct sk_buff *skb)
  941. {
  942. irnet_socket * self = (irnet_socket *) instance;
  943. int test_open;
  944. int test_connect;
  945. DENTER(IRDA_TCB_TRACE, "(self=0x%p)\n", self);
  946. DASSERT(self != NULL, , IRDA_CB_ERROR, "Self is NULL !!!\n");
  947. /* Don't care about it, but let's not leak it */
  948. if(skb)
  949. dev_kfree_skb(skb);
  950. /* Prevent higher layer from accessing IrTTP */
  951. test_open = test_and_clear_bit(0, &self->ttp_open);
  952. /* Not connecting anymore...
  953. * (note : TSAP is open, so IAP callbacks are no longer pending...) */
  954. test_connect = test_and_clear_bit(0, &self->ttp_connect);
  955. /* If both self->ttp_open and self->ttp_connect are NULL, it mean that we
  956. * have a race condition with irda_irnet_destroy() or
  957. * irnet_connect_indication(), so don't mess up tsap...
  958. */
  959. if(!(test_open || test_connect))
  960. {
  961. DERROR(IRDA_CB_ERROR, "Race condition detected...\n");
  962. return;
  963. }
  964. /* If we were active, notify the control channel */
  965. if(test_open)
  966. irnet_post_event(self, IRNET_DISCONNECT_FROM,
  967. self->saddr, self->daddr, self->rname, 0);
  968. else
  969. /* If we were trying to connect, notify the control channel */
  970. if((self->tsap) && (self != &irnet_server.s))
  971. irnet_post_event(self, IRNET_NOANSWER_FROM,
  972. self->saddr, self->daddr, self->rname, 0);
  973. /* Close our IrTTP connection, cleanup tsap */
  974. if((self->tsap) && (self != &irnet_server.s))
  975. {
  976. DEBUG(IRDA_CB_INFO, "Closing our TTP connection.\n");
  977. irttp_close_tsap(self->tsap);
  978. self->tsap = NULL;
  979. }
  980. /* Cleanup the socket in case we want to reconnect in ppp_output_wakeup() */
  981. self->stsap_sel = 0;
  982. self->daddr = DEV_ADDR_ANY;
  983. self->tx_flow = FLOW_START;
  984. /* Deal with the ppp instance if it's still alive */
  985. if(self->ppp_open)
  986. {
  987. if(test_open)
  988. {
  989. #ifdef MISSING_PPP_API
  990. /* ppp_unregister_channel() wants a user context, which we
  991. * are guaranteed to NOT have here. What are we supposed
  992. * to do here ? Jean II */
  993. /* If we were connected, cleanup & close the PPP channel,
  994. * which will kill pppd (hangup) and the rest */
  995. ppp_unregister_channel(&self->chan);
  996. self->ppp_open = 0;
  997. #endif
  998. }
  999. else
  1000. {
  1001. /* If we were trying to connect, flush (drain) ppp_generic
  1002. * Tx queue (most often we have blocked it), which will
  1003. * trigger an other attempt to connect. If we are passive,
  1004. * this will empty the Tx queue after last try. */
  1005. ppp_output_wakeup(&self->chan);
  1006. }
  1007. }
  1008. DEXIT(IRDA_TCB_TRACE, "\n");
  1009. }
  1010. /*------------------------------------------------------------------*/
  1011. /*
  1012. * Function irnet_connect_confirm (instance, sap, qos, max_sdu_size, skb)
  1013. *
  1014. * Connections has been confirmed by the remote device
  1015. *
  1016. */
  1017. static void
  1018. irnet_connect_confirm(void * instance,
  1019. void * sap,
  1020. struct qos_info *qos,
  1021. __u32 max_sdu_size,
  1022. __u8 max_header_size,
  1023. struct sk_buff *skb)
  1024. {
  1025. irnet_socket * self = (irnet_socket *) instance;
  1026. DENTER(IRDA_TCB_TRACE, "(self=0x%p)\n", self);
  1027. /* Check if socket is closing down (via irda_irnet_destroy()) */
  1028. if(! test_bit(0, &self->ttp_connect))
  1029. {
  1030. DERROR(IRDA_CB_ERROR, "Socket no longer connecting. Ouch !\n");
  1031. return;
  1032. }
  1033. /* How much header space do we need to reserve */
  1034. self->max_header_size = max_header_size;
  1035. /* IrTTP max SDU size in transmit direction */
  1036. self->max_sdu_size_tx = max_sdu_size;
  1037. self->max_data_size = max_sdu_size;
  1038. #ifdef STREAM_COMPAT
  1039. if(max_sdu_size == 0)
  1040. self->max_data_size = irttp_get_max_seg_size(self->tsap);
  1041. #endif /* STREAM_COMPAT */
  1042. /* At this point, IrLMP has assigned our source address */
  1043. self->saddr = irttp_get_saddr(self->tsap);
  1044. /* Allow higher layer to access IrTTP */
  1045. set_bit(0, &self->ttp_open);
  1046. clear_bit(0, &self->ttp_connect); /* Not racy, IrDA traffic is serial */
  1047. /* Give a kick in the ass of ppp_generic so that he sends us some data */
  1048. ppp_output_wakeup(&self->chan);
  1049. /* Check size of received packet */
  1050. if(skb->len > 0)
  1051. {
  1052. #ifdef PASS_CONNECT_PACKETS
  1053. DEBUG(IRDA_CB_INFO, "Passing connect packet to PPP.\n");
  1054. /* Try to pass it to PPP */
  1055. irnet_data_indication(instance, sap, skb);
  1056. #else /* PASS_CONNECT_PACKETS */
  1057. DERROR(IRDA_CB_ERROR, "Dropping non empty packet.\n");
  1058. kfree_skb(skb); /* Note : will be optimised with other kfree... */
  1059. #endif /* PASS_CONNECT_PACKETS */
  1060. }
  1061. else
  1062. kfree_skb(skb);
  1063. /* Notify the control channel */
  1064. irnet_post_event(self, IRNET_CONNECT_TO,
  1065. self->saddr, self->daddr, self->rname, 0);
  1066. DEXIT(IRDA_TCB_TRACE, "\n");
  1067. }
  1068. /*------------------------------------------------------------------*/
  1069. /*
  1070. * Function irnet_flow_indication (instance, sap, flow)
  1071. *
  1072. * Used by TinyTP to tell us if it can accept more data or not
  1073. *
  1074. */
  1075. static void
  1076. irnet_flow_indication(void * instance,
  1077. void * sap,
  1078. LOCAL_FLOW flow)
  1079. {
  1080. irnet_socket * self = (irnet_socket *) instance;
  1081. LOCAL_FLOW oldflow = self->tx_flow;
  1082. DENTER(IRDA_TCB_TRACE, "(self=0x%p, flow=%d)\n", self, flow);
  1083. /* Update our state */
  1084. self->tx_flow = flow;
  1085. /* Check what IrTTP want us to do... */
  1086. switch(flow)
  1087. {
  1088. case FLOW_START:
  1089. DEBUG(IRDA_CB_INFO, "IrTTP wants us to start again\n");
  1090. /* Check if we really need to wake up PPP */
  1091. if(oldflow == FLOW_STOP)
  1092. ppp_output_wakeup(&self->chan);
  1093. else
  1094. DEBUG(IRDA_CB_INFO, "But we were already transmitting !!!\n");
  1095. break;
  1096. case FLOW_STOP:
  1097. DEBUG(IRDA_CB_INFO, "IrTTP wants us to slow down\n");
  1098. break;
  1099. default:
  1100. DEBUG(IRDA_CB_INFO, "Unknown flow command!\n");
  1101. break;
  1102. }
  1103. DEXIT(IRDA_TCB_TRACE, "\n");
  1104. }
  1105. /*------------------------------------------------------------------*/
  1106. /*
  1107. * Function irnet_status_indication (instance, sap, reason, skb)
  1108. *
  1109. * Link (IrLAP) status report.
  1110. *
  1111. */
  1112. static void
  1113. irnet_status_indication(void * instance,
  1114. LINK_STATUS link,
  1115. LOCK_STATUS lock)
  1116. {
  1117. irnet_socket * self = (irnet_socket *) instance;
  1118. DENTER(IRDA_TCB_TRACE, "(self=0x%p)\n", self);
  1119. DASSERT(self != NULL, , IRDA_CB_ERROR, "Self is NULL !!!\n");
  1120. /* We can only get this event if we are connected */
  1121. switch(link)
  1122. {
  1123. case STATUS_NO_ACTIVITY:
  1124. irnet_post_event(self, IRNET_BLOCKED_LINK,
  1125. self->saddr, self->daddr, self->rname, 0);
  1126. break;
  1127. default:
  1128. DEBUG(IRDA_CB_INFO, "Unknown status...\n");
  1129. }
  1130. DEXIT(IRDA_TCB_TRACE, "\n");
  1131. }
  1132. /*------------------------------------------------------------------*/
  1133. /*
  1134. * Function irnet_connect_indication(instance, sap, qos, max_sdu_size, userdata)
  1135. *
  1136. * Incoming connection
  1137. *
  1138. * In theory, this function is called only on the server socket.
  1139. * Some other node is attempting to connect to the IrNET service, and has
  1140. * sent a connection request on our server socket.
  1141. * We just redirect the connection to the relevant IrNET socket.
  1142. *
  1143. * Note : we also make sure that between 2 irnet nodes, there can
  1144. * exist only one irnet connection.
  1145. */
  1146. static void
  1147. irnet_connect_indication(void * instance,
  1148. void * sap,
  1149. struct qos_info *qos,
  1150. __u32 max_sdu_size,
  1151. __u8 max_header_size,
  1152. struct sk_buff *skb)
  1153. {
  1154. irnet_socket * server = &irnet_server.s;
  1155. irnet_socket * new = (irnet_socket *) NULL;
  1156. DENTER(IRDA_TCB_TRACE, "(server=0x%p)\n", server);
  1157. DASSERT(instance == &irnet_server, , IRDA_CB_ERROR,
  1158. "Invalid instance (0x%p) !!!\n", instance);
  1159. DASSERT(sap == irnet_server.s.tsap, , IRDA_CB_ERROR, "Invalid sap !!!\n");
  1160. /* Try to find the most appropriate IrNET socket */
  1161. new = irnet_find_socket(server);
  1162. /* After all this hard work, do we have an socket ? */
  1163. if(new == (irnet_socket *) NULL)
  1164. {
  1165. DEXIT(IRDA_CB_INFO, ": No socket waiting for this connection.\n");
  1166. irnet_disconnect_server(server, skb);
  1167. return;
  1168. }
  1169. /* Is the socket already busy ? */
  1170. if(test_bit(0, &new->ttp_open))
  1171. {
  1172. DEXIT(IRDA_CB_INFO, ": Socket already connected.\n");
  1173. irnet_disconnect_server(server, skb);
  1174. return;
  1175. }
  1176. /* The following code is a bit tricky, so need comments ;-)
  1177. */
  1178. /* If ttp_connect is set, the socket is trying to connect to the other
  1179. * end and may have sent a IrTTP connection request and is waiting for
  1180. * a connection response (that may never come).
  1181. * Now, the pain is that the socket may have opened a tsap and is
  1182. * waiting on it, while the other end is trying to connect to it on
  1183. * another tsap.
  1184. * Because IrNET can be peer to peer, we need to workaround this.
  1185. * Furthermore, the way the irnetd script is implemented, the
  1186. * target will create a second IrNET connection back to the
  1187. * originator and expect the originator to bind this new connection
  1188. * to the original PPPD instance.
  1189. * And of course, if we don't use irnetd, we can have a race when
  1190. * both side try to connect simultaneously, which could leave both
  1191. * connections half closed (yuck).
  1192. * Conclusions :
  1193. * 1) The "originator" must accept the new connection and get rid
  1194. * of the old one so that irnetd works
  1195. * 2) One side must deny the new connection to avoid races,
  1196. * but both side must agree on which side it is...
  1197. * Most often, the originator is primary at the LAP layer.
  1198. * Jean II
  1199. */
  1200. /* Now, let's look at the way I wrote the test...
  1201. * We need to clear up the ttp_connect flag atomically to prevent
  1202. * irnet_disconnect_indication() to mess up the tsap we are going to close.
  1203. * We want to clear the ttp_connect flag only if we close the tsap,
  1204. * otherwise we will never close it, so we need to check for primary
  1205. * *before* doing the test on the flag.
  1206. * And of course, ALLOW_SIMULT_CONNECT can disable this entirely...
  1207. * Jean II
  1208. */
  1209. /* Socket already connecting ? On primary ? */
  1210. if(0
  1211. #ifdef ALLOW_SIMULT_CONNECT
  1212. || ((irttp_is_primary(server->tsap) == 1) /* primary */
  1213. && (test_and_clear_bit(0, &new->ttp_connect)))
  1214. #endif /* ALLOW_SIMULT_CONNECT */
  1215. )
  1216. {
  1217. DERROR(IRDA_CB_ERROR, "Socket already connecting, but going to reuse it !\n");
  1218. /* Cleanup the old TSAP if necessary - IrIAP will be cleaned up later */
  1219. if(new->tsap != NULL)
  1220. {
  1221. /* Close the old connection the new socket was attempting,
  1222. * so that we can hook it up to the new connection.
  1223. * It's now safe to do it... */
  1224. irttp_close_tsap(new->tsap);
  1225. new->tsap = NULL;
  1226. }
  1227. }
  1228. else
  1229. {
  1230. /* Three options :
  1231. * 1) socket was not connecting or connected : ttp_connect should be 0.
  1232. * 2) we don't want to connect the socket because we are secondary or
  1233. * ALLOW_SIMULT_CONNECT is undefined. ttp_connect should be 1.
  1234. * 3) we are half way in irnet_disconnect_indication(), and it's a
  1235. * nice race condition... Fortunately, we can detect that by checking
  1236. * if tsap is still alive. On the other hand, we can't be in
  1237. * irda_irnet_destroy() otherwise we would not have found this
  1238. * socket in the hashbin.
  1239. * Jean II */
  1240. if((test_bit(0, &new->ttp_connect)) || (new->tsap != NULL))
  1241. {
  1242. /* Don't mess this socket, somebody else in in charge... */
  1243. DERROR(IRDA_CB_ERROR, "Race condition detected, socket in use, abort connect...\n");
  1244. irnet_disconnect_server(server, skb);
  1245. return;
  1246. }
  1247. }
  1248. /* So : at this point, we have a socket, and it is idle. Good ! */
  1249. irnet_connect_socket(server, new, qos, max_sdu_size, max_header_size);
  1250. /* Check size of received packet */
  1251. if(skb->len > 0)
  1252. {
  1253. #ifdef PASS_CONNECT_PACKETS
  1254. DEBUG(IRDA_CB_INFO, "Passing connect packet to PPP.\n");
  1255. /* Try to pass it to PPP */
  1256. irnet_data_indication(new, new->tsap, skb);
  1257. #else /* PASS_CONNECT_PACKETS */
  1258. DERROR(IRDA_CB_ERROR, "Dropping non empty packet.\n");
  1259. kfree_skb(skb); /* Note : will be optimised with other kfree... */
  1260. #endif /* PASS_CONNECT_PACKETS */
  1261. }
  1262. else
  1263. kfree_skb(skb);
  1264. DEXIT(IRDA_TCB_TRACE, "\n");
  1265. }
  1266. /********************** IRDA-IAS/LMP CALLBACKS **********************/
  1267. /*
  1268. * These are the callbacks called by other layers of the IrDA stack,
  1269. * mainly LMP for discovery and IAS for name queries.
  1270. */
  1271. /*------------------------------------------------------------------*/
  1272. /*
  1273. * Function irnet_getvalue_confirm (result, obj_id, value, priv)
  1274. *
  1275. * Got answer from remote LM-IAS, just connect
  1276. *
  1277. * This is the reply to a IAS query we were doing to find the TSAP of
  1278. * the device we want to connect to.
  1279. * If we have found a valid TSAP, just initiate the TTP connection
  1280. * on this TSAP.
  1281. */
  1282. static void
  1283. irnet_getvalue_confirm(int result,
  1284. __u16 obj_id,
  1285. struct ias_value *value,
  1286. void * priv)
  1287. {
  1288. irnet_socket * self = (irnet_socket *) priv;
  1289. DENTER(IRDA_OCB_TRACE, "(self=0x%p)\n", self);
  1290. DASSERT(self != NULL, , IRDA_OCB_ERROR, "Self is NULL !!!\n");
  1291. /* Check if already connected (via irnet_connect_socket())
  1292. * or socket is closing down (via irda_irnet_destroy()) */
  1293. if(! test_bit(0, &self->ttp_connect))
  1294. {
  1295. DERROR(IRDA_OCB_ERROR, "Socket no longer connecting. Ouch !\n");
  1296. return;
  1297. }
  1298. /* We probably don't need to make any more queries */
  1299. iriap_close(self->iriap);
  1300. self->iriap = NULL;
  1301. /* Post process the IAS reply */
  1302. self->dtsap_sel = irnet_ias_to_tsap(self, result, value);
  1303. /* If error, just go out */
  1304. if(self->errno)
  1305. {
  1306. clear_bit(0, &self->ttp_connect);
  1307. DERROR(IRDA_OCB_ERROR, "IAS connect failed ! (0x%X)\n", self->errno);
  1308. return;
  1309. }
  1310. DEBUG(IRDA_OCB_INFO, "daddr = %08x, lsap = %d, starting IrTTP connection\n",
  1311. self->daddr, self->dtsap_sel);
  1312. /* Start up TTP - non blocking */
  1313. irnet_connect_tsap(self);
  1314. DEXIT(IRDA_OCB_TRACE, "\n");
  1315. }
  1316. /*------------------------------------------------------------------*/
  1317. /*
  1318. * Function irnet_discovervalue_confirm (result, obj_id, value, priv)
  1319. *
  1320. * Handle the TSAP discovery procedure state machine.
  1321. * Got answer from remote LM-IAS, try next device
  1322. *
  1323. * We are doing a TSAP discovery procedure, and we got an answer to
  1324. * a IAS query we were doing to find the TSAP on one of the address
  1325. * in the discovery log.
  1326. *
  1327. * If we have found a valid TSAP for the first time, save it. If it's
  1328. * not the first time we found one, complain.
  1329. *
  1330. * If we have more addresses in the log, just initiate a new query.
  1331. * Note that those query may fail (see irnet_discover_daddr_and_lsap_sel())
  1332. *
  1333. * Otherwise, wrap up the procedure (cleanup), check if we have found
  1334. * any device and connect to it.
  1335. */
  1336. static void
  1337. irnet_discovervalue_confirm(int result,
  1338. __u16 obj_id,
  1339. struct ias_value *value,
  1340. void * priv)
  1341. {
  1342. irnet_socket * self = (irnet_socket *) priv;
  1343. __u8 dtsap_sel; /* TSAP we are looking for */
  1344. DENTER(IRDA_OCB_TRACE, "(self=0x%p)\n", self);
  1345. DASSERT(self != NULL, , IRDA_OCB_ERROR, "Self is NULL !!!\n");
  1346. /* Check if already connected (via irnet_connect_socket())
  1347. * or socket is closing down (via irda_irnet_destroy()) */
  1348. if(! test_bit(0, &self->ttp_connect))
  1349. {
  1350. DERROR(IRDA_OCB_ERROR, "Socket no longer connecting. Ouch !\n");
  1351. return;
  1352. }
  1353. /* Post process the IAS reply */
  1354. dtsap_sel = irnet_ias_to_tsap(self, result, value);
  1355. /* Have we got something ? */
  1356. if(self->errno == 0)
  1357. {
  1358. /* We found the requested service */
  1359. if(self->daddr != DEV_ADDR_ANY)
  1360. {
  1361. DERROR(IRDA_OCB_ERROR, "More than one device in range supports IrNET...\n");
  1362. }
  1363. else
  1364. {
  1365. /* First time we found that one, save it ! */
  1366. self->daddr = self->discoveries[self->disco_index].daddr;
  1367. self->dtsap_sel = dtsap_sel;
  1368. }
  1369. }
  1370. /* If no failure */
  1371. if((self->errno == -EADDRNOTAVAIL) || (self->errno == 0))
  1372. {
  1373. int ret;
  1374. /* Search the next node */
  1375. ret = irnet_discover_next_daddr(self);
  1376. if(!ret)
  1377. {
  1378. /* In this case, the above request was non-blocking.
  1379. * We will return here after a while... */
  1380. return;
  1381. }
  1382. /* In this case, we have processed the last discovery item */
  1383. }
  1384. /* No more queries to be done (failure or last one) */
  1385. /* We probably don't need to make any more queries */
  1386. iriap_close(self->iriap);
  1387. self->iriap = NULL;
  1388. /* No more items : remove the log and signal termination */
  1389. DEBUG(IRDA_OCB_INFO, "Cleaning up log (0x%p)\n",
  1390. self->discoveries);
  1391. if(self->discoveries != NULL)
  1392. {
  1393. /* Cleanup our copy of the discovery log */
  1394. kfree(self->discoveries);
  1395. self->discoveries = NULL;
  1396. }
  1397. self->disco_number = -1;
  1398. /* Check out what we found */
  1399. if(self->daddr == DEV_ADDR_ANY)
  1400. {
  1401. self->daddr = DEV_ADDR_ANY;
  1402. clear_bit(0, &self->ttp_connect);
  1403. DEXIT(IRDA_OCB_TRACE, ": cannot discover IrNET in any device !!!\n");
  1404. return;
  1405. }
  1406. /* We have a valid address - just connect */
  1407. DEBUG(IRDA_OCB_INFO, "daddr = %08x, lsap = %d, starting IrTTP connection\n",
  1408. self->daddr, self->dtsap_sel);
  1409. /* Start up TTP - non blocking */
  1410. irnet_connect_tsap(self);
  1411. DEXIT(IRDA_OCB_TRACE, "\n");
  1412. }
  1413. #ifdef DISCOVERY_EVENTS
  1414. /*------------------------------------------------------------------*/
  1415. /*
  1416. * Function irnet_discovery_indication (discovery)
  1417. *
  1418. * Got a discovery indication from IrLMP, post an event
  1419. *
  1420. * Note : IrLMP take care of matching the hint mask for us, and also
  1421. * check if it is a "new" node for us...
  1422. *
  1423. * As IrLMP filter on the IrLAN hint bit, we get both IrLAN and IrNET
  1424. * nodes, so it's only at connection time that we will know if the
  1425. * node support IrNET, IrLAN or both. The other solution is to check
  1426. * in IAS the PNP ids and service name.
  1427. * Note : even if a node support IrNET (or IrLAN), it's no guarantee
  1428. * that we will be able to connect to it, the node might already be
  1429. * busy...
  1430. *
  1431. * One last thing : in some case, this function will trigger duplicate
  1432. * discovery events. On the other hand, we should catch all
  1433. * discoveries properly (i.e. not miss one). Filtering duplicate here
  1434. * is to messy, so we leave that to user space...
  1435. */
  1436. static void
  1437. irnet_discovery_indication(discinfo_t * discovery,
  1438. DISCOVERY_MODE mode,
  1439. void * priv)
  1440. {
  1441. irnet_socket * self = &irnet_server.s;
  1442. DENTER(IRDA_OCB_TRACE, "(self=0x%p)\n", self);
  1443. DASSERT(priv == &irnet_server, , IRDA_OCB_ERROR,
  1444. "Invalid instance (0x%p) !!!\n", priv);
  1445. DEBUG(IRDA_OCB_INFO, "Discovered new IrNET/IrLAN node %s...\n",
  1446. discovery->info);
  1447. /* Notify the control channel */
  1448. irnet_post_event(NULL, IRNET_DISCOVER,
  1449. discovery->saddr, discovery->daddr, discovery->info,
  1450. u16ho(discovery->hints));
  1451. DEXIT(IRDA_OCB_TRACE, "\n");
  1452. }
  1453. /*------------------------------------------------------------------*/
  1454. /*
  1455. * Function irnet_expiry_indication (expiry)
  1456. *
  1457. * Got a expiry indication from IrLMP, post an event
  1458. *
  1459. * Note : IrLMP take care of matching the hint mask for us, we only
  1460. * check if it is a "new" node...
  1461. */
  1462. static void
  1463. irnet_expiry_indication(discinfo_t * expiry,
  1464. DISCOVERY_MODE mode,
  1465. void * priv)
  1466. {
  1467. irnet_socket * self = &irnet_server.s;
  1468. DENTER(IRDA_OCB_TRACE, "(self=0x%p)\n", self);
  1469. DASSERT(priv == &irnet_server, , IRDA_OCB_ERROR,
  1470. "Invalid instance (0x%p) !!!\n", priv);
  1471. DEBUG(IRDA_OCB_INFO, "IrNET/IrLAN node %s expired...\n",
  1472. expiry->info);
  1473. /* Notify the control channel */
  1474. irnet_post_event(NULL, IRNET_EXPIRE,
  1475. expiry->saddr, expiry->daddr, expiry->info,
  1476. u16ho(expiry->hints));
  1477. DEXIT(IRDA_OCB_TRACE, "\n");
  1478. }
  1479. #endif /* DISCOVERY_EVENTS */
  1480. /*********************** PROC ENTRY CALLBACKS ***********************/
  1481. /*
  1482. * We create a instance in the /proc filesystem, and here we take care
  1483. * of that...
  1484. */
  1485. #ifdef CONFIG_PROC_FS
  1486. /*------------------------------------------------------------------*/
  1487. /*
  1488. * Function irnet_proc_read (buf, start, offset, len, unused)
  1489. *
  1490. * Give some info to the /proc file system
  1491. */
  1492. static int
  1493. irnet_proc_read(char * buf,
  1494. char ** start,
  1495. off_t offset,
  1496. int len)
  1497. {
  1498. irnet_socket * self;
  1499. char * state;
  1500. int i = 0;
  1501. len = 0;
  1502. /* Get the IrNET server information... */
  1503. len += sprintf(buf+len, "IrNET server - ");
  1504. len += sprintf(buf+len, "IrDA state: %s, ",
  1505. (irnet_server.running ? "running" : "dead"));
  1506. len += sprintf(buf+len, "stsap_sel: %02x, ", irnet_server.s.stsap_sel);
  1507. len += sprintf(buf+len, "dtsap_sel: %02x\n", irnet_server.s.dtsap_sel);
  1508. /* Do we need to continue ? */
  1509. if(!irnet_server.running)
  1510. return len;
  1511. /* Protect access to the instance list */
  1512. spin_lock_bh(&irnet_server.spinlock);
  1513. /* Get the sockets one by one... */
  1514. self = (irnet_socket *) hashbin_get_first(irnet_server.list);
  1515. while(self != NULL)
  1516. {
  1517. /* Start printing info about the socket. */
  1518. len += sprintf(buf+len, "\nIrNET socket %d - ", i++);
  1519. /* First, get the requested configuration */
  1520. len += sprintf(buf+len, "Requested IrDA name: \"%s\", ", self->rname);
  1521. len += sprintf(buf+len, "daddr: %08x, ", self->rdaddr);
  1522. len += sprintf(buf+len, "saddr: %08x\n", self->rsaddr);
  1523. /* Second, get all the PPP info */
  1524. len += sprintf(buf+len, " PPP state: %s",
  1525. (self->ppp_open ? "registered" : "unregistered"));
  1526. if(self->ppp_open)
  1527. {
  1528. len += sprintf(buf+len, ", unit: ppp%d",
  1529. ppp_unit_number(&self->chan));
  1530. len += sprintf(buf+len, ", channel: %d",
  1531. ppp_channel_index(&self->chan));
  1532. len += sprintf(buf+len, ", mru: %d",
  1533. self->mru);
  1534. /* Maybe add self->flags ? Later... */
  1535. }
  1536. /* Then, get all the IrDA specific info... */
  1537. if(self->ttp_open)
  1538. state = "connected";
  1539. else
  1540. if(self->tsap != NULL)
  1541. state = "connecting";
  1542. else
  1543. if(self->iriap != NULL)
  1544. state = "searching";
  1545. else
  1546. if(self->ttp_connect)
  1547. state = "weird";
  1548. else
  1549. state = "idle";
  1550. len += sprintf(buf+len, "\n IrDA state: %s, ", state);
  1551. len += sprintf(buf+len, "daddr: %08x, ", self->daddr);
  1552. len += sprintf(buf+len, "stsap_sel: %02x, ", self->stsap_sel);
  1553. len += sprintf(buf+len, "dtsap_sel: %02x\n", self->dtsap_sel);
  1554. /* Next socket, please... */
  1555. self = (irnet_socket *) hashbin_get_next(irnet_server.list);
  1556. }
  1557. /* Spin lock end */
  1558. spin_unlock_bh(&irnet_server.spinlock);
  1559. return len;
  1560. }
  1561. #endif /* PROC_FS */
  1562. /********************** CONFIGURATION/CLEANUP **********************/
  1563. /*
  1564. * Initialisation and teardown of the IrDA part, called at module
  1565. * insertion and removal...
  1566. */
  1567. /*------------------------------------------------------------------*/
  1568. /*
  1569. * Prepare the IrNET layer for operation...
  1570. */
  1571. int __init
  1572. irda_irnet_init(void)
  1573. {
  1574. int err = 0;
  1575. DENTER(MODULE_TRACE, "()\n");
  1576. /* Pure paranoia - should be redundant */
  1577. memset(&irnet_server, 0, sizeof(struct irnet_root));
  1578. /* Setup start of irnet instance list */
  1579. irnet_server.list = hashbin_new(HB_NOLOCK);
  1580. DABORT(irnet_server.list == NULL, -ENOMEM,
  1581. MODULE_ERROR, "Can't allocate hashbin!\n");
  1582. /* Init spinlock for instance list */
  1583. spin_lock_init(&irnet_server.spinlock);
  1584. /* Initialise control channel */
  1585. init_waitqueue_head(&irnet_events.rwait);
  1586. irnet_events.index = 0;
  1587. /* Init spinlock for event logging */
  1588. spin_lock_init(&irnet_events.spinlock);
  1589. #ifdef CONFIG_PROC_FS
  1590. /* Add a /proc file for irnet infos */
  1591. create_proc_info_entry("irnet", 0, proc_irda, irnet_proc_read);
  1592. #endif /* CONFIG_PROC_FS */
  1593. /* Setup the IrNET server */
  1594. err = irnet_setup_server();
  1595. if(!err)
  1596. /* We are no longer functional... */
  1597. irnet_server.running = 1;
  1598. DEXIT(MODULE_TRACE, "\n");
  1599. return err;
  1600. }
  1601. /*------------------------------------------------------------------*/
  1602. /*
  1603. * Cleanup at exit...
  1604. */
  1605. void __exit
  1606. irda_irnet_cleanup(void)
  1607. {
  1608. DENTER(MODULE_TRACE, "()\n");
  1609. /* We are no longer there... */
  1610. irnet_server.running = 0;
  1611. #ifdef CONFIG_PROC_FS
  1612. /* Remove our /proc file */
  1613. remove_proc_entry("irnet", proc_irda);
  1614. #endif /* CONFIG_PROC_FS */
  1615. /* Remove our IrNET server from existence */
  1616. irnet_destroy_server();
  1617. /* Remove all instances of IrNET socket still present */
  1618. hashbin_delete(irnet_server.list, (FREE_FUNC) irda_irnet_destroy);
  1619. DEXIT(MODULE_TRACE, "\n");
  1620. }