ckb-next  beta-v0.2.8 at branch testing
ckb-next driver for corsair devices
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator 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_recv) {
71  struct usbdevfs_bulktransfer transfer = {0};
72  transfer.ep = (kb->fwversion >= 0x130 && kb->fwversion < 0x200) ? 4 : 3;
73  transfer.len = MSG_SIZE;
74  transfer.timeout = 5000;
75  transfer.data = (void*)out_msg;
76  res = ioctl(kb->handle - 1, USBDEVFS_BULK, &transfer);
77  } else {
78  struct usbdevfs_ctrltransfer transfer = { 0x21, 0x09, 0x0200, kb->epcount - 1, MSG_SIZE, 5000, (void*)out_msg };
79  res = ioctl(kb->handle - 1, USBDEVFS_CONTROL, &transfer);
80  }
81 
82  if (res <= 0){
83  ckb_err_fn(" %s, res = 0x%x\n", file, line, res ? strerror(errno) : "No data written", res);
84  if(res == -1 && errno == ETIMEDOUT)
85  return -1;
86  else
87  return 0;
88  } else if (res != MSG_SIZE)
89  ckb_warn_fn("Wrote %d bytes (expected %d)\n", file, line, res, MSG_SIZE);
90 #ifdef DEBUG_USB
91  char converted[MSG_SIZE*3 + 1];
92  for(int i=0;i<MSG_SIZE;i++)
93  sprintf(&converted[i*3], "%02x ", out_msg[i]);
94  ckb_warn_fn("Sent %s\n", file, line, converted);
95 #endif
96  return res;
97 }
98 
101 
129 int os_usbrecv(usbdevice* kb, uchar* in_msg, const char* file, int line){
130  int res;
131  // This is what CUE does, but it doesn't seem to work on linux.
132  /*if(kb->fwversion >= 0x130){
133  struct usbdevfs_bulktransfer transfer = {0};
134  transfer.ep = 0x84;
135  transfer.len = MSG_SIZE;
136  transfer.timeout = 5000;
137  transfer.data = in_msg;
138  res = ioctl(kb->handle - 1, USBDEVFS_BULK, &transfer);
139  } else {*/
140  struct usbdevfs_ctrltransfer transfer = { 0xa1, 0x01, 0x0300, kb->epcount - 1, MSG_SIZE, 5000, in_msg };
141  res = ioctl(kb->handle - 1, USBDEVFS_CONTROL, &transfer);
142  //}
143  if(res <= 0){
144  ckb_err_fn("%s\n", file, line, res ? strerror(errno) : "No data read");
145  if(res == -1 && errno == ETIMEDOUT)
146  return -1;
147  else
148  return 0;
149  } else if(res != MSG_SIZE)
150  ckb_warn_fn("Read %d bytes (expected %d)\n", file, line, res, MSG_SIZE);
151 #ifdef DEBUG_USB_RECV
152  char converted[MSG_SIZE*3 + 1];
153  for(int i=0;i<MSG_SIZE;i++)
154  sprintf(&converted[i*3], "%02x ", in_msg[i]);
155  ckb_warn_fn("Recv %s\n", file, line, converted);
156 #endif
157  return res;
158 }
159 
188 int _nk95cmd(usbdevice* kb, uchar bRequest, ushort wValue, const char* file, int line){
189  if(kb->product != P_K95_NRGB)
190  return 0;
191  struct usbdevfs_ctrltransfer transfer = { 0x40, bRequest, wValue, 0, 0, 5000, 0 };
192  int res = ioctl(kb->handle - 1, USBDEVFS_CONTROL, &transfer);
193  if(res <= 0){
194  ckb_err_fn("%s\n", file, line, res ? strerror(errno) : "No data written");
195  return 1;
196  }
197  return 0;
198 }
199 
214  static int countForReset = 0;
215  struct usbdevfs_ctrltransfer transfer = { 0x21, 0x09, 0x0200, 0x00, 1, 500, &kb->ileds };
216  int res = ioctl(kb->handle - 1, USBDEVFS_CONTROL, &transfer);
217  if(res <= 0) {
218  ckb_err("%s\n", res ? strerror(errno) : "No data written");
219  if (usb_tryreset(kb) == 0 && countForReset++ < 3) {
220  os_sendindicators(kb);
221  }
222  }
223 }
224 
237 
238 void* os_inputmain(void* context){
239  usbdevice* kb = context;
240  int fd = kb->handle - 1;
241  short vendor = kb->vendor, product = kb->product;
242  int index = INDEX_OF(kb, keyboard);
243  ckb_info("Starting input thread for %s%d\n", devpath, index);
244 
249  int urbcount = IS_RGB(vendor, product) ? (kb->epcount - 1) : kb->epcount;
250  if (urbcount == 0) {
251  ckb_err("urbcount = 0, so there is nothing to claim in os_inputmain()\n");
252  return 0;
253  }
254 
256  struct usbdevfs_urb urbs[urbcount + 1];
257  memset(urbs, 0, sizeof(urbs));
258 
272  urbs[0].buffer_length = 8;
273  if(urbcount > 1 && IS_RGB(vendor, product)) {
274  if(IS_MOUSE(vendor, product))
275  urbs[1].buffer_length = 10;
276  else
277  urbs[1].buffer_length = 21;
278  urbs[2].buffer_length = MSG_SIZE;
279  if(urbcount != 3)
280  urbs[urbcount - 1].buffer_length = MSG_SIZE;
281  } else {
282  urbs[1].buffer_length = 4;
283  urbs[2].buffer_length = 15;
284  }
285 
288  for(int i = 0; i < urbcount; i++){
289  urbs[i].type = USBDEVFS_URB_TYPE_INTERRUPT;
290  urbs[i].endpoint = 0x80 | (i + 1);
291  urbs[i].buffer = malloc(urbs[i].buffer_length);
292  ioctl(fd, USBDEVFS_SUBMITURB, urbs + i);
293  }
294 
296  while (1) {
297  struct usbdevfs_urb* urb = 0;
298 
301  if (ioctl(fd, USBDEVFS_REAPURB, &urb)) {
302  if (errno == ENODEV || errno == ENOENT || errno == ESHUTDOWN)
303  // Stop the thread if the handle closes
304  break;
305  else if(errno == EPIPE && urb){
307  ioctl(fd, USBDEVFS_CLEAR_HALT, &urb->endpoint);
308  // Re-submit the URB
309  if(urb)
310  ioctl(fd, USBDEVFS_SUBMITURB, urb);
311  urb = 0;
312  }
313  continue;
314  }
315 
319  if (urb) {
320 
332  pthread_mutex_lock(imutex(kb));
333  if(IS_MOUSE(vendor, product)){
334  switch(urb->actual_length){
335  case 8:
336  case 10:
337  case 11:
338  // HID mouse input
339  hid_mouse_translate(kb->input.keys, &kb->input.rel_x, &kb->input.rel_y, -(urb->endpoint & 0xF), urb->actual_length, urb->buffer);
340  break;
341  case MSG_SIZE:
342  // Corsair mouse input
343  corsair_mousecopy(kb->input.keys, -(urb->endpoint & 0xF), urb->buffer);
344  break;
345  }
346  } else if(IS_RGB(vendor, product)){
347  switch(urb->actual_length){
348  case 8:
349  // RGB EP 1: 6KRO (BIOS mode) input
350  hid_kb_translate(kb->input.keys, -1, urb->actual_length, urb->buffer);
351  break;
352  case 21:
353  case 5:
354  // RGB EP 2: NKRO (non-BIOS) input. Accept only if keyboard is inactive
355  if(!kb->active)
356  hid_kb_translate(kb->input.keys, -2, urb->actual_length, urb->buffer);
357  break;
358  case MSG_SIZE:
359  // RGB EP 3: Corsair input
360  corsair_kbcopy(kb->input.keys, -(urb->endpoint & 0xF), urb->buffer);
361  break;
362  }
363  } else {
364  // Non-RGB input
365  hid_kb_translate(kb->input.keys, urb->endpoint & 0xF, urb->actual_length, urb->buffer);
366  }
369  inputupdate(kb);
370  pthread_mutex_unlock(imutex(kb));
371 
373  ioctl(fd, USBDEVFS_SUBMITURB, urb);
374  urb = 0;
375  }
376  }
377 
381  ckb_info("Stopping input thread for %s%d\n", devpath, index);
382  for(int i = 0; i < urbcount; i++){
383  ioctl(fd, USBDEVFS_DISCARDURB, urbs + i);
384  free(urbs[i].buffer);
385  }
386  return 0;
387 }
388 
406 static int usbunclaim(usbdevice* kb, int resetting) {
407  int handle = kb->handle - 1;
408  int count = kb->epcount;
409  for (int i = 0; i < count; i++) {
410  ioctl(handle, USBDEVFS_RELEASEINTERFACE, &i);
411  }
412  // 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.
413  // Reconnecting any of the others causes trouble.
414  if (!resetting) {
415  struct usbdevfs_ioctl ctl = { 0, USBDEVFS_CONNECT, 0 };
416  ioctl(handle, USBDEVFS_IOCTL, &ctl);
417  ctl.ifno = 1;
418  ioctl(handle, USBDEVFS_IOCTL, &ctl);
419  // Also reconnect iface #2 (HID) for non-RGB keyboards
420  if(!HAS_FEATURES(kb, FEAT_RGB)){
421  ctl.ifno = 2;
422  ioctl(handle, USBDEVFS_IOCTL, &ctl);
423  }
424  }
425  return 0;
426 }
427 
436  if(kb->handle){
437  usbunclaim(kb, 0);
438  close(kb->handle - 1);
439  }
440  if(kb->udev)
441  udev_device_unref(kb->udev);
442  kb->handle = 0;
443  kb->udev = 0;
444  kbsyspath[INDEX_OF(kb, keyboard)][0] = 0;
445 }
446 
459 static int usbclaim(usbdevice* kb){
460  int count = kb->epcount;
461 #ifdef DEBUG
462  ckb_info("claiming %d endpoints\n", count);
463 #endif // DEBUG
464 
465  for(int i = 0; i < count; i++){
466  struct usbdevfs_ioctl ctl = { i, USBDEVFS_DISCONNECT, 0 };
467  ioctl(kb->handle - 1, USBDEVFS_IOCTL, &ctl);
468  if(ioctl(kb->handle - 1, USBDEVFS_CLAIMINTERFACE, &i)) {
469  ckb_err("Failed to claim interface %d: %s\n", i, strerror(errno));
470  return -1;
471  }
472  }
473  return 0;
474 }
475 
479 #define TEST_RESET(op) \
480  if(op){ \
481  ckb_err_fn("resetusb failed: %s\n", file, line, strerror(errno)); \
482  if(errno == EINTR || errno == EAGAIN) \
483  return -1; /* try again if status code says so */ \
484  return -2; /* else, remove device */ \
485  }
486 
497 int os_resetusb(usbdevice* kb, const char* file, int line) {
498  TEST_RESET(usbunclaim(kb, 1));
499  TEST_RESET(ioctl(kb->handle - 1, USBDEVFS_RESET));
500  TEST_RESET(usbclaim(kb));
501  // Success!
502  return 0;
503 }
504 
510 void strtrim(char* string){
511  // Find last non-space
512  char* last = string;
513  for(char* c = string; *c != 0; c++){
514  if(!isspace(*c))
515  last = c;
516  }
517  last[1] = 0;
518  // Find first non-space
519  char* first = string;
520  for(; *first != 0; first++){
521  if(!isspace(*first))
522  break;
523  }
524  if(first != string)
525  memmove(string, first, last - first);
526 }
527 
538  struct udev_device* dev = kb->udev;
539  const char* name = udev_device_get_sysattr_value(dev, "product");
540  if(name)
541  strncpy(kb->name, name, KB_NAME_LEN);
542  strtrim(kb->name);
543  const char* serial = udev_device_get_sysattr_value(dev, "serial");
544  if(serial)
545  strncpy(kb->serial, serial, SERIAL_LEN);
546  strtrim(kb->serial);
549  const char* firmware = udev_device_get_sysattr_value(dev, "bcdDevice");
550  if(firmware)
551  sscanf(firmware, "%hx", &kb->fwversion);
552  else
553  kb->fwversion = 0;
554  int index = INDEX_OF(kb, keyboard);
555 
557  ckb_info("Connecting %s at %s%d\n", kb->name, devpath, index);
558 
564  const char* ep_str = udev_device_get_sysattr_value(dev, "bNumInterfaces");
565 #ifdef DEBUG
566  ckb_info("claiming interfaces. name=%s, firmware=%s; Got >>%s<< as ep_str\n", name, firmware, ep_str);
567 #endif //DEBUG
568  kb->epcount = 0;
569  if(ep_str)
570  sscanf(ep_str, "%d", &kb->epcount);
571  if(kb->epcount < 2){
572  // IF we have an RGB KB with 0 or 1 endpoints, it will be in BIOS mode.
573  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);
574  if (usb_tryreset(kb) == 0) {
575  static int retryCount = 0;
576  if (retryCount++ < 5) {
577  return os_setupusb(kb);
578  }
579  }
580  return -1;
581  // ToDo are there special versions we have to detect? If there are, that was the old code to handle it:
582  // This shouldn't happen, but if it does, assume EP count based onckb_warn what the device is supposed to have
583  // kb->epcount = (HAS_FEATURES(kb, FEAT_RGB) ? 4 : 3);
584  // ckb_warn("Unable to read endpoint count from udev, assuming %d and reading >>%s<<...\n", kb->epcount, ep_str);
585  }
586  if(usbclaim(kb)){
587  ckb_err("Failed to claim interfaces: %s\n", strerror(errno));
588  return -1;
589  }
590  return 0;
591 }
592 
593 int usbadd(struct udev_device* dev, short vendor, short product) {
594  const char* path = udev_device_get_devnode(dev);
595  const char* syspath = udev_device_get_syspath(dev);
596  if(!path || !syspath || path[0] == 0 || syspath[0] == 0){
597  ckb_err("Failed to get device path\n");
598  return -1;
599  }
600 #ifdef DEBUG
601  ckb_info(">>>vendor = 0x%x, product = 0x%x, path = %s, syspath = %s\n", vendor, product, path, syspath);
602 #endif // DEDBUG
603  // Find a free USB slot
604  for(int index = 1; index < DEV_MAX; index++){
605  usbdevice* kb = keyboard + index;
606  if(pthread_mutex_trylock(dmutex(kb))){
607  // If the mutex is locked then the device is obviously in use, so keep going
608  if(!strcmp(syspath, kbsyspath[index])){
609  // Make sure this existing keyboard doesn't have the same syspath (this shouldn't happen)
610  return 0;
611  }
612  continue;
613  }
614  if(!IS_CONNECTED(kb)){
615  // Open the sysfs device
616  kb->handle = open(path, O_RDWR) + 1;
617  if(kb->handle <= 0){
618  ckb_err("Failed to open USB device: %s\n", strerror(errno));
619  kb->handle = 0;
620  pthread_mutex_unlock(dmutex(kb));
621  return -1;
622  } else {
623  // Set up device
624  kb->udev = dev;
625  kb->vendor = vendor;
626  kb->product = product;
627  strncpy(kbsyspath[index], syspath, FILENAME_MAX);
628  // Mutex remains locked
629  setupusb(kb);
630  return 0;
631  }
632  }
633  pthread_mutex_unlock(dmutex(kb));
634  }
635  ckb_err("No free devices\n");
636  return -1;
637 }
638 
639 static struct udev* udev;
640 
643 
644 // String -> numeric model map
645 typedef struct {
646  const char* name;
647  short number;
648 } _model;
655 static _model models[] = {
656  // Keyboards
657  { P_K65_STR, P_K65 },
661  { P_K70_STR, P_K70 },
667  { P_K95_STR, P_K95 },
670  { P_STRAFE_STR, P_STRAFE },
672  // Mice
673  { P_M65_STR, P_M65 },
681 };
682 #define N_MODELS (sizeof(models) / sizeof(_model))
683 
695 static int usb_add_device(struct udev_device* dev){
696  const char* vendor = udev_device_get_sysattr_value(dev, "idVendor");
697  if(vendor && !strcmp(vendor, V_CORSAIR_STR)){
698  const char* product = udev_device_get_sysattr_value(dev, "idProduct");
699  if(product){
700  for(_model* model = models; model < models + N_MODELS; model++){
701  if(!strcmp(product, model->name)){
702  return usbadd(dev, V_CORSAIR, model->number);
703  }
704  }
705  }
706  }
707  return 1;
708 }
709 
720 static void usb_rm_device(struct udev_device* dev){
721  // Device removed. Look for it in our list of keyboards
722  const char* syspath = udev_device_get_syspath(dev);
723  if(!syspath || syspath[0] == 0)
724  return;
725  for(int i = 1; i < DEV_MAX; i++){
726  pthread_mutex_lock(devmutex + i);
727  if(!strcmp(syspath, kbsyspath[i]))
728  closeusb(keyboard + i);
729  pthread_mutex_unlock(devmutex + i);
730  }
731 }
732 
747 static void udev_enum(){
748  struct udev_enumerate* enumerator = udev_enumerate_new(udev);
749  udev_enumerate_add_match_subsystem(enumerator, "usb");
750  udev_enumerate_add_match_sysattr(enumerator, "idVendor", V_CORSAIR_STR);
751  udev_enumerate_scan_devices(enumerator);
752  struct udev_list_entry* devices, *dev_list_entry;
753  devices = udev_enumerate_get_list_entry(enumerator);
754 
755  udev_list_entry_foreach(dev_list_entry, devices){
756  const char* path = udev_list_entry_get_name(dev_list_entry);
757  if(!path)
758  continue;
759  struct udev_device* dev = udev_device_new_from_syspath(udev, path);
760  if(!dev)
761  continue;
762  // If the device matches a recognized device ID, open it
763  if(usb_add_device(dev))
764  // Release device if not
765  udev_device_unref(dev);
766  }
767  udev_enumerate_unref(enumerator);
768 }
769 
775 int usbmain(){
780  // Load the uinput module (if it's not loaded already)
781  if(system("modprobe uinput") != 0)
782  ckb_warn("Failed to load uinput module\n");
783 
787  if(!(udev = udev_new())) {
788  ckb_fatal("Failed to initialize udev in usbmain(), usb_linux.c\n");
789  return -1;
790  }
791 
794  udev_enum();
795 
798  // Done scanning. Enter a loop to poll for device updates
799  struct udev_monitor* monitor = udev_monitor_new_from_netlink(udev, "udev");
800  udev_monitor_filter_add_match_subsystem_devtype(monitor, "usb", 0);
801  udev_monitor_enable_receiving(monitor);
802  // Get an fd for the monitor
803  int fd = udev_monitor_get_fd(monitor);
804  fd_set fds;
805  while(udev){
806  FD_ZERO(&fds);
807  FD_SET(fd, &fds);
808  // Block until an event is read
809  if(select(fd + 1, &fds, 0, 0, 0) > 0 && FD_ISSET(fd, &fds)){
810  struct udev_device* dev = udev_monitor_receive_device(monitor);
811  if(!dev)
812  continue;
813  const char* action = udev_device_get_action(dev);
814  if(!action){
815  udev_device_unref(dev);
816  continue;
817  }
818  // Add/remove device
819  if(!strcmp(action, "add")){
820  int res = usb_add_device(dev);
821  if(res == 0)
822  continue;
823  // If the device matched but the handle wasn't opened correctly, re-enumerate (this sometimes solves the problem)
824  if(res == -1)
825  udev_enum();
826  } else if(!strcmp(action, "remove"))
827  usb_rm_device(dev);
828  udev_device_unref(dev);
829  }
830  }
831  udev_monitor_unref(monitor);
832  return 0;
833 }
834 
835 void usbkill(){
836  udev_unref(udev);
837  udev = 0;
838 }
839 
840 #endif
static char kbsyspath[9][FILENAME_MAX]
Definition: usb_linux.c:13
#define P_K70_RFIRE_NRGB
Definition: usb.h:61
#define KB_NAME_LEN
Definition: structures.h:174
#define P_STRAFE_NRGB_STR
Definition: usb.h:76
#define MSG_SIZE
Definition: structures.h:176
void setupusb(usbdevice *kb)
Definition: usb.c:386
#define P_M65_STR
Definition: usb.h:80
#define P_K95_PLATINUM
Definition: usb.h:69
int usb_tryreset(usbdevice *kb)
Definition: usb.c:465
#define P_M65_PRO_STR
Definition: usb.h:82
#define P_K65_LUX
Definition: usb.h:45
char name[40+1]
Definition: structures.h:233
#define P_K95
Definition: usb.h:65
#define TEST_RESET(op)
TEST_RESET doesa "try / catch" for resetting the usb interface.
Definition: usb_linux.c:479
#define IS_CONNECTED(kb)
Definition: device.h:12
#define P_K70_NRGB_STR
Definition: usb.h:54
usbinput input
Definition: structures.h:245
#define P_SABRE_N
Definition: usb.h:89
#define P_SABRE_O
Definition: usb.h:85
#define P_K95_NRGB_STR
Definition: usb.h:68
#define P_K65
Definition: usb.h:41
#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:124
#define P_K70_NRGB
Definition: usb.h:53
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
uchar keys[((((152+3+12)+25)+7)/8)]
Definition: structures.h:130
void os_sendindicators(usbdevice *kb)
Definition: usb_linux.c:213
static int usbunclaim(usbdevice *kb, int resetting)
Definition: usb_linux.c:406
struct udev_device * udev
Definition: structures.h:186
static int usbclaim(usbdevice *kb)
Definition: usb_linux.c:459
int usbadd(struct udev_device *dev, short vendor, short product)
Definition: usb_linux.c:593
pthread_mutex_t devmutex[9]
Mutex for handling the usbdevice structure.
Definition: device.c:12
#define P_K95_STR
Definition: usb.h:66
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:238
#define P_K70_STR
Definition: usb.h:52
#define P_M65
Definition: usb.h:79
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:73
#define P_SABRE_L
Definition: usb.h:87
int epcount
Definition: structures.h:215
#define P_K95_PLATINUM_STR
Definition: usb.h:70
int os_resetusb(usbdevice *kb, const char *file, int line)
Definition: usb_linux.c:497
void inputupdate(usbdevice *kb)
Definition: input.c:241
void usbkill()
Stop the USB system.
Definition: usb_linux.c:835
#define N_MODELS
Definition: usb_linux.c:682
#define ckb_fatal(fmt, args...)
Definition: includes.h:46
#define IS_MOUSE(vendor, product)
Mouse vs keyboard test.
Definition: usb.h:141
#define P_SABRE_L_STR
Definition: usb.h:88
unsigned char uchar
Definition: includes.h:24
#define P_SCIMITAR_STR
Definition: usb.h:96
#define P_SABRE_O2_STR
Definition: usb.h:92
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:720
#define ckb_warn_fn(fmt, file, line, args...)
Definition: includes.h:51
short number
Definition: usb_linux.c:647
void hid_mouse_translate(unsigned char *kbinput, short *xaxis, short *yaxis, int endpoint, int length, const unsigned char *urbinput)
Definition: keymap.c:366
#define P_M65_PRO
Definition: usb.h:81
#define P_K70_RFIRE
Definition: usb.h:59
#define ckb_warn(fmt, args...)
Definition: includes.h:52
void corsair_mousecopy(unsigned char *kbinput, int endpoint, const unsigned char *urbinput)
Definition: keymap.c:403
#define P_K65_RFIRE_STR
Definition: usb.h:48
void os_closeusb(usbdevice *kb)
Definition: usb_linux.c:435
const char *const devpath
Definition: devnode.c:11
#define ckb_info(fmt, args...)
Definition: includes.h:55
#define P_K65_NRGB
Definition: usb.h:43
#define P_SCIMITAR_PRO
Definition: usb.h:97
short product
Definition: structures.h:237
const char * name
Definition: usb_linux.c:646
#define P_K70_RFIRE_STR
Definition: usb.h:60
#define INDEX_OF(entry, array)
Definition: includes.h:27
#define P_K70_RFIRE_NRGB_STR
Definition: usb.h:62
#define P_K70
Definition: usb.h:51
short rel_y
Definition: structures.h:132
static _model models[]
Definition: usb_linux.c:655
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:129
int usbmain()
Definition: usb_linux.c:775
unsigned short ushort
Definition: includes.h:25
void strtrim(char *string)
Definition: usb_linux.c:510
#define P_K95_NRGB
Definition: usb.h:67
#define V_CORSAIR_STR
Definition: usb.h:39
#define P_SABRE_O2
Definition: usb.h:91
pthread_t udevthread
Definition: usb_linux.c:642
int closeusb(usbdevice *kb)
Definition: usb.c:677
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:223
#define P_K65_LUX_STR
Definition: usb.h:46
#define P_STRAFE_NRGB
Definition: usb.h:75
int handle
Definition: structures.h:187
#define HAS_FEATURES(kb, feat)
Definition: structures.h:157
#define P_K70_LUX_STR
Definition: usb.h:56
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:747
static int usb_add_device(struct udev_device *dev)
Add a udev device. Returns 0 if device was recognized/added.
Definition: usb_linux.c:695
Definitions for using USB interface.
static struct udev * udev
struct udef is defined in /usr/include/libudev.h
Definition: usb_linux.c:639
#define P_K65_STR
Definition: usb.h:42
#define P_K70_LUX
Definition: usb.h:55
int os_setupusb(usbdevice *kb)
Definition: usb_linux.c:535
void corsair_kbcopy(unsigned char *kbinput, int endpoint, const unsigned char *urbinput)
Definition: keymap.c:394
#define V_CORSAIR
For the following Defines please see "Detailed Description".
Definition: usb.h:38
#define P_SABRE_O_STR
Definition: usb.h:86
#define P_K70_LUX_NRGB
Definition: usb.h:57
#define DEV_MAX
Definition: device.h:8
#define P_SCIMITAR
Definition: usb.h:95
#define dmutex(kb)
Definition: device.h:18
pthread_t usbthread
Definition: usb_linux.c:642
#define P_K65_NRGB_STR
Definition: usb.h:44
short vendor
Definition: structures.h:237
#define ckb_err_fn(fmt, file, line, args...)
Definition: includes.h:48
#define P_STRAFE_STR
Definition: usb.h:74
#define P_SCIMITAR_PRO_STR
Definition: usb.h:98
#define SERIAL_LEN
Definition: structures.h:175
#define P_K65_RFIRE
Definition: usb.h:47
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:188
#define P_SABRE_N_STR
Definition: usb.h:90
#define P_K70_LUX_NRGB_STR
Definition: usb.h:58