ckb-next  v0.2.8 at branch master
ckb-next driver for corsair devices
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
usb_linux.c
Go to the documentation of this file.
1 #include "device.h"
2 #include "devnode.h"
3 #include "input.h"
4 #include "notify.h"
5 #include "usb.h"
6 
7 #ifdef OS_LINUX
8 
11 #define DEBUG
12 
13 static char kbsyspath[DEV_MAX][FILENAME_MAX];
14 
68 int os_usbsend(usbdevice* kb, const uchar* out_msg, int is_recv, const char* file, int line) {
69  int res;
70  if ((kb->fwversion >= 0x120 || IS_V2_OVERRIDE(kb)) && !is_recv){
71  struct usbdevfs_bulktransfer transfer = {0};
72  // FW 2.XX uses 0x03, FW 3.XX uses 0x02
73  transfer.ep = (kb->fwversion >= 0x130 && kb->fwversion < 0x200) ? 4 : (kb->fwversion >= 0x300 ? 2 : 3);
74  transfer.len = MSG_SIZE;
75  transfer.timeout = 5000;
76  transfer.data = (void*)out_msg;
77  res = ioctl(kb->handle - 1, USBDEVFS_BULK, &transfer);
78  } else {
79  struct usbdevfs_ctrltransfer transfer = { 0x21, 0x09, 0x0200, kb->epcount - 1, MSG_SIZE, 5000, (void*)out_msg };
80  res = ioctl(kb->handle - 1, USBDEVFS_CONTROL, &transfer);
81  }
82 
83  if (res <= 0){
84  ckb_err_fn(" %s, res = 0x%x\n", file, line, res ? strerror(errno) : "No data written", res);
85  if(res == -1 && errno == ETIMEDOUT)
86  return -1;
87  else
88  return 0;
89  } else if (res != MSG_SIZE)
90  ckb_warn_fn("Wrote %d bytes (expected %d)\n", file, line, res, MSG_SIZE);
91 #ifdef DEBUG_USB_SEND
92  char converted[MSG_SIZE*3 + 1];
93  for(int i=0;i<MSG_SIZE;i++)
94  sprintf(&converted[i*3], "%02x ", out_msg[i]);
95  ckb_warn_fn("Sent %s\n", file, line, converted);
96 #endif
97  return res;
98 }
99 
102 
130 int os_usbrecv(usbdevice* kb, uchar* in_msg, const char* file, int line){
131  int res;
132  // This is what CUE does, but it doesn't seem to work on linux.
133  /*if(kb->fwversion >= 0x130){
134  struct usbdevfs_bulktransfer transfer = {0};
135  transfer.ep = 0x84;
136  transfer.len = MSG_SIZE;
137  transfer.timeout = 5000;
138  transfer.data = in_msg;
139  res = ioctl(kb->handle - 1, USBDEVFS_BULK, &transfer);
140  } else {*/
141  struct usbdevfs_ctrltransfer transfer = { 0xa1, 0x01, 0x0300, kb->epcount - 1, MSG_SIZE, 5000, in_msg };
142  res = ioctl(kb->handle - 1, USBDEVFS_CONTROL, &transfer);
143  //}
144  if(res <= 0){
145  ckb_err_fn("%s\n", file, line, res ? strerror(errno) : "No data read");
146  if(res == -1 && errno == ETIMEDOUT)
147  return -1;
148  else
149  return 0;
150  } else if(res != MSG_SIZE)
151  ckb_warn_fn("Read %d bytes (expected %d)\n", file, line, res, MSG_SIZE);
152 #ifdef DEBUG_USB_RECV
153  char converted[MSG_SIZE*3 + 1];
154  for(int i=0;i<MSG_SIZE;i++)
155  sprintf(&converted[i*3], "%02x ", in_msg[i]);
156  ckb_warn_fn("Recv %s\n", file, line, converted);
157 #endif
158  return res;
159 }
160 
189 int _nk95cmd(usbdevice* kb, uchar bRequest, ushort wValue, const char* file, int line){
190  if(kb->product != P_K95_NRGB)
191  return 0;
192  struct usbdevfs_ctrltransfer transfer = { 0x40, bRequest, wValue, 0, 0, 5000, 0 };
193  int res = ioctl(kb->handle - 1, USBDEVFS_CONTROL, &transfer);
194  if(res <= 0){
195  ckb_err_fn("%s\n", file, line, res ? strerror(errno) : "No data written");
196  return 1;
197  }
198  return 0;
199 }
200 
215  static int countForReset = 0;
216  void *ileds;
217  ushort leds;
218  if(kb->fwversion >= 0x300) {
219  leds = (kb->ileds << 8) | 0x0001;
220  ileds = &leds;
221  }
222  else {
223  ileds = &kb->ileds;
224  }
225  struct usbdevfs_ctrltransfer transfer = { 0x21, 0x09, 0x0200, 0x00, (kb->fwversion >= 0x300 ? 2 : 1), 500, ileds };
226  int res = ioctl(kb->handle - 1, USBDEVFS_CONTROL, &transfer);
227  if(res <= 0) {
228  ckb_err("%s\n", res ? strerror(errno) : "No data written");
229  if (usb_tryreset(kb) == 0 && countForReset++ < 3) {
230  os_sendindicators(kb);
231  }
232  }
233 }
234 
247 
248 void* os_inputmain(void* context){
249  usbdevice* kb = context;
250  int fd = kb->handle - 1;
251  short vendor = kb->vendor, product = kb->product;
252  int index = INDEX_OF(kb, keyboard);
253  ckb_info("Starting input thread for %s%d\n", devpath, index);
254 
259  int urbcount = IS_RGB(vendor, product) ? (kb->epcount - 1) : kb->epcount;
260  if (urbcount == 0) {
261  ckb_err("urbcount = 0, so there is nothing to claim in os_inputmain()\n");
262  return 0;
263  }
264 
266  struct usbdevfs_urb urbs[urbcount + 1];
267  memset(urbs, 0, sizeof(urbs));
268 
282  urbs[0].buffer_length = (kb->fwversion >= 0x300 ? MSG_SIZE : 8);
283  if(urbcount > 1 && IS_RGB(vendor, product)) {
284  if(IS_MOUSE(vendor, product))
285  urbs[1].buffer_length = 10;
286  else
287  urbs[1].buffer_length = 21;
288  urbs[2].buffer_length = MSG_SIZE;
289  if(urbcount != 3)
290  urbs[urbcount - 1].buffer_length = MSG_SIZE;
291  } else if(kb->fwversion < 0x300) {
292  urbs[1].buffer_length = 4;
293  urbs[2].buffer_length = 15;
294  }
295 
298  for(int i = 0; i < urbcount; i++){
299  urbs[i].type = USBDEVFS_URB_TYPE_INTERRUPT;
300  urbs[i].endpoint = 0x80 | (i + 1);
301  urbs[i].buffer = malloc(urbs[i].buffer_length);
302  ioctl(fd, USBDEVFS_SUBMITURB, urbs + i);
303  }
304 
306  while (1) {
307  struct usbdevfs_urb* urb = 0;
308 
311  if (ioctl(fd, USBDEVFS_REAPURB, &urb)) {
312  if (errno == ENODEV || errno == ENOENT || errno == ESHUTDOWN)
313  // Stop the thread if the handle closes
314  break;
315  else if(errno == EPIPE && urb){
317  ioctl(fd, USBDEVFS_CLEAR_HALT, &urb->endpoint);
318  // Re-submit the URB
319  if(urb)
320  ioctl(fd, USBDEVFS_SUBMITURB, urb);
321  urb = 0;
322  }
323  continue;
324  }
325 
329  if (urb) {
330 
342  pthread_mutex_lock(imutex(kb));
343  // EP workaround for FWv3
344  // Corsair input comes through 0x81, but case 1 in keymap.c is used for 6KRO
345  uchar urbendpoint = (kb->fwversion >= 0x300 ? 2 : (urb->endpoint & 0xF));
346  if(IS_MOUSE(vendor, product)){
347  switch(urb->actual_length){
348  case 8:
349  case 10:
350  case 11:
351  // HID mouse input
352  hid_mouse_translate(kb->input.keys, &kb->input.rel_x, &kb->input.rel_y, -urbendpoint, urb->actual_length, urb->buffer, kb->fwversion);
353  break;
354  case MSG_SIZE:
355  // Corsair mouse input
356  corsair_mousecopy(kb->input.keys, -urbendpoint, urb->buffer);
357  break;
358  }
359  } else if(IS_RGB(vendor, product)){
360  switch(urb->actual_length){
361  case 8:
362  // RGB EP 1: 6KRO (BIOS mode) input
363  hid_kb_translate(kb->input.keys, -1, urb->actual_length, urb->buffer);
364  break;
365  case 21:
366  case 5:
367  // RGB EP 2: NKRO (non-BIOS) input. Accept only if keyboard is inactive
368  if(!kb->active)
369  hid_kb_translate(kb->input.keys, -2, urb->actual_length, urb->buffer);
370  break;
371  case MSG_SIZE:
372  // RGB EP 3: Corsair input
373  corsair_kbcopy(kb->input.keys, -urbendpoint, urb->buffer);
374  break;
375  }
376  } else {
377  // Non-RGB input
378  hid_kb_translate(kb->input.keys, urb->endpoint & 0xF, urb->actual_length, urb->buffer);
379  }
382  inputupdate(kb);
383  pthread_mutex_unlock(imutex(kb));
384 
386  ioctl(fd, USBDEVFS_SUBMITURB, urb);
387  urb = 0;
388  }
389  }
390 
394  ckb_info("Stopping input thread for %s%d\n", devpath, index);
395  for(int i = 0; i < urbcount; i++){
396  ioctl(fd, USBDEVFS_DISCARDURB, urbs + i);
397  free(urbs[i].buffer);
398  }
399  return 0;
400 }
401 
419 static int usbunclaim(usbdevice* kb, int resetting) {
420  int handle = kb->handle - 1;
421  int count = kb->epcount;
422  for (int i = 0; i < count; i++) {
423  ioctl(handle, USBDEVFS_RELEASEINTERFACE, &i);
424  }
425  // For RGB keyboards, the kernel driver should only be reconnected to interfaces 0 and 1 (HID), and only if we're not about to do a USB reset.
426  // Reconnecting any of the others causes trouble.
427  if (!resetting) {
428  struct usbdevfs_ioctl ctl = { 0, USBDEVFS_CONNECT, 0 };
429  ioctl(handle, USBDEVFS_IOCTL, &ctl);
430  ctl.ifno = 1;
431  ioctl(handle, USBDEVFS_IOCTL, &ctl);
432  // Also reconnect iface #2 (HID) for non-RGB keyboards
433  if(!HAS_FEATURES(kb, FEAT_RGB)){
434  ctl.ifno = 2;
435  ioctl(handle, USBDEVFS_IOCTL, &ctl);
436  }
437  }
438  return 0;
439 }
440 
449  if(kb->handle){
450  usbunclaim(kb, 0);
451  close(kb->handle - 1);
452  }
453  if(kb->udev)
454  udev_device_unref(kb->udev);
455  kb->handle = 0;
456  kb->udev = 0;
457  kbsyspath[INDEX_OF(kb, keyboard)][0] = 0;
458 }
459 
472 static int usbclaim(usbdevice* kb){
473  int count = kb->epcount;
474 #ifdef DEBUG
475  ckb_info("claiming %d endpoints\n", count);
476 #endif // DEBUG
477 
478  for(int i = 0; i < count; i++){
479  struct usbdevfs_ioctl ctl = { i, USBDEVFS_DISCONNECT, 0 };
480  ioctl(kb->handle - 1, USBDEVFS_IOCTL, &ctl);
481  if(ioctl(kb->handle - 1, USBDEVFS_CLAIMINTERFACE, &i)) {
482  ckb_err("Failed to claim interface %d: %s\n", i, strerror(errno));
483  return -1;
484  }
485  }
486  return 0;
487 }
488 
492 #define TEST_RESET(op) \
493  if(op){ \
494  ckb_err_fn("resetusb failed: %s\n", file, line, strerror(errno)); \
495  if(errno == EINTR || errno == EAGAIN) \
496  return -1; /* try again if status code says so */ \
497  return -2; /* else, remove device */ \
498  }
499 
510 int os_resetusb(usbdevice* kb, const char* file, int line) {
511  TEST_RESET(usbunclaim(kb, 1));
512  TEST_RESET(ioctl(kb->handle - 1, USBDEVFS_RESET));
513  TEST_RESET(usbclaim(kb));
514  // Success!
515  return 0;
516 }
517 
523 void strtrim(char* string){
524  // Find last non-space
525  char* last = string;
526  for(char* c = string; *c != 0; c++){
527  if(!isspace(*c))
528  last = c;
529  }
530  last[1] = 0;
531  // Find first non-space
532  char* first = string;
533  for(; *first != 0; first++){
534  if(!isspace(*first))
535  break;
536  }
537  if(first != string)
538  memmove(string, first, last - first);
539 }
540 
551  struct udev_device* dev = kb->udev;
552  const char* name = udev_device_get_sysattr_value(dev, "product");
553  if(name)
554  strncpy(kb->name, name, KB_NAME_LEN);
555  strtrim(kb->name);
556  const char* serial = udev_device_get_sysattr_value(dev, "serial");
557  if(serial)
558  strncpy(kb->serial, serial, SERIAL_LEN);
559  strtrim(kb->serial);
562  const char* firmware = udev_device_get_sysattr_value(dev, "bcdDevice");
563  if(firmware)
564  sscanf(firmware, "%hx", &kb->fwversion);
565  else
566  kb->fwversion = 0;
567  int index = INDEX_OF(kb, keyboard);
568 
570  ckb_info("Connecting %s at %s%d\n", kb->name, devpath, index);
571 
577  const char* ep_str = udev_device_get_sysattr_value(dev, "bNumInterfaces");
578 #ifdef DEBUG
579  ckb_info("claiming interfaces. name=%s, firmware=%s; ep_str=%s\n", name, firmware, ep_str);
580 #endif //DEBUG
581  kb->epcount = 0;
582  if(ep_str)
583  sscanf(ep_str, "%d", &kb->epcount);
584  if(kb->epcount < 2){
585  // IF we have an RGB KB with 0 or 1 endpoints, it will be in BIOS mode.
586  ckb_err("Unable to read endpoint count from udev, assuming %d and reading >>%s<< or device is in BIOS mode\n", kb->epcount, ep_str);
587  if (usb_tryreset(kb) == 0) {
588  static int retryCount = 0;
589  if (retryCount++ < 5) {
590  return os_setupusb(kb);
591  }
592  }
593  return -1;
594  // ToDo are there special versions we have to detect? If there are, that was the old code to handle it:
595  // This shouldn't happen, but if it does, assume EP count based onckb_warn what the device is supposed to have
596  // kb->epcount = (HAS_FEATURES(kb, FEAT_RGB) ? 4 : 3);
597  // ckb_warn("Unable to read endpoint count from udev, assuming %d and reading >>%s<<...\n", kb->epcount, ep_str);
598  }
599  if(usbclaim(kb)){
600  ckb_err("Failed to claim interfaces: %s\n", strerror(errno));
601  return -1;
602  }
603  return 0;
604 }
605 
606 int usbadd(struct udev_device* dev, short vendor, short product) {
607  const char* path = udev_device_get_devnode(dev);
608  const char* syspath = udev_device_get_syspath(dev);
609  if(!path || !syspath || path[0] == 0 || syspath[0] == 0){
610  ckb_err("Failed to get device path\n");
611  return -1;
612  }
613 #ifdef DEBUG
614  ckb_info(">>>vendor = 0x%x, product = 0x%x, path = %s, syspath = %s\n", vendor, product, path, syspath);
615 #endif // DEDBUG
616  // Find a free USB slot
617  for(int index = 1; index < DEV_MAX; index++){
618  usbdevice* kb = keyboard + index;
619  if(pthread_mutex_trylock(dmutex(kb))){
620  // If the mutex is locked then the device is obviously in use, so keep going
621  if(!strcmp(syspath, kbsyspath[index])){
622  // Make sure this existing keyboard doesn't have the same syspath (this shouldn't happen)
623  return 0;
624  }
625  continue;
626  }
627  if(!IS_CONNECTED(kb)){
628  // Open the sysfs device
629  kb->handle = open(path, O_RDWR) + 1;
630  if(kb->handle <= 0){
631  ckb_err("Failed to open USB device: %s\n", strerror(errno));
632  kb->handle = 0;
633  pthread_mutex_unlock(dmutex(kb));
634  return -1;
635  } else {
636  // Set up device
637  kb->udev = dev;
638  kb->vendor = vendor;
639  kb->product = product;
640  strncpy(kbsyspath[index], syspath, FILENAME_MAX);
641  // Mutex remains locked
642  setupusb(kb);
643  return 0;
644  }
645  }
646  pthread_mutex_unlock(dmutex(kb));
647  }
648  ckb_err("No free devices\n");
649  return -1;
650 }
651 
652 static struct udev* udev;
653 
656 
657 // String -> numeric model map
658 typedef struct {
659  const char* name;
660  short number;
661 } _model;
668 static _model models[] = {
669  // Keyboards
671  { P_K65_STR, P_K65 },
675  { P_K68_STR, P_K68 },
676  { P_K70_STR, P_K70 },
682  { P_K95_STR, P_K95 },
685  { P_STRAFE_STR, P_STRAFE },
688  // Mice
689  { P_M65_STR, P_M65 },
691  { P_GLAIVE_STR, P_GLAIVE },
699 };
700 #define N_MODELS (sizeof(models) / sizeof(_model))
701 
713 static int usb_add_device(struct udev_device* dev){
714  const char* vendor = udev_device_get_sysattr_value(dev, "idVendor");
715  if(vendor && !strcmp(vendor, V_CORSAIR_STR)){
716  const char* product = udev_device_get_sysattr_value(dev, "idProduct");
717  if(product){
718  for(_model* model = models; model < models + N_MODELS; model++){
719  if(!strcmp(product, model->name)){
720  return usbadd(dev, V_CORSAIR, model->number);
721  }
722  }
723  }
724  }
725  return 1;
726 }
727 
738 static void usb_rm_device(struct udev_device* dev){
739  // Device removed. Look for it in our list of keyboards
740  const char* syspath = udev_device_get_syspath(dev);
741  if(!syspath || syspath[0] == 0)
742  return;
743  for(int i = 1; i < DEV_MAX; i++){
744  pthread_mutex_lock(devmutex + i);
745  if(!strcmp(syspath, kbsyspath[i]))
746  closeusb(keyboard + i);
747  pthread_mutex_unlock(devmutex + i);
748  }
749 }
750 
765 static void udev_enum(){
766  struct udev_enumerate* enumerator = udev_enumerate_new(udev);
767  udev_enumerate_add_match_subsystem(enumerator, "usb");
768  udev_enumerate_add_match_sysattr(enumerator, "idVendor", V_CORSAIR_STR);
769  udev_enumerate_scan_devices(enumerator);
770  struct udev_list_entry* devices, *dev_list_entry;
771  devices = udev_enumerate_get_list_entry(enumerator);
772 
773  udev_list_entry_foreach(dev_list_entry, devices){
774  const char* path = udev_list_entry_get_name(dev_list_entry);
775  if(!path)
776  continue;
777  struct udev_device* dev = udev_device_new_from_syspath(udev, path);
778  if(!dev)
779  continue;
780  // If the device matches a recognized device ID, open it
781  if(usb_add_device(dev))
782  // Release device if not
783  udev_device_unref(dev);
784  }
785  udev_enumerate_unref(enumerator);
786 }
787 
793 int usbmain(){
798  // Load the uinput module (if it's not loaded already)
799  if(system("modprobe uinput") != 0)
800  ckb_warn("Failed to load uinput module\n");
801 
805  if(!(udev = udev_new())) {
806  ckb_fatal("Failed to initialize udev in usbmain(), usb_linux.c\n");
807  return -1;
808  }
809 
812  udev_enum();
813 
816  // Done scanning. Enter a loop to poll for device updates
817  struct udev_monitor* monitor = udev_monitor_new_from_netlink(udev, "udev");
818  udev_monitor_filter_add_match_subsystem_devtype(monitor, "usb", 0);
819  udev_monitor_enable_receiving(monitor);
820  // Get an fd for the monitor
821  int fd = udev_monitor_get_fd(monitor);
822  fd_set fds;
823  while(udev){
824  FD_ZERO(&fds);
825  FD_SET(fd, &fds);
826  // Block until an event is read
827  if(select(fd + 1, &fds, 0, 0, 0) > 0 && FD_ISSET(fd, &fds)){
828  struct udev_device* dev = udev_monitor_receive_device(monitor);
829  if(!dev)
830  continue;
831  const char* action = udev_device_get_action(dev);
832  if(!action){
833  udev_device_unref(dev);
834  continue;
835  }
836  // Add/remove device
837  if(!strcmp(action, "add")){
838  int res = usb_add_device(dev);
839  if(res == 0)
840  continue;
841  // If the device matched but the handle wasn't opened correctly, re-enumerate (this sometimes solves the problem)
842  if(res == -1)
843  udev_enum();
844  } else if(!strcmp(action, "remove"))
845  usb_rm_device(dev);
846  udev_device_unref(dev);
847  }
848  }
849  udev_monitor_unref(monitor);
850  return 0;
851 }
852 
853 void usbkill(){
854  udev_unref(udev);
855  udev = 0;
856 }
857 
858 #endif
static char kbsyspath[9][FILENAME_MAX]
Definition: usb_linux.c:13
#define P_K70_RFIRE_NRGB
Definition: usb.h:73
#define KB_NAME_LEN
Definition: structures.h:174
#define P_STRAFE_NRGB_STR
Definition: usb.h:88
#define MSG_SIZE
Definition: structures.h:176
#define P_GLAIVE
Definition: usb.h:119
void setupusb(usbdevice *kb)
Definition: usb.c:396
#define P_M65_STR
Definition: usb.h:94
#define P_K95_PLATINUM
Definition: usb.h:81
int usb_tryreset(usbdevice *kb)
Definition: usb.c:475
#define P_M65_PRO_STR
Definition: usb.h:96
#define P_K65_LUX
Definition: usb.h:53
char name[40+1]
Definition: structures.h:233
#define P_K95
Definition: usb.h:77
#define TEST_RESET(op)
TEST_RESET doesa "try / catch" for resetting the usb interface.
Definition: usb_linux.c:492
#define IS_CONNECTED(kb)
Definition: device.h:12
#define P_K70_NRGB_STR
Definition: usb.h:66
usbinput input
Definition: structures.h:245
#define P_STRAFE_NRGB_2
Definition: usb.h:89
#define P_SABRE_N
Definition: usb.h:103
#define P_SABRE_O
Definition: usb.h:99
#define P_K63_NRGB_STR
Definition: usb.h:46
#define P_K95_NRGB_STR
Definition: usb.h:80
#define P_K65
Definition: usb.h:49
#define ckb_err(fmt, args...)
Definition: includes.h:49
#define IS_RGB(vendor, product)
RGB vs non-RGB test (note: non-RGB Strafe is still considered "RGB" in that it shares the same protoc...
Definition: usb.h:146
#define P_K70_NRGB
Definition: usb.h:65
ushort fwversion
Definition: structures.h:239
#define FEAT_RGB
Definition: structures.h:136
usbdevice keyboard[9]
remember all usb devices. Needed for closeusb().
Definition: device.c:10
void os_sendindicators(usbdevice *kb)
Definition: usb_linux.c:214
static int usbunclaim(usbdevice *kb, int resetting)
Definition: usb_linux.c:419
struct udev_device * udev
Definition: structures.h:186
static int usbclaim(usbdevice *kb)
Definition: usb_linux.c:472
int usbadd(struct udev_device *dev, short vendor, short product)
Definition: usb_linux.c:606
pthread_mutex_t devmutex[9]
Mutex for handling the usbdevice structure.
Definition: device.c:12
#define P_K95_STR
Definition: usb.h:78
void * os_inputmain(void *context)
os_inputmain This function is run in a separate thread and will be detached from the main thread...
Definition: usb_linux.c:248
#define P_K70_STR
Definition: usb.h:64
#define P_K63_NRGB
Definition: usb.h:45
#define P_M65
Definition: usb.h:93
uchar ileds
Definition: structures.h:247
int os_usbsend(usbdevice *kb, const uchar *out_msg, int is_recv, const char *file, int line)
os_usbsend sends a data packet (MSG_SIZE = 64) Bytes long
Definition: usb_linux.c:68
char active
Definition: structures.h:231
#define P_STRAFE
Definition: usb.h:85
#define P_SABRE_L
Definition: usb.h:101
int epcount
Definition: structures.h:215
#define P_K95_PLATINUM_STR
Definition: usb.h:82
int os_resetusb(usbdevice *kb, const char *file, int line)
Definition: usb_linux.c:510
#define P_HARPOON
Definition: usb.h:115
void inputupdate(usbdevice *kb)
Definition: input.c:241
void usbkill()
Stop the USB system.
Definition: usb_linux.c:853
#define N_MODELS
Definition: usb_linux.c:700
#define ckb_fatal(fmt, args...)
Definition: includes.h:46
#define IS_MOUSE(vendor, product)
Mouse vs keyboard test.
Definition: usb.h:163
#define P_SABRE_L_STR
Definition: usb.h:102
unsigned char uchar
Definition: includes.h:24
QString devpath
Definition: kbmanager.cpp:4
#define P_K68
Definition: usb.h:59
#define P_SCIMITAR_STR
Definition: usb.h:110
#define P_SABRE_O2_STR
Definition: usb.h:106
short rel_x
Definition: structures.h:132
static void usb_rm_device(struct udev_device *dev)
usb_rm_device find the usb port to remove and close it via closeusb().
Definition: usb_linux.c:738
#define ckb_warn_fn(fmt, file, line, args...)
Definition: includes.h:51
short number
Definition: usb_linux.c:660
#define P_M65_PRO
Definition: usb.h:95
#define P_K70_RFIRE
Definition: usb.h:71
#define ckb_warn(fmt, args...)
Definition: includes.h:52
void corsair_mousecopy(unsigned char *kbinput, int endpoint, const unsigned char *urbinput)
Definition: keymap.c:429
#define P_K65_RFIRE_STR
Definition: usb.h:56
void os_closeusb(usbdevice *kb)
Definition: usb_linux.c:448
void hid_mouse_translate(unsigned char *kbinput, short *xaxis, short *yaxis, int endpoint, int length, const unsigned char *urbinput, ushort fwversion)
Definition: keymap.c:391
#define ckb_info(fmt, args...)
Definition: includes.h:55
#define P_K65_NRGB
Definition: usb.h:51
#define P_SCIMITAR_PRO
Definition: usb.h:111
#define P_K68_STR
Definition: usb.h:60
short product
Definition: structures.h:237
const char * name
Definition: usb_linux.c:659
#define P_K70_RFIRE_STR
Definition: usb.h:72
#define INDEX_OF(entry, array)
Definition: includes.h:27
#define P_K70_RFIRE_NRGB_STR
Definition: usb.h:74
#define P_K70
Definition: usb.h:63
short rel_y
Definition: structures.h:132
static _model models[]
Definition: usb_linux.c:668
int os_usbrecv(usbdevice *kb, uchar *in_msg, const char *file, int line)
os_usbrecv receives a max MSGSIZE long buffer from usb device
Definition: usb_linux.c:130
int usbmain()
Definition: usb_linux.c:793
unsigned short ushort
Definition: includes.h:25
void strtrim(char *string)
Definition: usb_linux.c:523
#define P_K95_NRGB
Definition: usb.h:79
#define V_CORSAIR_STR
Definition: usb.h:43
#define P_SABRE_O2
Definition: usb.h:105
#define P_STRAFE_NRGB_2_STR
Definition: usb.h:90
pthread_t udevthread
Definition: usb_linux.c:655
int closeusb(usbdevice *kb)
Definition: usb.c:687
char serial[34]
Definition: structures.h:235
#define imutex(kb)
Definition: device.h:22
void hid_kb_translate(unsigned char *kbinput, int endpoint, int length, const unsigned char *urbinput)
Definition: keymap.c:246
#define P_K65_LUX_STR
Definition: usb.h:54
#define P_STRAFE_NRGB
Definition: usb.h:87
int handle
Definition: structures.h:187
#define HAS_FEATURES(kb, feat)
Definition: structures.h:157
#define P_K70_LUX_STR
Definition: usb.h:68
static void udev_enum()
udev_enum use the udev_enumerate_add_match_subsystem() to get all you need but only that...
Definition: usb_linux.c:765
static int usb_add_device(struct udev_device *dev)
Add a udev device. Returns 0 if device was recognized/added.
Definition: usb_linux.c:713
Definitions for using USB interface.
#define P_GLAIVE_STR
Definition: usb.h:120
static struct udev * udev
struct udef is defined in /usr/include/libudev.h
Definition: usb_linux.c:652
#define P_K65_STR
Definition: usb.h:50
#define P_K70_LUX
Definition: usb.h:67
int os_setupusb(usbdevice *kb)
Definition: usb_linux.c:548
void corsair_kbcopy(unsigned char *kbinput, int endpoint, const unsigned char *urbinput)
Definition: keymap.c:420
#define V_CORSAIR
For the following Defines please see "Detailed Description".
Definition: usb.h:42
#define P_HARPOON_STR
Definition: usb.h:116
#define P_SABRE_O_STR
Definition: usb.h:100
#define P_K70_LUX_NRGB
Definition: usb.h:69
#define DEV_MAX
Definition: device.h:8
#define P_SCIMITAR
Definition: usb.h:109
uchar keys[((((152+22+12)+25)+7)/8)]
Definition: structures.h:130
#define dmutex(kb)
Definition: device.h:18
pthread_t usbthread
Definition: usb_linux.c:655
#define P_K65_NRGB_STR
Definition: usb.h:52
short vendor
Definition: structures.h:237
#define ckb_err_fn(fmt, file, line, args...)
Definition: includes.h:48
#define IS_V2_OVERRIDE(kb)
Used when a device has a firmware with a low version number that uses the new protocol.
Definition: usb.h:172
#define P_STRAFE_STR
Definition: usb.h:86
#define P_SCIMITAR_PRO_STR
Definition: usb.h:112
#define SERIAL_LEN
Definition: structures.h:175
#define P_K65_RFIRE
Definition: usb.h:55
int _nk95cmd(usbdevice *kb, uchar bRequest, ushort wValue, const char *file, int line)
_nk95cmd If we control a non RGB keyboard, set the keyboard via ioctl with usbdevfs_ctrltransfer ...
Definition: usb_linux.c:189
#define P_SABRE_N_STR
Definition: usb.h:104
#define P_K70_LUX_NRGB_STR
Definition: usb.h:70