librazer.c 38 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573
  1. /*
  2. * Razer device access library
  3. *
  4. * Copyright (C) 2007-2011 Michael Buesch <m@bues.ch>
  5. *
  6. * This program is free software; you can redistribute it and/or
  7. * modify it under the terms of the GNU General Public License
  8. * as published by the Free Software Foundation; either version 2
  9. * of the License, or (at your option) any later version.
  10. *
  11. * This program is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. * GNU General Public License for more details.
  15. */
  16. #include "librazer.h"
  17. #include "razer_private.h"
  18. #include "config.h"
  19. #include "profile_emulation.h"
  20. #include "hw_deathadder.h"
  21. #include "hw_deathadder2013.h"
  22. #include "hw_deathadder_chroma.h"
  23. #include "hw_naga.h"
  24. #include "hw_krait.h"
  25. #include "hw_lachesis.h"
  26. #include "hw_lachesis5k6.h"
  27. #include "hw_copperhead.h"
  28. #include "hw_boomslangce.h"
  29. #include "hw_imperator.h"
  30. #include "hw_taipan.h"
  31. #include <stdint.h>
  32. #include <stdlib.h>
  33. #include <string.h>
  34. #include <errno.h>
  35. #include <stdio.h>
  36. #include <unistd.h>
  37. #include <sys/ioctl.h>
  38. enum razer_devtype {
  39. RAZER_DEVTYPE_MOUSE,
  40. };
  41. /** struct razer_mouse_base_ops - Basic device-init operations
  42. *
  43. * @type: The type ID.
  44. *
  45. * @init: Initialize the device and its private data structures.
  46. *
  47. * @release: Release device and data structures.
  48. */
  49. struct razer_mouse_base_ops {
  50. enum razer_mouse_type type;
  51. int (*init)(struct razer_mouse *m, struct libusb_device *udev);
  52. void (*release)(struct razer_mouse *m);
  53. };
  54. struct razer_usb_device {
  55. uint16_t vendor; /* Vendor ID */
  56. uint16_t product; /* Product ID */
  57. enum razer_devtype type;
  58. union {
  59. const struct razer_mouse_base_ops *mouse_ops;
  60. } u;
  61. };
  62. static const struct razer_mouse_base_ops razer_deathadder_base_ops = {
  63. .type = RAZER_MOUSETYPE_DEATHADDER,
  64. .init = razer_deathadder_init,
  65. .release = razer_deathadder_release,
  66. };
  67. static const struct razer_mouse_base_ops razer_deathadder2013_base_ops = {
  68. .type = RAZER_MOUSETYPE_DEATHADDER,
  69. .init = razer_deathadder2013_init,
  70. .release = razer_deathadder2013_release,
  71. };
  72. static const struct razer_mouse_base_ops razer_deathadder_chroma_base_ops = {
  73. .type = RAZER_MOUSETYPE_DEATHADDER,
  74. .init = razer_deathadder_chroma_init,
  75. .release = razer_deathadder_chroma_release,
  76. };
  77. static const struct razer_mouse_base_ops razer_naga_base_ops = {
  78. .type = RAZER_MOUSETYPE_NAGA,
  79. .init = razer_naga_init,
  80. .release = razer_naga_release,
  81. };
  82. static const struct razer_mouse_base_ops razer_krait_base_ops = {
  83. .type = RAZER_MOUSETYPE_KRAIT,
  84. .init = razer_krait_init,
  85. .release = razer_krait_release,
  86. };
  87. static const struct razer_mouse_base_ops razer_lachesis_base_ops = {
  88. .type = RAZER_MOUSETYPE_LACHESIS,
  89. .init = razer_lachesis_init,
  90. .release = razer_lachesis_release,
  91. };
  92. static const struct razer_mouse_base_ops razer_lachesis5k6_base_ops = {
  93. .type = RAZER_MOUSETYPE_LACHESIS,
  94. .init = razer_lachesis5k6_init,
  95. .release = razer_lachesis5k6_release,
  96. };
  97. static const struct razer_mouse_base_ops razer_copperhead_base_ops = {
  98. .type = RAZER_MOUSETYPE_COPPERHEAD,
  99. .init = razer_copperhead_init,
  100. .release = razer_copperhead_release,
  101. };
  102. static const struct razer_mouse_base_ops razer_boomslangce_base_ops = {
  103. .type = RAZER_MOUSETYPE_BOOMSLANGCE,
  104. .init = razer_boomslangce_init,
  105. .release = razer_boomslangce_release,
  106. };
  107. static const struct razer_mouse_base_ops razer_imperator_base_ops = {
  108. .type = RAZER_MOUSETYPE_IMPERATOR,
  109. .init = razer_imperator_init,
  110. .release = razer_imperator_release,
  111. };
  112. static const struct razer_mouse_base_ops razer_taipan_base_ops = {
  113. .type = RAZER_MOUSETYPE_TAIPAN,
  114. .init = razer_taipan_init,
  115. .release = razer_taipan_release,
  116. };
  117. #define USBVENDOR_ANY 0xFFFF
  118. #define USBPRODUCT_ANY 0xFFFF
  119. #define USB_MOUSE(_vendor, _product, _mouse_ops) \
  120. { .vendor = _vendor, .product = _product, \
  121. .type = RAZER_DEVTYPE_MOUSE, \
  122. .u = { .mouse_ops = _mouse_ops, }, }
  123. /* Table of supported USB devices. */
  124. static const struct razer_usb_device razer_usbdev_table[] = {
  125. USB_MOUSE(0x1532, 0x0007, &razer_deathadder_base_ops), /* classic */
  126. USB_MOUSE(0x1532, 0x0016, &razer_deathadder_base_ops), /* 3500 DPI */
  127. USB_MOUSE(0x1532, 0x0029, &razer_deathadder_base_ops), /* black edition */
  128. USB_MOUSE(0x1532, 0x0037, &razer_deathadder2013_base_ops), /* 2013 edition */
  129. USB_MOUSE(0x1532, 0x0043, &razer_deathadder_chroma_base_ops), /* Chroma edition */
  130. // USB_MOUSE(0x04B4, 0xE006, &razer_deathadder_base_ops), /* cypress bootloader */
  131. USB_MOUSE(0x1532, 0x0003, &razer_krait_base_ops),
  132. USB_MOUSE(0x1532, 0x000C, &razer_lachesis_base_ops), /* classic */
  133. USB_MOUSE(0x1532, 0x001E, &razer_lachesis5k6_base_ops), /* 5600 DPI */
  134. USB_MOUSE(0x1532, RAZER_NAGA_PID_CLASSIC, &razer_naga_base_ops),
  135. USB_MOUSE(0x1532, RAZER_NAGA_PID_EPIC, &razer_naga_base_ops),
  136. USB_MOUSE(0x1532, RAZER_NAGA_PID_2012, &razer_naga_base_ops),
  137. USB_MOUSE(0x1532, RAZER_NAGA_PID_HEX, &razer_naga_base_ops),
  138. USB_MOUSE(0x1532, RAZER_NAGA_PID_2014, &razer_naga_base_ops),
  139. USB_MOUSE(0x1532, RAZER_NAGA_PID_HEX_2014, &razer_naga_base_ops),
  140. USB_MOUSE(0x1532, 0x0101, &razer_copperhead_base_ops),
  141. USB_MOUSE(0x1532, 0x0005, &razer_boomslangce_base_ops),
  142. USB_MOUSE(0x1532, 0x0017, &razer_imperator_base_ops),
  143. USB_MOUSE(0x1532, 0x0034, &razer_taipan_base_ops),
  144. { 0, }, /* List end */
  145. };
  146. #undef USB_MOUSE
  147. static struct libusb_context *libusb_ctx;
  148. static struct razer_mouse *mice_list = NULL;
  149. /* We currently only have one handler. */
  150. static razer_event_handler_t event_handler;
  151. static struct config_file *razer_config_file = NULL;
  152. static bool profile_emu_enabled;
  153. razer_logfunc_t razer_logfunc_info;
  154. razer_logfunc_t razer_logfunc_error;
  155. razer_logfunc_t razer_logfunc_debug;
  156. static inline bool razer_initialized(void)
  157. {
  158. return !!libusb_ctx;
  159. }
  160. int razer_register_event_handler(razer_event_handler_t handler)
  161. {
  162. if (event_handler)
  163. return -EEXIST;
  164. event_handler = handler;
  165. return 0;
  166. }
  167. void razer_unregister_event_handler(razer_event_handler_t handler)
  168. {
  169. event_handler = NULL;
  170. }
  171. static void razer_notify_event(enum razer_event type,
  172. const struct razer_event_data *data)
  173. {
  174. if (event_handler)
  175. event_handler(type, data);
  176. }
  177. static int match_usbdev(const struct libusb_device_descriptor *desc,
  178. const struct razer_usb_device *id)
  179. {
  180. if ((desc->idVendor != id->vendor) &&
  181. (id->vendor != USBVENDOR_ANY))
  182. return 0;
  183. if ((desc->idProduct != id->product) &&
  184. (id->product != USBPRODUCT_ANY))
  185. return 0;
  186. return 1;
  187. }
  188. static const struct razer_usb_device * usbdev_lookup(const struct libusb_device_descriptor *desc)
  189. {
  190. const struct razer_usb_device *id = &(razer_usbdev_table[0]);
  191. while (id->vendor || id->product) {
  192. if (match_usbdev(desc, id))
  193. return id;
  194. id++;
  195. }
  196. return NULL;
  197. }
  198. static void mouse_list_add(struct razer_mouse **base, struct razer_mouse *new_entry)
  199. {
  200. struct razer_mouse *i;
  201. new_entry->next = NULL;
  202. if (!(*base)) {
  203. *base = new_entry;
  204. return;
  205. }
  206. for (i = *base; i->next; i = i->next)
  207. ;
  208. i->next = new_entry;
  209. }
  210. static void mouse_list_del(struct razer_mouse **base, struct razer_mouse *del_entry)
  211. {
  212. struct razer_mouse *i;
  213. if (del_entry == *base) {
  214. *base = (*base)->next;
  215. return;
  216. }
  217. for (i = *base; i && (i->next != del_entry); i = i->next)
  218. ;
  219. if (i)
  220. i->next = del_entry->next;
  221. }
  222. static struct razer_mouse * mouse_list_find(struct razer_mouse *base,
  223. struct libusb_device *udev)
  224. {
  225. struct razer_mouse *m, *next;
  226. uint8_t busnr = libusb_get_bus_number(udev);
  227. uint8_t devaddr = libusb_get_device_address(udev);
  228. razer_for_each_mouse(m, next, base) {
  229. if (m->usb_ctx) {
  230. if (libusb_get_bus_number(m->usb_ctx->dev) == busnr &&
  231. libusb_get_device_address(m->usb_ctx->dev) == devaddr)
  232. return m;
  233. }
  234. }
  235. return NULL;
  236. }
  237. static int parse_idstr(char *idstr, char **devtype, char **devname,
  238. char **buspos, char **devid)
  239. {
  240. *devtype = idstr;
  241. *devname = razer_strsplit(*devtype, ':');
  242. *buspos = razer_strsplit(*devname, ':');
  243. *devid = razer_strsplit(*buspos, ':');
  244. if (!*devtype || !*devname || !*buspos || !*devid)
  245. return -EINVAL;
  246. return 0;
  247. }
  248. static bool simple_globcmp(const char *string,
  249. const char *template)
  250. {
  251. char s, t, tnext;
  252. while (1) {
  253. s = string[0];
  254. t = template[0];
  255. if (s == '\0' && t == '\0')
  256. break;
  257. if (t == '*') {
  258. tnext = template[1];
  259. if (s == '\0') {
  260. if (tnext == '\0')
  261. break;
  262. return 0;
  263. }
  264. if (s == tnext) {
  265. template++;
  266. continue;
  267. }
  268. } else {
  269. if (s == '\0' || t == '\0')
  270. return 0;
  271. if (s != t)
  272. return 0;
  273. template++;
  274. }
  275. string++;
  276. }
  277. return 1; /* Match */
  278. }
  279. static bool mouse_idstr_glob_match(struct config_file *f,
  280. void *context, void *data,
  281. const char *section)
  282. {
  283. struct razer_mouse *m = context;
  284. const char **matched_section = data;
  285. char idstr[RAZER_IDSTR_MAX_SIZE + 1] = { 0, };
  286. char *idstr_devtype, *idstr_devname, *idstr_buspos, *idstr_devid;
  287. char globstr[RAZER_IDSTR_MAX_SIZE + 1] = { 0, };
  288. char *globstr_devtype, *globstr_devname, *globstr_buspos, *globstr_devid;
  289. if (strlen(section) > RAZER_IDSTR_MAX_SIZE) {
  290. razer_error("globbed idstr \"%s\" in config too long\n",
  291. section);
  292. return 1;
  293. }
  294. strcpy(globstr, section);
  295. strcpy(idstr, m->idstr);
  296. if (parse_idstr(globstr, &globstr_devtype, &globstr_devname,
  297. &globstr_buspos, &globstr_devid))
  298. return 1;
  299. if (parse_idstr(idstr, &idstr_devtype, &idstr_devname,
  300. &idstr_buspos, &idstr_devid)) {
  301. razer_error("INTERNAL-ERROR: Failed to parse idstr \"%s\"\n",
  302. idstr);
  303. return 1;
  304. }
  305. if (!simple_globcmp(idstr_devtype, globstr_devtype))
  306. return 1;
  307. if (!simple_globcmp(idstr_devname, globstr_devname))
  308. return 1;
  309. if (!simple_globcmp(idstr_buspos, globstr_buspos))
  310. return 1;
  311. if (!simple_globcmp(idstr_devid, globstr_devid))
  312. return 1;
  313. *matched_section = section;
  314. return 0; /* Match */
  315. }
  316. static struct razer_mouse_profile * find_prof(struct razer_mouse *m, unsigned int nr)
  317. {
  318. struct razer_mouse_profile *list;
  319. unsigned int i;
  320. if (!m->get_profiles)
  321. return NULL;
  322. list = m->get_profiles(m);
  323. if (!list)
  324. return NULL;
  325. for (i = 0; i < m->nr_profiles; i++) {
  326. if (list[i].nr == nr)
  327. return &list[i];
  328. }
  329. return NULL;
  330. }
  331. static int parse_int_int_pair(const char *str, int *val0, int *val1)
  332. {
  333. char a[64] = { 0, }, b[64] = { 0, };
  334. int err;
  335. *val0 = *val1 = -1;
  336. err = razer_split_tuple(str, ':', min(sizeof(a), sizeof(b)),
  337. a, b, NULL);
  338. if (err) {
  339. /* It's not a pair. Interpret it as one value. */
  340. razer_strlcpy(a, str, sizeof(a));
  341. err = razer_string_to_int(razer_string_strip(a), val1);
  342. if (err)
  343. return -EINVAL;
  344. return 1;
  345. }
  346. err = razer_string_to_int(razer_string_strip(a), val0);
  347. err |= razer_string_to_int(razer_string_strip(b), val1);
  348. if (err)
  349. return -EINVAL;
  350. return 0;
  351. }
  352. static bool mouse_apply_one_config(struct config_file *f,
  353. void *context, void *data,
  354. const char *section,
  355. const char *item,
  356. const char *value)
  357. {
  358. struct razer_mouse *m = context;
  359. struct razer_mouse_profile *prof;
  360. bool *error = data;
  361. int err, nr;
  362. static const size_t tmplen = 128;
  363. char a[tmplen], b[tmplen], c[tmplen];
  364. //FIXME fixes for glob/prof configs
  365. if (strcasecmp(item, "profile") == 0) {
  366. int profile;
  367. err = razer_string_to_int(value, &profile);
  368. if (err || profile < 1 || (unsigned int)profile > m->nr_profiles)
  369. goto error;
  370. if (m->set_active_profile) {
  371. prof = find_prof(m, profile - 1);
  372. if (!prof)
  373. goto error;
  374. err = m->set_active_profile(m, prof);
  375. if (err)
  376. goto error;
  377. }
  378. } else if (strcasecmp(item, "res") == 0) {
  379. int profile, resolution, i;
  380. struct razer_mouse_dpimapping *mappings;
  381. err = parse_int_int_pair(value, &profile, &resolution);
  382. if (err == 1) {
  383. prof = m->get_active_profile(m);
  384. profile = prof->nr + 1;
  385. } else if (err)
  386. goto error;
  387. if (profile < 1 || resolution < 1)
  388. goto error;
  389. prof = find_prof(m, profile - 1);
  390. if (!prof)
  391. goto error;
  392. nr = m->supported_dpimappings(m, &mappings);
  393. if (nr <= 0)
  394. goto error;
  395. //FIXME dims
  396. for (i = 0; i < nr; i++) {
  397. if (resolution >= 100) {
  398. if ((int)(mappings[i].res[RAZER_DIM_0]) != resolution)
  399. continue;
  400. } else {
  401. if (mappings[i].nr != (unsigned int)resolution)
  402. continue;
  403. }
  404. err = prof->set_dpimapping(prof, NULL, &mappings[i]);
  405. if (err)
  406. goto error;
  407. goto ok;
  408. }
  409. goto error;
  410. } else if (strcasecmp(item, "freq") == 0) {
  411. int profile, freq, i;
  412. enum razer_mouse_freq *freqs;
  413. err = parse_int_int_pair(value, &profile, &freq);
  414. if (err == 1) {
  415. prof = m->get_active_profile(m);
  416. profile = prof->nr + 1;
  417. } else if (err)
  418. goto error;
  419. if (profile < 1 || freq < 1)
  420. goto error;
  421. prof = find_prof(m, profile - 1);
  422. if (!prof)
  423. goto error;
  424. nr = m->supported_freqs(m, &freqs);
  425. if (nr <= 0)
  426. goto error;
  427. for (i = 0; i < nr; i++) {
  428. if (freqs[i] != (enum razer_mouse_freq)freq)
  429. continue;
  430. err = prof->set_freq(prof, freqs[i]);
  431. razer_free_freq_list(freqs, nr);
  432. if (err)
  433. goto error;
  434. goto ok;
  435. }
  436. razer_free_freq_list(freqs, nr);
  437. goto error;
  438. } else if (strcasecmp(item, "led") == 0) {
  439. bool on;
  440. struct razer_led *leds, *led;
  441. const char *ledname, *ledstate;
  442. int profile;
  443. err = razer_split_tuple(value, ':', tmplen, a, b, c, NULL);
  444. if (err && err != -ENODATA)
  445. goto error;
  446. if (!strlen(a) || !strlen(b))
  447. goto error;
  448. if (strlen(c)) {
  449. /* A profile was specified */
  450. err = razer_string_to_int(razer_string_strip(a), &profile);
  451. if (err || profile < 1)
  452. goto error;
  453. prof = find_prof(m, profile - 1);
  454. if (!prof)
  455. goto error;
  456. ledname = razer_string_strip(b);
  457. ledstate = razer_string_strip(c);
  458. } else {
  459. /* Modify global LEDs */
  460. prof = NULL;
  461. ledname = razer_string_strip(a);
  462. ledstate = razer_string_strip(b);
  463. }
  464. err = razer_string_to_bool(ledstate, &on);
  465. if (err)
  466. goto error;
  467. if (prof) {
  468. if (prof->get_leds) {
  469. err = prof->get_leds(prof, &leds);
  470. } else {
  471. /* Try to fall back to global */
  472. if (!m->global_get_leds)
  473. goto ok; /* No LEDs. Ignore config. */
  474. err = m->global_get_leds(m, &leds);
  475. }
  476. } else {
  477. if (!m->global_get_leds)
  478. goto ok; /* No LEDs. Ignore config. */
  479. err = m->global_get_leds(m, &leds);
  480. }
  481. if (err < 0)
  482. goto error;
  483. if (err == 0)
  484. goto ok; /* No LEDs. Ignore config. */
  485. for (led = leds; led; led = led->next) {
  486. if (strcasecmp(led->name, ledname) != 0)
  487. continue;
  488. if (!led->toggle_state) {
  489. razer_free_leds(leds);
  490. goto invalid;
  491. }
  492. err = led->toggle_state(led,
  493. on ? RAZER_LED_ON : RAZER_LED_OFF);
  494. razer_free_leds(leds);
  495. if (err)
  496. goto error;
  497. goto ok;
  498. }
  499. razer_free_leds(leds);
  500. goto error;
  501. } else if (strcasecmp(item, "mode") == 0) {
  502. enum razer_led_mode mode;
  503. struct razer_led *leds, *led;
  504. const char *ledname, *ledmode;
  505. int profile;
  506. err = razer_split_tuple(value, ':', tmplen, a, b, c, NULL);
  507. if (err && err != -ENODATA)
  508. goto error;
  509. if (!strlen(a) || !strlen(b))
  510. goto error;
  511. if (strlen(c)) {
  512. /* A profile was specified */
  513. err = razer_string_to_int(razer_string_strip(a), &profile);
  514. if (err || profile < 1)
  515. goto error;
  516. prof = find_prof(m, profile - 1);
  517. if (!prof)
  518. goto error;
  519. ledname = razer_string_strip(b);
  520. ledmode = razer_string_strip(c);
  521. } else {
  522. /* Modify global LEDs */
  523. prof = NULL;
  524. ledname = razer_string_strip(a);
  525. ledmode = razer_string_strip(b);
  526. }
  527. err = razer_string_to_mode(ledmode, &mode);
  528. if (err)
  529. goto error;
  530. if (prof) {
  531. if (prof->get_leds) {
  532. err = prof->get_leds(prof, &leds);
  533. } else {
  534. /* Try to fall back to global */
  535. if (!m->global_get_leds)
  536. goto ok; /* No LEDs. Ignore config. */
  537. err = m->global_get_leds(m, &leds);
  538. }
  539. } else {
  540. if (!m->global_get_leds)
  541. goto ok; /* No LEDs. Ignore config. */
  542. err = m->global_get_leds(m, &leds);
  543. }
  544. if (err < 0)
  545. goto error;
  546. if (err == 0)
  547. goto ok; /* No LEDs. Ignore config. */
  548. for (led = leds; led; led = led->next) {
  549. if (strcasecmp(led->name, ledname) != 0)
  550. continue;
  551. if (!led->set_mode) {
  552. razer_free_leds(leds);
  553. goto invalid;
  554. }
  555. err = led->set_mode(led, mode);
  556. razer_free_leds(leds);
  557. if (err)
  558. goto error;
  559. goto ok;
  560. }
  561. razer_free_leds(leds);
  562. goto error;
  563. } else if (strcasecmp(item, "color") == 0) {
  564. struct razer_rgb_color color;
  565. struct razer_led *leds, *led;
  566. const char *ledname, *ledcolor;
  567. int profile;
  568. err = razer_split_tuple(value, ':', tmplen, a, b, c, NULL);
  569. if (err && err != -ENODATA)
  570. goto error;
  571. if (!strlen(a) || !strlen(b))
  572. goto error;
  573. if (strlen(c)) {
  574. /* A profile was specified */
  575. err = razer_string_to_int(razer_string_strip(a), &profile);
  576. if (err || profile < 1)
  577. goto error;
  578. prof = find_prof(m, profile - 1);
  579. if (!prof)
  580. goto error;
  581. ledname = razer_string_strip(b);
  582. ledcolor = razer_string_strip(c);
  583. } else {
  584. /* Modify global LEDs */
  585. prof = NULL;
  586. ledname = razer_string_strip(a);
  587. ledcolor = razer_string_strip(b);
  588. }
  589. err = razer_string_to_color(ledcolor, &color);
  590. if (err)
  591. goto error;
  592. if (prof) {
  593. if (prof->get_leds) {
  594. err = prof->get_leds(prof, &leds);
  595. } else {
  596. /* Try to fall back to global */
  597. if (!m->global_get_leds)
  598. goto ok; /* No LEDs. Ignore config. */
  599. err = m->global_get_leds(m, &leds);
  600. }
  601. } else {
  602. if (!m->global_get_leds)
  603. goto ok; /* No LEDs. Ignore config. */
  604. err = m->global_get_leds(m, &leds);
  605. }
  606. if (err < 0)
  607. goto error;
  608. if (err == 0)
  609. goto ok; /* No LEDs. Ignore config. */
  610. for (led = leds; led; led = led->next) {
  611. if (strcasecmp(led->name, ledname) != 0)
  612. continue;
  613. if (!led->change_color) {
  614. razer_free_leds(leds);
  615. goto invalid;
  616. }
  617. err = led->change_color(led, &color);
  618. razer_free_leds(leds);
  619. if (err)
  620. goto error;
  621. goto ok;
  622. }
  623. razer_free_leds(leds);
  624. goto error;
  625. } else if (strcasecmp(item, "disabled") == 0) {
  626. goto ok;
  627. } else
  628. goto invalid;
  629. ok:
  630. return 1;
  631. error:
  632. *error = 1;
  633. invalid:
  634. razer_error("Config section \"%s\" item \"%s\" "
  635. "invalid.\n", section, item);
  636. return *error ? 0 : 1;
  637. }
  638. static void mouse_apply_initial_config(struct razer_mouse *m)
  639. {
  640. const char *section = NULL;
  641. int err;
  642. bool error = 0;
  643. config_for_each_section(razer_config_file,
  644. m, &section,
  645. mouse_idstr_glob_match);
  646. if (!section)
  647. return;
  648. if (config_get_bool(razer_config_file, section,
  649. "disabled", 0, CONF_NOCASE)) {
  650. razer_debug("Initial config for \"%s\" is disabled. Not applying.\n",
  651. m->idstr);
  652. return;
  653. }
  654. razer_debug("Applying config section \"%s\" to \"%s\"\n",
  655. section, m->idstr);
  656. err = m->claim(m);
  657. if (err) {
  658. razer_error("Failed to claim \"%s\"\n", m->idstr);
  659. return;
  660. }
  661. config_for_each_item(razer_config_file,
  662. m, &error,
  663. section,
  664. mouse_apply_one_config);
  665. m->release(m);
  666. if (error) {
  667. razer_error("Failed to apply initial config "
  668. "to \"%s\"\n", m->idstr);
  669. }
  670. }
  671. static struct razer_usb_context * razer_create_usb_ctx(struct libusb_device *dev)
  672. {
  673. struct razer_usb_context *ctx;
  674. ctx = zalloc(sizeof(*ctx));
  675. if (!ctx)
  676. return NULL;
  677. ctx->dev = dev;
  678. ctx->bConfigurationValue = 1;
  679. return ctx;
  680. }
  681. static int mouse_default_claim(struct razer_mouse *m)
  682. {
  683. return razer_generic_usb_claim_refcount(m->usb_ctx, &m->claim_count);
  684. }
  685. static int mouse_default_release(struct razer_mouse *m)
  686. {
  687. int err = 0;
  688. if (m->claim_count == 1) {
  689. if (m->commit)
  690. err = m->commit(m, 0);
  691. }
  692. razer_generic_usb_release_refcount(m->usb_ctx, &m->claim_count);
  693. return err;
  694. }
  695. static struct razer_mouse * mouse_new(const struct razer_usb_device *id,
  696. struct libusb_device *udev)
  697. {
  698. struct razer_event_data ev;
  699. struct razer_mouse *m;
  700. int err;
  701. libusb_ref_device(udev);
  702. m = zalloc(sizeof(*m));
  703. if (!m)
  704. return NULL;
  705. m->usb_ctx = razer_create_usb_ctx(udev);
  706. if (!m->usb_ctx)
  707. goto err_free_mouse;
  708. /* Set default values and callbacks */
  709. m->nr_profiles = 1;
  710. m->claim = mouse_default_claim;
  711. m->release = mouse_default_release;
  712. /* Call the driver init */
  713. m->base_ops = id->u.mouse_ops;
  714. err = m->base_ops->init(m, udev);
  715. if (err)
  716. goto err_free_ctx;
  717. udev = m->usb_ctx->dev;
  718. if (WARN_ON(m->nr_profiles <= 0))
  719. goto err_release;
  720. if (m->nr_profiles == 1 && !m->get_active_profile)
  721. m->get_active_profile = m->get_profiles;
  722. if (profile_emu_enabled && m->nr_profiles == 1) {
  723. err = razer_mouse_init_profile_emulation(m);
  724. if (err)
  725. goto err_release;
  726. }
  727. mouse_apply_initial_config(m);
  728. razer_debug("Allocated and initialized new mouse \"%s\"\n",
  729. m->idstr);
  730. ev.u.mouse = m;
  731. razer_notify_event(RAZER_EV_MOUSE_ADD, &ev);
  732. return m;
  733. err_release:
  734. m->base_ops->release(m);
  735. err_free_ctx:
  736. razer_free(m->usb_ctx, sizeof(*(m->usb_ctx)));
  737. err_free_mouse:
  738. razer_free(m, sizeof(*m));
  739. libusb_unref_device(udev);
  740. return NULL;
  741. }
  742. static void razer_free_mouse(struct razer_mouse *m)
  743. {
  744. struct razer_event_data ev;
  745. razer_debug("Freeing mouse (type=%d)\n",
  746. m->base_ops->type);
  747. ev.u.mouse = m;
  748. razer_notify_event(RAZER_EV_MOUSE_REMOVE, &ev);
  749. if (m->release == mouse_default_release) {
  750. while (m->claim_count)
  751. m->release(m);
  752. }
  753. razer_mouse_exit_profile_emulation(m);
  754. m->base_ops->release(m);
  755. libusb_unref_device(m->usb_ctx->dev);
  756. razer_free(m->usb_ctx, sizeof(*(m->usb_ctx)));
  757. razer_free(m, sizeof(*m));
  758. }
  759. static void razer_free_mice(struct razer_mouse *mouse_list)
  760. {
  761. struct razer_mouse *mouse, *next;
  762. for (mouse = mouse_list; mouse; ) {
  763. next = mouse->next;
  764. razer_free_mouse(mouse);
  765. mouse = next;
  766. }
  767. }
  768. struct new_razer_usb_device {
  769. const struct razer_usb_device *id;
  770. struct usb_device *udev;
  771. };
  772. struct razer_mouse * razer_rescan_mice(void)
  773. {
  774. struct libusb_device **devlist, *dev;
  775. ssize_t nr_devices;
  776. unsigned int i;
  777. int err;
  778. struct libusb_device_descriptor desc;
  779. const struct razer_usb_device *id;
  780. struct razer_mouse *m, *next;
  781. nr_devices = libusb_get_device_list(libusb_ctx, &devlist);
  782. if (nr_devices < 0) {
  783. razer_error("razer_rescan_mice: Failed to get USB device list\n");
  784. return NULL;
  785. }
  786. for (i = 0; i < nr_devices; i++) {
  787. dev = devlist[i];
  788. err = libusb_get_device_descriptor(dev, &desc);
  789. if (err) {
  790. razer_error("razer_rescan_mice: Failed to get descriptor\n");
  791. continue;
  792. }
  793. id = usbdev_lookup(&desc);
  794. if (!id || id->type != RAZER_DEVTYPE_MOUSE)
  795. continue;
  796. m = mouse_list_find(mice_list, dev);
  797. if (m) {
  798. /* We already had this mouse */
  799. m->flags |= RAZER_MOUSEFLG_PRESENT;
  800. } else {
  801. /* We don't have this mouse, yet. Create a new one */
  802. m = mouse_new(id, dev);
  803. if (m) {
  804. m->flags |= RAZER_MOUSEFLG_PRESENT;
  805. mouse_list_add(&mice_list, m);
  806. }
  807. }
  808. }
  809. /* Remove mice that are not connected anymore. */
  810. razer_for_each_mouse(m, next, mice_list) {
  811. if (m->flags & RAZER_MOUSEFLG_PRESENT) {
  812. m->flags &= ~RAZER_MOUSEFLG_PRESENT;
  813. continue;
  814. }
  815. mouse_list_del(&mice_list, m);
  816. razer_free_mouse(m);
  817. }
  818. libusb_free_device_list(devlist, 1);
  819. return mice_list;
  820. }
  821. int razer_reconfig_mice(void)
  822. {
  823. struct razer_mouse *m, *next;
  824. int err;
  825. razer_for_each_mouse(m, next, mice_list) {
  826. err = m->claim(m);
  827. if (err)
  828. return err;
  829. if (m->commit)
  830. err = m->commit(m, 1);
  831. m->release(m);
  832. if (err)
  833. return err;
  834. }
  835. return 0;
  836. }
  837. void razer_free_freq_list(enum razer_mouse_freq *freq_list, int count)
  838. {
  839. if (freq_list)
  840. free(freq_list);
  841. }
  842. void razer_free_resolution_list(enum razer_mouse_res *res_list, int count)
  843. {
  844. if (res_list)
  845. free(res_list);
  846. }
  847. void razer_free_leds(struct razer_led *led_list)
  848. {
  849. struct razer_led *led, *next;
  850. for (led = led_list; led; ) {
  851. next = led->next;
  852. free(led);
  853. led = next;
  854. }
  855. }
  856. int razer_init(int enable_profile_emu)
  857. {
  858. int err = 0;
  859. if (!razer_initialized())
  860. err = libusb_init(&libusb_ctx);
  861. if (!err)
  862. profile_emu_enabled = enable_profile_emu;
  863. return err ? -EINVAL : 0;
  864. }
  865. void razer_exit(void)
  866. {
  867. if (!razer_initialized())
  868. return;
  869. razer_free_mice(mice_list);
  870. mice_list = NULL;
  871. config_file_free(razer_config_file);
  872. razer_config_file = NULL;
  873. libusb_exit(libusb_ctx);
  874. libusb_ctx = NULL;
  875. }
  876. int razer_usb_add_used_interface(struct razer_usb_context *ctx,
  877. int bInterfaceNumber,
  878. int bAlternateSetting)
  879. {
  880. struct razer_usb_interface *interf;
  881. if (ctx->nr_interfaces >= ARRAY_SIZE(ctx->interfaces)) {
  882. razer_error("USB context interface array overflow\n");
  883. return -ENOSPC;
  884. }
  885. interf = &ctx->interfaces[ctx->nr_interfaces];
  886. interf->bInterfaceNumber = bInterfaceNumber;
  887. interf->bAlternateSetting = bAlternateSetting;
  888. ctx->nr_interfaces++;
  889. return 0;
  890. }
  891. static void razer_reattach_usb_kdrv(struct razer_usb_context *ctx,
  892. int bInterfaceNumber)
  893. {
  894. int res;
  895. res = libusb_kernel_driver_active(ctx->h, bInterfaceNumber);
  896. if (res == 1)
  897. return;
  898. if (res) {
  899. razer_error("Failed to get kernel driver state\n");
  900. return;
  901. }
  902. res = libusb_attach_kernel_driver(ctx->h, bInterfaceNumber);
  903. if (res) {
  904. razer_error("Failed to reconnect the kernel driver (%d).\n"
  905. "The device most likely won't work now. Try to replug it.\n", res);
  906. return;
  907. }
  908. }
  909. static void razer_usb_release(struct razer_usb_context *ctx,
  910. int bInterfaceNumber)
  911. {
  912. libusb_release_interface(ctx->h, bInterfaceNumber);
  913. razer_reattach_usb_kdrv(ctx, bInterfaceNumber);
  914. }
  915. int razer_generic_usb_claim(struct razer_usb_context *ctx)
  916. {
  917. unsigned int tries, i;
  918. int err, config;
  919. struct razer_usb_interface *interf;
  920. err = libusb_open(ctx->dev, &ctx->h);
  921. if (err) {
  922. razer_error("razer_generic_usb_claim: Failed to open USB device\n");
  923. return -ENODEV;
  924. }
  925. /* Detach kernel drivers for all interfaces. */
  926. for (i = 0; i < ctx->nr_interfaces; i++) {
  927. interf = &ctx->interfaces[i];
  928. err = libusb_kernel_driver_active(ctx->h, interf->bInterfaceNumber);
  929. if (err == 1) {
  930. err = libusb_detach_kernel_driver(ctx->h, interf->bInterfaceNumber);
  931. if (err) {
  932. err = -EBUSY;
  933. razer_error("Failed to detach kernel driver\n");
  934. goto err_close;
  935. }
  936. } else if (err) {
  937. err = -ENODEV;
  938. razer_error("Failed to get kernel driver state\n");
  939. goto err_close;
  940. }
  941. }
  942. tries = 0;
  943. while (1) {
  944. if (tries >= 10) {
  945. razer_error("razer_generic_usb_claim: Failed to claim config\n");
  946. goto err_close;
  947. }
  948. /* Select the correct configuration */
  949. err = libusb_get_configuration(ctx->h, &config);
  950. if (err) {
  951. err = -EBUSY;
  952. razer_error("razer_generic_usb_claim: Failed to get configuration\n");
  953. goto err_close;
  954. }
  955. if (config != ctx->bConfigurationValue) {
  956. err = libusb_set_configuration(ctx->h, ctx->bConfigurationValue);
  957. if (err) {
  958. err = -EBUSY;
  959. razer_error("razer_generic_usb_claim: Failed to set configuration\n");
  960. goto err_close;
  961. }
  962. }
  963. /* And finally claim all interfaces. */
  964. for (i = 0; i < ctx->nr_interfaces; i++) {
  965. interf = &ctx->interfaces[i];
  966. err = libusb_claim_interface(ctx->h, interf->bInterfaceNumber);
  967. if (err) {
  968. err = -EIO;
  969. razer_error("Failed to claim USB interface\n");
  970. goto err_close;
  971. }
  972. err = libusb_set_interface_alt_setting(ctx->h, interf->bInterfaceNumber,
  973. interf->bAlternateSetting);
  974. if (err) {
  975. /* This error triggers on some devices.
  976. * Just print a warning and ignore. */
  977. razer_info("razer_generic_usb_claim: "
  978. "Failed to set alt setting %d on interface %d. "
  979. "Ignoring...\n",
  980. (int)interf->bAlternateSetting,
  981. (int)interf->bInterfaceNumber);
  982. }
  983. }
  984. /* To make sure there was no race, check config value again */
  985. err = libusb_get_configuration(ctx->h, &config);
  986. if (err) {
  987. err = -EBUSY;
  988. razer_error("razer_generic_usb_claim: Failed to get configuration\n");
  989. goto err_close;
  990. }
  991. if (config == ctx->bConfigurationValue)
  992. break;
  993. razer_msleep(100);
  994. tries++;
  995. }
  996. return 0;
  997. err_close:
  998. libusb_close(ctx->h);
  999. return err;
  1000. }
  1001. int razer_generic_usb_claim_refcount(struct razer_usb_context *ctx,
  1002. unsigned int *refcount)
  1003. {
  1004. int err;
  1005. if (!(*refcount)) {
  1006. err = razer_generic_usb_claim(ctx);
  1007. if (err)
  1008. return err;
  1009. }
  1010. (*refcount)++;
  1011. return 0;
  1012. }
  1013. void razer_generic_usb_release(struct razer_usb_context *ctx)
  1014. {
  1015. int i;
  1016. for (i = ctx->nr_interfaces - 1; i >= 0; i--)
  1017. razer_usb_release(ctx, ctx->interfaces[i].bInterfaceNumber);
  1018. libusb_close(ctx->h);
  1019. }
  1020. void razer_generic_usb_release_refcount(struct razer_usb_context *ctx,
  1021. unsigned int *refcount)
  1022. {
  1023. if (*refcount) {
  1024. (*refcount)--;
  1025. if (!(*refcount))
  1026. razer_generic_usb_release(ctx);
  1027. }
  1028. }
  1029. void razer_generic_usb_gen_idstr(struct libusb_device *udev,
  1030. struct libusb_device_handle *h,
  1031. const char *devname,
  1032. bool include_devicenr,
  1033. const char *serial,
  1034. char *idstr_buf)
  1035. {
  1036. char devid[64];
  1037. char serial_buf[64];
  1038. char buspos[512];
  1039. char c;
  1040. size_t i;
  1041. unsigned int serial_index = 0;
  1042. int err;
  1043. struct libusb_device_descriptor devdesc;
  1044. struct razer_usb_context usbctx = {
  1045. .dev = udev,
  1046. .h = h,
  1047. };
  1048. err = libusb_get_device_descriptor(udev, &devdesc);
  1049. if (err) {
  1050. razer_error("razer_generic_usb_gen_idstr: Failed to get "
  1051. "device descriptor (%d)\n", err);
  1052. return;
  1053. }
  1054. if (serial && strlen(serial)) {
  1055. /* Enforce ASCII characters. */
  1056. for (i = 0; i < ARRAY_SIZE(serial_buf) - 1; i++) {
  1057. c = serial[i];
  1058. if (c == '\0')
  1059. break;
  1060. if ((unsigned char)c <= 0x7Fu)
  1061. serial_buf[i] = c;
  1062. else
  1063. serial_buf[i] = '?'; /* Non-ASCII char. */
  1064. }
  1065. serial_buf[i] = '\0';
  1066. serial = serial_buf;
  1067. } else {
  1068. serial_buf[0] = '\0';
  1069. serial_index = devdesc.iSerialNumber;
  1070. err = -EINVAL;
  1071. if (serial_index) {
  1072. err = 0;
  1073. if (!h)
  1074. err = razer_generic_usb_claim(&usbctx);
  1075. if (err) {
  1076. razer_error("Failed to claim device for serial fetching.\n");
  1077. } else {
  1078. err = libusb_get_string_descriptor_ascii(
  1079. usbctx.h, serial_index,
  1080. (unsigned char *)serial_buf, sizeof(serial_buf));
  1081. if (!h)
  1082. razer_generic_usb_release(&usbctx);
  1083. /* Enforce ASCII characters. */
  1084. for (i = 0; i < ARRAY_SIZE(serial_buf); i++) {
  1085. if (serial_buf[i] == '\0')
  1086. break;
  1087. if ((unsigned char)serial_buf[i] > 0x7Fu)
  1088. serial_buf[i] = '?'; /* Non-ASCII char. */
  1089. }
  1090. }
  1091. }
  1092. if (err <= 0)
  1093. strcpy(serial_buf, "0");
  1094. serial = serial_buf;
  1095. }
  1096. snprintf(devid, sizeof(devid), "%04X-%04X-%s",
  1097. devdesc.idVendor,
  1098. devdesc.idProduct, serial);
  1099. if (include_devicenr) {
  1100. snprintf(buspos, sizeof(buspos), "%03d-%03d",
  1101. libusb_get_bus_number(udev),
  1102. libusb_get_device_address(udev));
  1103. } else {
  1104. snprintf(buspos, sizeof(buspos), "%03d",
  1105. libusb_get_bus_number(udev));
  1106. }
  1107. razer_create_idstr(idstr_buf, BUSTYPESTR_USB, buspos,
  1108. DEVTYPESTR_MOUSE, devname, devid);
  1109. }
  1110. /** razer_usb_force_hub_reset
  1111. * Force reset of the hub the specified device is on
  1112. */
  1113. int razer_usb_force_hub_reset(struct razer_usb_context *device_ctx)
  1114. {
  1115. struct libusb_device_handle *h;
  1116. struct libusb_device *hub = NULL, *dev;
  1117. uint8_t hub_bus_number, hub_device_address;
  1118. struct razer_usb_reconnect_guard rg;
  1119. int err;
  1120. struct libusb_device **devlist;
  1121. ssize_t devlist_size, i;
  1122. razer_debug("Forcing hub reset for device %03u:%03u\n",
  1123. libusb_get_bus_number(device_ctx->dev),
  1124. libusb_get_device_address(device_ctx->dev));
  1125. razer_usb_reconnect_guard_init(&rg, device_ctx);
  1126. hub_bus_number = libusb_get_bus_number(device_ctx->dev);
  1127. hub_device_address = 1; /* Constant */
  1128. devlist_size = libusb_get_device_list(libusb_ctx, &devlist);
  1129. for (i = 0; i < devlist_size; i++) {
  1130. dev = devlist[i];
  1131. if (libusb_get_bus_number(dev) == hub_bus_number &&
  1132. libusb_get_device_address(dev) == hub_device_address) {
  1133. hub = dev;
  1134. break;
  1135. }
  1136. }
  1137. if (!hub) {
  1138. razer_error("razer_usb_force_reinit: Failed to find hub\n");
  1139. err = -ENODEV;
  1140. goto error;
  1141. }
  1142. razer_debug("Resetting root hub %03u:%03u\n",
  1143. hub_bus_number, hub_device_address);
  1144. err = libusb_open(hub, &h);
  1145. if (err) {
  1146. razer_error("razer_usb_force_reinit: Failed to open hub device\n");
  1147. err = -ENODEV;
  1148. goto error;
  1149. }
  1150. libusb_reset_device(h);
  1151. libusb_close(h);
  1152. err = razer_usb_reconnect_guard_wait(&rg, 1);
  1153. if (err) {
  1154. razer_error("razer_usb_force_reinit: "
  1155. "Failed to discover the reconnected device\n");
  1156. goto error;
  1157. }
  1158. razer_debug("Hub reset completed. Device rediscovered as %03u:%03u\n",
  1159. libusb_get_bus_number(device_ctx->dev),
  1160. libusb_get_device_address(device_ctx->dev));
  1161. err = 0;
  1162. error:
  1163. libusb_free_device_list(devlist, 1);
  1164. return err;
  1165. }
  1166. /** razer_usb_reconnect_guard_init - Init the reconnect-guard context
  1167. *
  1168. * Call this _before_ triggering any device operations that might
  1169. * reset the device.
  1170. */
  1171. int razer_usb_reconnect_guard_init(struct razer_usb_reconnect_guard *guard,
  1172. struct razer_usb_context *ctx)
  1173. {
  1174. int err;
  1175. guard->ctx = ctx;
  1176. err = libusb_get_device_descriptor(ctx->dev, &guard->old_desc);
  1177. if (err) {
  1178. razer_error("razer_usb_reconnect_guard_init: Failed to "
  1179. "get device descriptor\n");
  1180. return err;
  1181. }
  1182. guard->old_busnr = libusb_get_bus_number(ctx->dev);
  1183. guard->old_devaddr = libusb_get_device_address(ctx->dev);
  1184. return 0;
  1185. }
  1186. static struct libusb_device * guard_find_usb_dev(const struct libusb_device_descriptor *expected_desc,
  1187. uint8_t expected_bus_number,
  1188. uint8_t expected_dev_addr,
  1189. bool exact_match)
  1190. {
  1191. struct libusb_device **devlist, *dev;
  1192. struct libusb_device_descriptor desc;
  1193. uint8_t dev_addr;
  1194. ssize_t nr_devices, i, j;
  1195. int err;
  1196. nr_devices = libusb_get_device_list(libusb_ctx, &devlist);
  1197. if (nr_devices < 0) {
  1198. razer_error("guard_find_usb_dev: Failed to get device list\n");
  1199. return NULL;
  1200. }
  1201. for (i = 0; i < nr_devices; i++) {
  1202. dev = devlist[i];
  1203. if (libusb_get_bus_number(dev) != expected_bus_number)
  1204. continue;
  1205. err = libusb_get_device_descriptor(dev, &desc);
  1206. if (err)
  1207. continue;
  1208. if (memcmp(&desc, expected_desc, sizeof(desc)) != 0)
  1209. continue;
  1210. dev_addr = libusb_get_device_address(dev);
  1211. if (exact_match) {
  1212. if (dev_addr == expected_dev_addr)
  1213. goto found_dev;
  1214. } else {
  1215. for (j = 0; j < 64; j++) {
  1216. if (dev_addr == ((expected_dev_addr + j) & 0x7F))
  1217. goto found_dev;
  1218. }
  1219. }
  1220. }
  1221. libusb_free_device_list(devlist, 1);
  1222. return NULL;
  1223. found_dev:
  1224. libusb_ref_device(dev);
  1225. libusb_free_device_list(devlist, 1);
  1226. return dev;
  1227. }
  1228. /** razer_usb_reconnect_guard_wait - Protect against a firmware reconnect.
  1229. *
  1230. * If the firmware does a reconnect of the device on the USB bus, this
  1231. * function tries to keep track of the device and it will update the
  1232. * usb context information.
  1233. * Of course, this is not completely race-free, but we try to do our best.
  1234. *
  1235. * hub_reset is true, if the device reconnects due to a HUB reset event.
  1236. * Otherwise it's assumed that the device reconnects on behalf of itself.
  1237. * If hub_reset is false, the device is expected to be claimed.
  1238. */
  1239. int razer_usb_reconnect_guard_wait(struct razer_usb_reconnect_guard *guard, bool hub_reset)
  1240. {
  1241. uint8_t reconn_dev_addr;
  1242. uint8_t old_dev_addr = guard->old_devaddr;
  1243. uint8_t old_bus_number = guard->old_busnr;
  1244. int res, errorcode = 0;
  1245. struct libusb_device *dev;
  1246. struct timeval now, timeout;
  1247. if (!hub_reset) {
  1248. /* Release the device, so the kernel can detect the bus reconnect. */
  1249. razer_generic_usb_release(guard->ctx);
  1250. }
  1251. /* Wait for the device to disconnect. */
  1252. gettimeofday(&timeout, NULL);
  1253. razer_timeval_add_msec(&timeout, 3000);
  1254. while (1) {
  1255. dev = guard_find_usb_dev(&guard->old_desc,
  1256. old_bus_number, old_dev_addr, 1);
  1257. if (!dev)
  1258. break;
  1259. libusb_unref_device(dev);
  1260. gettimeofday(&now, NULL);
  1261. if (razer_timeval_after(&now, &timeout)) {
  1262. /* Timeout. Hm. It seems the device won't reconnect.
  1263. * That's probably OK. Reclaim it. */
  1264. razer_error("razer_usb_reconnect_guard: "
  1265. "The device did not disconnect! If it "
  1266. "does not work anymore, try to replug it.\n");
  1267. goto reclaim;
  1268. }
  1269. razer_msleep(50);
  1270. }
  1271. /* Construct the device address it will reconnect on.
  1272. * On a device reset the new dev addr will be >= reconn_dev_addr.
  1273. */
  1274. reconn_dev_addr = (old_dev_addr + 1) & 0x7F;
  1275. /* Wait for the device to reconnect. */
  1276. gettimeofday(&timeout, NULL);
  1277. razer_timeval_add_msec(&timeout, 3000);
  1278. while (1) {
  1279. dev = guard_find_usb_dev(&guard->old_desc,
  1280. old_bus_number, reconn_dev_addr, 0);
  1281. if (dev)
  1282. break;
  1283. gettimeofday(&now, NULL);
  1284. if (razer_timeval_after(&now, &timeout)) {
  1285. razer_error("razer_usb_reconnect_guard: The device did not "
  1286. "reconnect! It might not work anymore. Try to replug it.\n");
  1287. razer_debug("Expected reconnect busid was: %02u:>=%03u\n",
  1288. old_dev_addr, reconn_dev_addr);
  1289. errorcode = -EBUSY;
  1290. goto out;
  1291. }
  1292. razer_msleep(50);
  1293. }
  1294. /* Update the USB context. */
  1295. libusb_unref_device(guard->ctx->dev);
  1296. guard->ctx->dev = dev;
  1297. reclaim:
  1298. if (!hub_reset) {
  1299. /* Reclaim the new device. */
  1300. res = razer_generic_usb_claim(guard->ctx);
  1301. if (res) {
  1302. razer_error("razer_usb_reconnect_guard: Reclaim failed.\n");
  1303. return res;
  1304. }
  1305. }
  1306. out:
  1307. return errorcode;
  1308. }
  1309. int razer_load_config(const char *path)
  1310. {
  1311. struct config_file *conf = NULL;
  1312. if (!razer_initialized())
  1313. return -EINVAL;
  1314. if (!path)
  1315. path = RAZER_DEFAULT_CONFIG;
  1316. if (strlen(path)) {
  1317. conf = config_file_parse(path, 1);
  1318. if (!conf)
  1319. return -ENOENT;
  1320. }
  1321. config_file_free(razer_config_file);
  1322. razer_config_file = conf;
  1323. return 0;
  1324. }
  1325. void razer_set_logging(razer_logfunc_t info_callback,
  1326. razer_logfunc_t error_callback,
  1327. razer_logfunc_t debug_callback)
  1328. {
  1329. razer_logfunc_info = info_callback;
  1330. razer_logfunc_error = error_callback;
  1331. razer_logfunc_debug = debug_callback;
  1332. }
  1333. static void do_init_axis(struct razer_axis *axis,
  1334. unsigned int id, const char *name, unsigned int flags)
  1335. {
  1336. if (name) {
  1337. axis->id = id;
  1338. axis->name = name;
  1339. axis->flags = flags;
  1340. }
  1341. }
  1342. void razer_init_axes(struct razer_axis *axes,
  1343. const char *name0, unsigned int flags0,
  1344. const char *name1, unsigned int flags1,
  1345. const char *name2, unsigned int flags2)
  1346. {
  1347. do_init_axis(&axes[0], 0, name0, flags0);
  1348. do_init_axis(&axes[1], 1, name1, flags1);
  1349. do_init_axis(&axes[2], 2, name2, flags2);
  1350. }
  1351. struct razer_mouse_dpimapping * razer_mouse_get_dpimapping_by_res(
  1352. struct razer_mouse_dpimapping *mappings, size_t nr_mappings,
  1353. enum razer_dimension dim, enum razer_mouse_res res)
  1354. {
  1355. struct razer_mouse_dpimapping *mapping = NULL;
  1356. size_t i;
  1357. for (i = 0; i < nr_mappings; i++) {
  1358. if (mappings[i].res[dim] == res) {
  1359. mapping = &mappings[i];
  1360. break;
  1361. }
  1362. }
  1363. return mapping;
  1364. }
  1365. void razer_event_spacing_init(struct razer_event_spacing *es,
  1366. unsigned int msec)
  1367. {
  1368. memset(es, 0, sizeof(*es));
  1369. es->spacing_msec = msec;
  1370. }
  1371. void razer_event_spacing_enter(struct razer_event_spacing *es)
  1372. {
  1373. struct timeval now, deadline;
  1374. int wait_msec;
  1375. gettimeofday(&now, NULL);
  1376. deadline = es->last_event;
  1377. razer_timeval_add_msec(&deadline, es->spacing_msec);
  1378. if (razer_timeval_after(&deadline, &now)) {
  1379. /* We have to sleep long enough to ensure we're
  1380. * after the deadline. */
  1381. wait_msec = razer_timeval_msec_diff(&deadline, &now);
  1382. WARN_ON(wait_msec < 0);
  1383. razer_msleep(wait_msec + 1);
  1384. gettimeofday(&now, NULL);
  1385. razer_error_on(razer_timeval_after(&deadline, &now),
  1386. "Failed to maintain event spacing\n");
  1387. }
  1388. }
  1389. void razer_event_spacing_leave(struct razer_event_spacing *es)
  1390. {
  1391. gettimeofday(&es->last_event, NULL);
  1392. }