ckb-next
v0.2.8 at branch master
ckb-next driver for corsair devices
|
Definitions for using USB interface. More...
Go to the source code of this file.
Macros | |
#define | V_CORSAIR 0x1b1c |
For the following Defines please see "Detailed Description". More... | |
#define | V_CORSAIR_STR "1b1c" |
#define | P_K63_NRGB 0x1b40 |
#define | P_K63_NRGB_STR "1b40" |
#define | IS_K63(kb) ((kb)->vendor == V_CORSAIR && (kb)->product == P_K63_NRGB) |
#define | P_K65 0x1b17 |
#define | P_K65_STR "1b17" |
#define | P_K65_NRGB 0x1b07 |
#define | P_K65_NRGB_STR "1b07" |
#define | P_K65_LUX 0x1b37 |
#define | P_K65_LUX_STR "1b37" |
#define | P_K65_RFIRE 0x1b39 |
#define | P_K65_RFIRE_STR "1b39" |
#define | IS_K65(kb) ((kb)->vendor == V_CORSAIR && ((kb)->product == P_K65 || (kb)->product == P_K65_NRGB || (kb)->product == P_K65_LUX || (kb)->product == P_K65_RFIRE)) |
#define | P_K68 0x1b3f |
#define | P_K68_STR "1b3f" |
#define | IS_K68(kb) ((kb)->vendor == V_CORSAIR && (kb)->product == P_K68) |
#define | P_K70 0x1b13 |
#define | P_K70_STR "1b13" |
#define | P_K70_NRGB 0x1b09 |
#define | P_K70_NRGB_STR "1b09" |
#define | P_K70_LUX 0x1b33 |
#define | P_K70_LUX_STR "1b33" |
#define | P_K70_LUX_NRGB 0x1b36 |
#define | P_K70_LUX_NRGB_STR "1b36" |
#define | P_K70_RFIRE 0x1b38 |
#define | P_K70_RFIRE_STR "1b38" |
#define | P_K70_RFIRE_NRGB 0x1b3a |
#define | P_K70_RFIRE_NRGB_STR "1b3a" |
#define | IS_K70(kb) ((kb)->vendor == V_CORSAIR && ((kb)->product == P_K70 || (kb)->product == P_K70_NRGB || (kb)->product == P_K70_RFIRE || (kb)->product == P_K70_RFIRE_NRGB || (kb)->product == P_K70_LUX || (kb)->product == P_K70_LUX_NRGB)) |
#define | P_K95 0x1b11 |
#define | P_K95_STR "1b11" |
#define | P_K95_NRGB 0x1b08 |
#define | P_K95_NRGB_STR "1b08" |
#define | P_K95_PLATINUM 0x1b2d |
#define | P_K95_PLATINUM_STR "1b2d" |
#define | IS_K95(kb) ((kb)->vendor == V_CORSAIR && ((kb)->product == P_K95 || (kb)->product == P_K95_NRGB || (kb)->product == P_K95_PLATINUM)) |
#define | P_STRAFE 0x1b20 |
#define | P_STRAFE_STR "1b20" |
#define | P_STRAFE_NRGB 0x1b15 |
#define | P_STRAFE_NRGB_STR "1b15" |
#define | P_STRAFE_NRGB_2 0x1b44 |
#define | P_STRAFE_NRGB_2_STR "1b44" |
#define | IS_STRAFE(kb) ((kb)->vendor == V_CORSAIR && ((kb)->product == P_STRAFE || (kb)->product == P_STRAFE_NRGB || (kb)->product == P_STRAFE_NRGB_2)) |
#define | P_M65 0x1b12 |
#define | P_M65_STR "1b12" |
#define | P_M65_PRO 0x1b2e |
#define | P_M65_PRO_STR "1b2e" |
#define | IS_M65(kb) ((kb)->vendor == V_CORSAIR && ((kb)->product == P_M65 || (kb)->product == P_M65_PRO)) |
#define | P_SABRE_O 0x1b14 /* optical */ |
#define | P_SABRE_O_STR "1b14" |
#define | P_SABRE_L 0x1b19 /* laser */ |
#define | P_SABRE_L_STR "1b19" |
#define | P_SABRE_N 0x1b2f /* new? */ |
#define | P_SABRE_N_STR "1b2f" |
#define | P_SABRE_O2 0x1b32 /* Observed on a CH-9000111-EU model SABRE */ |
#define | P_SABRE_O2_STR "1b32" |
#define | IS_SABRE(kb) ((kb)->vendor == V_CORSAIR && ((kb)->product == P_SABRE_O || (kb)->product == P_SABRE_L || (kb)->product == P_SABRE_N || (kb)->product == P_SABRE_O2)) |
#define | P_SCIMITAR 0x1b1e |
#define | P_SCIMITAR_STR "1b1e" |
#define | P_SCIMITAR_PRO 0x1b3e |
#define | P_SCIMITAR_PRO_STR "1b3e" |
#define | IS_SCIMITAR(kb) ((kb)->vendor == V_CORSAIR && ((kb)->product == P_SCIMITAR || (kb)->product == P_SCIMITAR_PRO)) |
#define | P_HARPOON 0x1b3c |
#define | P_HARPOON_STR "1b3c" |
#define | IS_HARPOON(kb) ((kb)->vendor == V_CORSAIR && (kb)->product == P_HARPOON) |
#define | P_GLAIVE 0x1b34 |
#define | P_GLAIVE_STR "1b34" |
#define | IS_GLAIVE(kb) ((kb)->vendor == V_CORSAIR && (kb)->product == P_GLAIVE) |
#define | IS_RGB(vendor, product) ((vendor) == (V_CORSAIR) && (product) != (P_K65_NRGB) && (product) != (P_K70_NRGB) && (product) != (P_K95_NRGB)) |
RGB vs non-RGB test (note: non-RGB Strafe is still considered "RGB" in that it shares the same protocol. The difference is denoted with the "monochrome" feature). More... | |
#define | IS_MONOCHROME(vendor, product) ((vendor) == (V_CORSAIR) && ((product) == (P_K68) || (product) == (P_STRAFE_NRGB) || (product) == (P_STRAFE_NRGB_2))) |
The difference between non RGB and monochrome is, that monochrome has lights, but just in one color. nonRGB has no lights. Change this if new monochrome devices are added. More... | |
#define | IS_RGB_DEV(kb) IS_RGB((kb)->vendor, (kb)->product) |
For calling with a usbdevice*, vendor and product are extracted and IS_RGB() is returned. More... | |
#define | IS_MONOCHROME_DEV(kb) IS_MONOCHROME((kb)->vendor, (kb)->product) |
For calling with a usbdevice*, vendor and product are extracted and IS_MONOCHROME() is returned. More... | |
#define | IS_FULLRANGE(kb) (IS_RGB((kb)->vendor, (kb)->product) && (kb)->product != P_K65 && (kb)->product != P_K70 && (kb)->product != P_K95) |
Full color range (16.8M) vs partial color range (512) More... | |
#define | IS_MOUSE(vendor, product) ((vendor) == (V_CORSAIR) && ((product) == (P_M65) || (product) == (P_M65_PRO) || (product) == (P_SABRE_O) || (product) == (P_SABRE_L) || (product) == (P_SABRE_N) || (product) == (P_SCIMITAR) || (product) == (P_SCIMITAR_PRO) || (product) == (P_SABRE_O2) || (product) == (P_GLAIVE) || (product) == (P_HARPOON))) |
Mouse vs keyboard test. More... | |
#define | IS_MOUSE_DEV(kb) IS_MOUSE((kb)->vendor, (kb)->product) |
For calling with a usbdevice*, vendor and product are extracted and IS_MOUSE() is returned. More... | |
#define | IS_PLATINUM(kb) ((kb)->vendor == V_CORSAIR && ((kb)->product == P_K95_PLATINUM)) |
Used to apply quirks and features to the PLATINUM devices. More... | |
#define | IS_V2_OVERRIDE(kb) (IS_PLATINUM(kb) || IS_K63(kb) || IS_K68(kb) || IS_HARPOON(kb) || IS_GLAIVE(kb) || (kb)->product == P_STRAFE_NRGB_2) |
Used when a device has a firmware with a low version number that uses the new protocol. More... | |
#define | DELAY_SHORT(kb) clock_nanosleep(CLOCK_MONOTONIC, 0, &(struct timespec) {.tv_nsec = ((int) (kb->usbdelay)) * 1000000}, NULL) |
USB delays for when the keyboards get picky about timing That was the original comment, but it is used anytime. More... | |
#define | DELAY_MEDIUM(kb) clock_nanosleep(CLOCK_MONOTONIC, 0, &(struct timespec) {.tv_nsec = ((int) (kb->usbdelay)) * 10000000}, NULL) |
the medium delay is used after sending a command before waiting for the answer. More... | |
#define | DELAY_LONG(kb) clock_nanosleep(CLOCK_MONOTONIC, 0, &(struct timespec) {.tv_nsec = 100000000}, NULL) |
The longest delay takes place where something went wrong (eg when resetting the device) More... | |
#define | USB_DELAY_DEFAULT 5 |
This constant is used to initialize kb->usbdelay. It is used in many places (see macros above) but often also overwritten to the fixed value of 10. Pure Hacker code. More... | |
#define | resetusb(kb) _resetusb(kb, __FILE_NOPATH__, __LINE__) |
resetusb() is just a macro to call _resetusb() with debuggin constants (file, lineno) More... | |
#define | usbsend(kb, messages, count) _usbsend(kb, messages, count, __FILE_NOPATH__, __LINE__) |
usbsend macro is used to wrap _usbsend() with debugging information (file and lineno) More... | |
#define | usbrecv(kb, out_msg, in_msg) _usbrecv(kb, out_msg, in_msg, __FILE_NOPATH__, __LINE__) |
usbrecv macro is used to wrap _usbrecv() with debugging information (file and lineno) More... | |
#define | nk95cmd(kb, command) _nk95cmd(kb, (command) >> 16 & 0xFF, (command) & 0xFFFF, __FILE_NOPATH__, __LINE__) |
nk95cmd() macro is used to wrap _nk95cmd() with debugging information (file and lineno). the command structure is different: Just the bits 23..16 are used as bits 7..0 for bRequest Bits 15..0 are used as wValue More... | |
#define | NK95_HWOFF 0x020030 |
Hardware-specific commands for the K95 nonRGB,. More... | |
#define | NK95_HWON 0x020001 |
Hardware playback on. More... | |
#define | NK95_M1 0x140001 |
Switch to mode 1. More... | |
#define | NK95_M2 0x140002 |
Switch to mode 2. More... | |
#define | NK95_M3 0x140003 |
Switch to mode 3. More... | |
Functions | |
const char * | vendor_str (short vendor) |
uncomment to see USB packets sent to the device More... | |
const char * | product_str (short product) |
product_str returns a condensed view on what type of device we have. More... | |
int | usbmain () |
Start the USB main loop. Returns program exit code when finished. More... | |
void | usbkill () |
Stop the USB system. More... | |
void | setupusb (usbdevice *kb) |
setupusb starts a thread with kb as parameter and _setupusb() as entrypoint. More... | |
int | os_setupusb (usbdevice *kb) |
os_setupusb OS-specific setup for a specific usb device. More... | |
void * | os_inputmain (void *context) |
os_inputmain is run in a separate thread and will be detached from the main thread, so it needs to clean up its own resources. More... | |
int | revertusb (usbdevice *kb) |
revertusb sets a given device to inactive (hardware controlled) mode if not a fw-ugrade is indicated More... | |
int | closeusb (usbdevice *kb) |
closeusb Close a USB device and remove device entry. More... | |
void | os_closeusb (usbdevice *kb) |
os_closeusb unclaim it, destroy the udev device and clear data structures at kb More... | |
int | _resetusb (usbdevice *kb, const char *file, int line) |
_resetusb Reset a USB device. More... | |
int | os_resetusb (usbdevice *kb, const char *file, int line) |
os_resetusb is the os specific implementation for resetting usb More... | |
int | _usbsend (usbdevice *kb, const uchar *messages, int count, const char *file, int line) |
_usbsend send a logical message completely to the given device More... | |
int | _usbrecv (usbdevice *kb, const uchar *out_msg, uchar *in_msg, const char *file, int line) |
_usbrecv Request data from a USB device by first sending an output packet and then reading the response. More... | |
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 More... | |
int | os_usbrecv (usbdevice *kb, uchar *in_msg, const char *file, int line) |
os_usbrecv receives a max MSGSIZE long buffer from usb device More... | |
void | os_sendindicators (usbdevice *kb) |
os_sendindicators update the indicators for the special keys (Numlock, Capslock and what else?) More... | |
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 More... | |
int | usb_tryreset (usbdevice *kb) |
usb_tryreset does what the name means: Try to reset the usb via resetusb() More... | |
Vendor/product codes
The list of defines in the first part of the file describes the various types of equipment from Corsair and summarizes them according to specific characteristics.
Each device type is described with two defines:
First entry-pair is the Provider ID (vendorID) from Corsair.
Block No. | contains | Devices are bundled via ------— | -----— | --------------------— 1 | The first block contains the K63 Non RGB Keyboard. No other K63 is known so far. 2 | the K65-like keyboards, regardless of their properties (RGB, ...). | In summary, they can be queried using the macro IS_K65(). 3 | K68 keyboard | IS_K68(). 4 | the K70-like Keyboards with all their configuration types | summarized by IS_K70(). 5 | the K95 series keyboards | collected with the macro IS_K95(). 6 | strafe keyboards | IS_STRAFE() 7 | M65 mice with and without RGB | IS_M65() 8 | Sabre mice | IS_SABRE() 9 | Scimitar mice | IS_SCIMITAR() 10| Harpoon mice | IS_HARPOON() 11| Glaive mice | IS_GLAIVE()
Definition in file usb.h.
#define DELAY_LONG | ( | kb | ) | clock_nanosleep(CLOCK_MONOTONIC, 0, &(struct timespec) {.tv_nsec = 100000000}, NULL) |
Definition at line 186 of file usb.h.
Referenced by _resetusb(), _setupusb(), _usbrecv(), _usbsend(), cmd_hwload_kb(), cmd_hwload_mouse(), cmd_hwsave_kb(), and cmd_hwsave_mouse().
#define DELAY_MEDIUM | ( | kb | ) | clock_nanosleep(CLOCK_MONOTONIC, 0, &(struct timespec) {.tv_nsec = ((int) (kb->usbdelay)) * 10000000}, NULL) |
Definition at line 182 of file usb.h.
Referenced by _usbrecv(), and setactive_kb().
#define DELAY_SHORT | ( | kb | ) | clock_nanosleep(CLOCK_MONOTONIC, 0, &(struct timespec) {.tv_nsec = ((int) (kb->usbdelay)) * 1000000}, NULL) |
The short delay is used before any send or receive
Definition at line 178 of file usb.h.
Referenced by _usbrecv(), _usbsend(), and updateindicators_kb().
#define IS_FULLRANGE | ( | kb | ) | (IS_RGB((kb)->vendor, (kb)->product) && (kb)->product != P_K65 && (kb)->product != P_K70 && (kb)->product != P_K95) |
Definition at line 160 of file usb.h.
Referenced by readcmd(), and updatergb_kb().
Definition at line 121 of file usb.h.
Referenced by updatergb_mouse().
#define IS_K63 | ( | kb | ) | ((kb)->vendor == V_CORSAIR && (kb)->product == P_K63_NRGB) |
#define IS_K65 | ( | kb | ) | ((kb)->vendor == V_CORSAIR && ((kb)->product == P_K65 || (kb)->product == P_K65_NRGB || (kb)->product == P_K65_LUX || (kb)->product == P_K65_RFIRE)) |
#define IS_K70 | ( | kb | ) | ((kb)->vendor == V_CORSAIR && ((kb)->product == P_K70 || (kb)->product == P_K70_NRGB || (kb)->product == P_K70_RFIRE || (kb)->product == P_K70_RFIRE_NRGB || (kb)->product == P_K70_LUX || (kb)->product == P_K70_LUX_NRGB)) |
#define IS_K95 | ( | kb | ) | ((kb)->vendor == V_CORSAIR && ((kb)->product == P_K95 || (kb)->product == P_K95_NRGB || (kb)->product == P_K95_PLATINUM)) |
Definition at line 83 of file usb.h.
Referenced by cmd_hwload_kb(), cmd_hwsave_kb(), and has_key().
#define IS_MONOCHROME | ( | vendor, | |
product | |||
) | ((vendor) == (V_CORSAIR) && ((product) == (P_K68) || (product) == (P_STRAFE_NRGB) || (product) == (P_STRAFE_NRGB_2))) |
Definition at line 151 of file usb.h.
Referenced by _setupusb().
#define IS_MONOCHROME_DEV | ( | kb | ) | IS_MONOCHROME((kb)->vendor, (kb)->product) |
#define IS_MOUSE | ( | vendor, | |
product | |||
) | ((vendor) == (V_CORSAIR) && ((product) == (P_M65) || (product) == (P_M65_PRO) || (product) == (P_SABRE_O) || (product) == (P_SABRE_L) || (product) == (P_SABRE_N) || (product) == (P_SCIMITAR) || (product) == (P_SCIMITAR_PRO) || (product) == (P_SABRE_O2) || (product) == (P_GLAIVE) || (product) == (P_HARPOON))) |
Definition at line 163 of file usb.h.
Referenced by _setupusb(), get_vtable(), has_key(), and os_inputmain().
#define IS_MOUSE_DEV | ( | kb | ) | IS_MOUSE((kb)->vendor, (kb)->product) |
#define IS_PLATINUM | ( | kb | ) | ((kb)->vendor == V_CORSAIR && ((kb)->product == P_K95_PLATINUM)) |
#define IS_RGB | ( | vendor, | |
product | |||
) | ((vendor) == (V_CORSAIR) && (product) != (P_K65_NRGB) && (product) != (P_K70_NRGB) && (product) != (P_K95_NRGB)) |
Definition at line 146 of file usb.h.
Referenced by _setupusb(), get_vtable(), and os_inputmain().
#define IS_SABRE | ( | kb | ) | ((kb)->vendor == V_CORSAIR && ((kb)->product == P_SABRE_O || (kb)->product == P_SABRE_L || (kb)->product == P_SABRE_N || (kb)->product == P_SABRE_O2)) |
Definition at line 107 of file usb.h.
Referenced by has_key(), loadrgb_mouse(), and savergb_mouse().
#define IS_SCIMITAR | ( | kb | ) | ((kb)->vendor == V_CORSAIR && ((kb)->product == P_SCIMITAR || (kb)->product == P_SCIMITAR_PRO)) |
Definition at line 113 of file usb.h.
Referenced by has_key(), loadrgb_mouse(), and savergb_mouse().
#define IS_STRAFE | ( | kb | ) | ((kb)->vendor == V_CORSAIR && ((kb)->product == P_STRAFE || (kb)->product == P_STRAFE_NRGB || (kb)->product == P_STRAFE_NRGB_2)) |
Definition at line 91 of file usb.h.
Referenced by savergb_kb().
#define IS_V2_OVERRIDE | ( | kb | ) | (IS_PLATINUM(kb) || IS_K63(kb) || IS_K68(kb) || IS_HARPOON(kb) || IS_GLAIVE(kb) || (kb)->product == P_STRAFE_NRGB_2) |
Definition at line 172 of file usb.h.
Referenced by loadrgb_kb(), os_usbsend(), and savergb_kb().
#define NK95_HWOFF 0x020030 |
Definition at line 333 of file usb.h.
Referenced by start_kb_nrgb().
#define NK95_HWON 0x020001 |
Definition at line 336 of file usb.h.
Referenced by revertusb().
#define NK95_M1 0x140001 |
Definition at line 339 of file usb.h.
Referenced by setmodeindex_nrgb().
#define NK95_M2 0x140002 |
Definition at line 342 of file usb.h.
Referenced by setmodeindex_nrgb().
#define NK95_M3 0x140003 |
Definition at line 345 of file usb.h.
Referenced by setmodeindex_nrgb().
#define nk95cmd | ( | kb, | |
command | |||
) | _nk95cmd(kb, (command) >> 16 & 0xFF, (command) & 0xFFFF, __FILE_NOPATH__, __LINE__) |
Definition at line 328 of file usb.h.
Referenced by revertusb(), setmodeindex_nrgb(), and start_kb_nrgb().
#define P_GLAIVE 0x1b34 |
Definition at line 119 of file usb.h.
Referenced by product_str().
#define P_HARPOON 0x1b3c |
Definition at line 115 of file usb.h.
Referenced by product_str().
#define P_K63_NRGB 0x1b40 |
Definition at line 45 of file usb.h.
Referenced by product_str().
#define P_K65 0x1b17 |
Definition at line 49 of file usb.h.
Referenced by product_str().
#define P_K65_LUX 0x1b37 |
Definition at line 53 of file usb.h.
Referenced by product_str().
#define P_K65_NRGB 0x1b07 |
Definition at line 51 of file usb.h.
Referenced by product_str().
#define P_K65_RFIRE 0x1b39 |
Definition at line 55 of file usb.h.
Referenced by product_str().
#define P_K68 0x1b3f |
Definition at line 59 of file usb.h.
Referenced by product_str().
#define P_K70 0x1b13 |
Definition at line 63 of file usb.h.
Referenced by product_str().
#define P_K70_LUX 0x1b33 |
Definition at line 67 of file usb.h.
Referenced by loadrgb_kb(), and product_str().
#define P_K70_LUX_NRGB 0x1b36 |
Definition at line 69 of file usb.h.
Referenced by loadrgb_kb(), and product_str().
#define P_K70_NRGB 0x1b09 |
Definition at line 65 of file usb.h.
Referenced by product_str().
#define P_K70_RFIRE 0x1b38 |
Definition at line 71 of file usb.h.
Referenced by product_str().
#define P_K70_RFIRE_NRGB 0x1b3a |
Definition at line 73 of file usb.h.
Referenced by product_str().
#define P_K95 0x1b11 |
Definition at line 77 of file usb.h.
Referenced by product_str().
#define P_K95_NRGB 0x1b08 |
Definition at line 79 of file usb.h.
Referenced by _nk95cmd(), and product_str().
#define P_K95_PLATINUM 0x1b2d |
Definition at line 81 of file usb.h.
Referenced by product_str(), and updatergb_kb().
#define P_M65 0x1b12 |
Definition at line 93 of file usb.h.
Referenced by product_str().
#define P_M65_PRO 0x1b2e |
Definition at line 95 of file usb.h.
Referenced by product_str().
#define P_SABRE_L 0x1b19 /* laser */ |
Definition at line 101 of file usb.h.
Referenced by product_str().
#define P_SABRE_N 0x1b2f /* new? */ |
Definition at line 103 of file usb.h.
Referenced by product_str().
#define P_SABRE_O 0x1b14 /* optical */ |
Definition at line 99 of file usb.h.
Referenced by product_str().
#define P_SABRE_O2 0x1b32 /* Observed on a CH-9000111-EU model SABRE */ |
Definition at line 105 of file usb.h.
Referenced by product_str().
#define P_SCIMITAR 0x1b1e |
Definition at line 109 of file usb.h.
Referenced by product_str().
#define P_SCIMITAR_PRO 0x1b3e |
Definition at line 111 of file usb.h.
Referenced by product_str().
#define P_STRAFE 0x1b20 |
Definition at line 85 of file usb.h.
Referenced by product_str().
#define P_STRAFE_NRGB 0x1b15 |
Definition at line 87 of file usb.h.
Referenced by product_str().
#define P_STRAFE_NRGB_2 0x1b44 |
Definition at line 89 of file usb.h.
Referenced by product_str().
#define resetusb | ( | kb | ) | _resetusb(kb, __FILE_NOPATH__, __LINE__) |
Definition at line 246 of file usb.h.
Referenced by usb_tryreset().
#define USB_DELAY_DEFAULT 5 |
Definition at line 192 of file usb.h.
Referenced by _setupusb(), and start_dev().
#define usbrecv | ( | kb, | |
out_msg, | |||
in_msg | |||
) | _usbrecv(kb, out_msg, in_msg, __FILE_NOPATH__, __LINE__) |
kb | THE usbdevice* |
IN] | out_msg What information does the caller want from the device? |
OUT] | in_msg Here comes the answer; The names represent the usb view, not the view of this function! So INput from usb is OUTput of this function. |
Definition at line 288 of file usb.h.
Referenced by cmd_hwload_kb(), cmd_hwload_mouse(), getfwversion(), hwloadmode(), loaddpi(), loadrgb_kb(), and loadrgb_mouse().
#define usbsend | ( | kb, | |
messages, | |||
count | |||
) | _usbsend(kb, messages, count, __FILE_NOPATH__, __LINE__) |
kb | THE usbdevice* |
IN] | messages a Pointer to the first byte of the logical message |
IN] | count how many MSG_SIZE buffers is the logical message long? |
Definition at line 271 of file usb.h.
Referenced by cmd_hwsave_kb(), cmd_hwsave_mouse(), cmd_pollrate(), fwupdate(), loadrgb_kb(), savedpi(), savergb_kb(), savergb_mouse(), setactive_kb(), setactive_mouse(), updatedpi(), updatergb_kb(), and updatergb_mouse().
#define V_CORSAIR 0x1b1c |
Definition at line 42 of file usb.h.
Referenced by usb_add_device(), and vendor_str().
#define V_CORSAIR_STR "1b1c" |
Definition at line 43 of file usb.h.
Referenced by udev_enum(), and usb_add_device().
kb | THE usbdevice* |
bRequest | the byte array with the usb request |
wValue | a usb wValue |
file | for error message |
line | for error message |
To send control packets to a non RGB non color K95 Keyboard, use this function. Normally it is called via the nk95cmd() macro.
If it is the wrong device for which the function is called, 0 is returned and nothing done. Otherwise a usbdevfs_ctrltransfer structure is filled and an USBDEVFS_CONTROL ioctl() called.
bRequestType | bRequest | wValue | EP | size | Timeout | data |
---|---|---|---|---|---|---|
0x40 | see table below to switch hardware-modus at Keyboard | wValue | device | MSG_SIZE | 5ms | the message buffer pointer |
Host to Device, Type=Vendor, Recipient=Device | bRequest parameter | given wValue Parameter | device 0 | 0 data to write | 5000 | null |
If a 0 or a negative error number is returned by the ioctl, an error message is shown depending on the errno or "No data written" if retval was 0. In either case 1 is returned to indicate the error. If the ioctl returned a value > 0, 0 is returned to indicate no error.
Currently the following combinations for bRequest and wValue are used:
Device | what it might to do | constant | bRequest | wValue |
---|---|---|---|---|
non RGB Keyboard | set HW-modus on (leave the ckb driver) | HWON | 0x0002 | 0x0030 |
non RGB Keyboard | set HW-modus off (initialize the ckb driver) | HWOFF | 0x0002 | 0x0001 |
non RGB Keyboard | set light modus M1 in single-color keyboards | NK95_M1 | 0x0014 | 0x0001 |
non RGB Keyboard | set light modus M2 in single-color keyboards | NK95_M2 | 0x0014 | 0x0002 |
non RGB Keyboard | set light modus M3 in single-color keyboards | NK95_M3 | 0x0014 | 0x0003 |
Definition at line 189 of file usb_linux.c.
References ckb_err_fn, usbdevice::handle, P_K95_NRGB, and usbdevice::product.
int _resetusb | ( | usbdevice * | kb, |
const char * | file, | ||
int | line | ||
) |
kb | THE usbdevice* |
file | filename for error messages |
line | line where it is called for error messages |
_resetusb Reset a USB device.
First reset the device via os_resetusb() after a long delay (it may send something to the host). If this worked (retval == 0), give the device another long delay Then perform the initialization via the device specific start() function entry in kb->vtable and if this is successful also, return the result of the device depenten updatergb() with force=true.
Definition at line 436 of file usb.c.
References usbdevice::active, DELAY_LONG, os_resetusb(), and usbdevice::vtable.
kb | THE usbdevice* |
IN] | out_msg What information does the caller want from the device? |
OUT] | in_msg Here comes the answer; The names represent the usb view, not the view of this function! So INput from usb is OUTput of this function. |
IN] | file for debugging |
IN] | line for debugging |
IN] | reset_stop global variable is read |
_usbrecv Request data from a USB device by first sending an output packet and then reading the response.
To fully understand this, you need to know about usb: All control is at the usb host (the CPU). If the device wants to communicate something to the host, it must wait for the host to ask. The usb protocol defines the cycles and periods in which actions are to be taken.
So in order to receive a data packet from the device, the host must first send a send request.
This is done by _usbrecv() in the first block by sending the MSG_SIZE large data block from out_msg via os_usbsend() as it is a machine depending implementation. The usb target device is as always determined over kb.
For os_usbsend() to know that it is a receive request, the is_recv parameter is set to true (1). With this, os_usbsend () generates a control package for the hardware, not a data packet.
If sending of the control package is not successful, a maximum of 5 times the transmission is repeated (including the first attempt). If a non-cancelable error is signaled or the drive is stopped via reset_stop, _usbrecv() immediately returns 0.
After this, the function waits for the requested response from the device using os_usbrecv ().
os_usbrecv() returns 0, -1 or something else.
Zero signals a serious error which is not treatable and _usbrecv() also returns 0.
-1 means that it is a treatable error - a timeout for example - and therefore the next transfer attempt is started after a long pause (DELAY_LONG) if not reset_stop or the wrong hwload_mode require a termination with a return value of 0.
After 5 attempts, _usbrecv () returns and returns 0 as well as an error message.
When data is received, the number of received bytes is returned. This should always be MSG_SIZE, but os_usbrecv() can also return less. It should not be more, because then there would be an unhandled buffer overflow, but it could be less. This would be signaled in os_usbrecv () with a message.
The buffers behind out_msg and in_msg are MSG_SIZE at least (currently 64 Bytes). More is ok but useless, less brings unpredictable behavior.
< Synchonization between macro and color information
Definition at line 611 of file usb.c.
References ckb_err_fn, DELAY_LONG, DELAY_MEDIUM, DELAY_SHORT, hwload_mode, mmutex, os_usbrecv(), os_usbsend(), and reset_stop.
kb | THE usbdevice* | |
IN] | messages a Pointer to the first byte of the logical message | |
IN] | count how many MSG_SIZE buffers is the logical message long? | |
IN] | file for debugging | |
IN] | line for debugging | |
[in] | reset_stop | global variable is read |
_usbsend send a logical message completely to the given device
The main task of _usbsend () is to transfer the complete logical message from the buffer beginning with messages to count * MSG_SIZE.
According to usb 2.0 specification, a USB transmits a maximum of 64 byte user data packets. For the transmission of longer messages we need a segmentation. And that is exactly what happens here.
The message is given one by one to os_usbsend() in MSG_SIZE (= 64) byte large bites.
An essential constant parameter which is relevant for os_usbsend() only is is_recv = 0, which means sending.
Now it gets a little complicated again:
When the last packet is transferred, _usbsend() returns the effectively counted set of bytes (from total_sent). This at least gives the caller the opportunity to check whether something has been lost in the middle.
A bit strange is the structure of the program: Handling the count MSG_SIZE blocks to be transferred is done in the outer for (...) loop. Repeating the transfer with a treatable error is managed by the inner while(1) loop.
This must be considered when reading the code; The "break" on successful block transfer leaves the inner while, not the for (...).
< Synchonization between macro and color information
Definition at line 542 of file usb.c.
References DELAY_LONG, DELAY_SHORT, hwload_mode, mmutex, MSG_SIZE, os_usbsend(), and reset_stop.
int closeusb | ( | usbdevice * | kb | ) |
IN,OUT] | kb |
closeusb Close a USB device and remove device entry.
An imutex lock ensures first of all, that no communication is currently running from the viewpoint of the driver to the user input device (ie the virtual driver with which characters or mouse movements are sent from the daemon to the operating system as inputs).
If the kb has an acceptable value != 0, the index of the device is looked for and with this index os_inputclose() is called. After this no more characters can be sent to the operating system.
Then the connection to the usb device is capped by os_closeusb().
If there is no valid handle, only updateconnected() is called. We are probably trying to disconnect a connection under construction. Not clear.
The cmd pipe as well as all open notify pipes are deleted via rmdevpath ().
This means that nothing can happen to the input path - so the device-specific imutex is unlocked again and remains unlocked.
Also the dmutex is unlocked now, but only to join the thread, which was originally taken under kb->thread (which started with _setupusb()) with pthread_join() again. Because of the closed devices that thread would have to quit sometime
As soon as the thread is caught, the dmutex is locked again, which is what I do not understand yet: What other thread can do usb communication now?
If the vtabel exists for the given kb (why not? It seems to have race conditions here!!), via the vtable the actually device-specific, but still everywhere identical freeprofile() is called. This frees areas that are no longer needed. Then the usbdevice structure in its array is set to zero completely.
Error handling is rather unusual in closeusb(); Everything works (no matter what the called functions return), and closeusb() always returns zero (success).
Definition at line 687 of file usb.c.
References ckb_info, devpath, dmutex, usbdevice::handle, imutex, INDEX_OF, keyboard, os_closeusb(), os_inputclose(), rmdevpath(), usbdevice::thread, updateconnected(), and usbdevice::vtable.
Referenced by _setupusb(), devmain(), quitWithLock(), and usb_rm_device().
void os_closeusb | ( | usbdevice * | kb | ) |
IN,OUT] | kb THE usbdevice* |
os_closeusb unclaim it, destroy the udev device and clear data structures at kb
os_closeusb is the linux specific implementation for closing an active usb port.
If a valid handle is given in the kb structure, the usb port is unclaimed (usbunclaim()).
The device in unrefenced via library function udev_device_unref().
handle, udev and the first char of kbsyspath are cleared to 0 (empty string for kbsyspath).
Definition at line 448 of file usb_linux.c.
References usbdevice::handle, INDEX_OF, kbsyspath, keyboard, usbdevice::udev, and usbunclaim().
Referenced by closeusb().
void* os_inputmain | ( | void * | context | ) |
context | THE usbdevice* ; Because os_inputmain() is started as a new thread, its formal parameter is named "context". |
os_inputmain is run in a separate thread and will be detached from the main thread, so it needs to clean up its own resources.
Here the actions in detail:
Monitor input transfers on all endpoints for non-RGB devices For RGB, monitor all but the last, as it's used for input/output
Get an usbdevfs_urb data structure and clear it via memset()
Hopefully the buffer lengths are equal for all devices with congruent types. You can find out the correctness for your device with lsusb –v or similar on macOS. Currently the following combinations are known and implemented:
device | detect with macro combination | endpoint # | buffer-length |
---|---|---|---|
each | none | 0 | 8, 64 for FW v3 |
RGB Mouse | IS_RGB && IS_MOUSE | 1 | 10 |
RGB Keyboard | IS_RGB && !IS_MOUSE | 1 | 21 |
RGB Mouse or Keyboard | IS_RGB | 2 | MSG_SIZE (64) |
non RGB Mouse or Keyboard | !IS_RGB | 1 | 4 |
non RGB Mouse or Keyboard | !IS_RGB | 2 | 15 |
Now submit all the URBs via ioctl(USBDEVFS_SUBMITURB) with type USBDEVFS_URB_TYPE_INTERRUPT (the endpoints are defined as type interrupt). Endpoint number is 0x80..0x82 or 0x83, depending on the model.
The userSpaceFS knows the URBs now, so start monitoring input
if the ioctl returns something != 0, let's have a deeper look what happened. Broken devices or shutting down the entire system leads to closing the device and finishing this thread.
If just an EPIPE ocurred, give the device a CLEAR_HALT and resubmit the URB.
A correct REAPURB returns a Pointer to the URB which we now have a closer look into. Lock all following actions with imutex.
Process the input depending on type of device. Interprete the actual size of the URB buffer
device | detect with macro combination | seems to be endpoint # | actual buffer-length | function called |
---|---|---|---|---|
mouse (RGB and non RGB) | IS_MOUSE | nA | 8, 10 or 11 | hid_mouse_translate() |
mouse (RGB and non RGB) | IS_MOUSE | nA | MSG_SIZE (64) | corsair_mousecopy() |
RGB Keyboard | IS_RGB && !IS_MOUSE | 1 | 8 (BIOS Mode) | hid_kb_translate() |
RGB Keyboard | IS_RGB && !IS_MOUSE | 2 | 5 or 21, KB inactive! | hid_kb_translate() |
RGB Keyboard | IS_RGB && !IS_MOUSE | 3? | MSG_SIZE | corsair_kbcopy() |
non RGB Keyboard | !IS_RGB && !IS_MOUSE | nA | nA | hid_kb_translate() |
The input data is transformed and copied to the kb structure. Now give it to the OS and unlock the imutex afterwards.
Re-submit the URB for the next run.
If the endless loop is terminated, clean up by discarding the URBs via ioctl(USBDEVFS_DISCARDURB), free the URB buffers and return a null pointer as thread exit code.
Definition at line 248 of file usb_linux.c.
References usbdevice::active, ckb_err, ckb_info, corsair_kbcopy(), corsair_mousecopy(), devpath, usbdevice::epcount, usbdevice::fwversion, usbdevice::handle, hid_kb_translate(), hid_mouse_translate(), imutex, INDEX_OF, usbdevice::input, inputupdate(), IS_MOUSE, IS_RGB, keyboard, usbinput::keys, MSG_SIZE, usbdevice::product, usbinput::rel_x, usbinput::rel_y, and usbdevice::vendor.
Referenced by _setupusb().
int os_resetusb | ( | usbdevice * | kb, |
const char * | file, | ||
int | line | ||
) |
kb | THE usbdevice* |
file | filename for error messages |
line | line where it is called for error messages |
os_resetusb is the os specific implementation for resetting usb
Try to reset an usb device in a linux user space driver.
Definition at line 510 of file usb_linux.c.
References usbdevice::handle, TEST_RESET, usbclaim(), and usbunclaim().
Referenced by _resetusb().
void os_sendindicators | ( | usbdevice * | kb | ) |
kb | THE usbdevice* |
os_sendindicators update the indicators for the special keys (Numlock, Capslock and what else?)
os_sendindicators update the indicators for the special keys (Numlock, Capslock and what else?)
Read the data from kb->ileds ans send them via ioctl() to the keyboard.
bRequestType | bRequest | wValue | EP | size | Timeout | data |
---|---|---|---|---|---|---|
0x21 | 0x09 | 0x0200 | Interface 0 | MSG_SIZE 1 Byte | timeout 0,5ms | the message buffer pointer |
Host to Device, Type=Class, Recipient=Interface (why not endpoint?) | 9 = SEND? | specific | 0 | 1 | 500 | struct* kb->ileds |
The ioctl command is USBDEVFS_CONTROL.
Definition at line 214 of file usb_linux.c.
References ckb_err, usbdevice::fwversion, usbdevice::handle, usbdevice::ileds, and usb_tryreset().
Referenced by updateindicators_kb().
int os_setupusb | ( | usbdevice * | kb | ) |
kb | THE usbdevice* |
os_setupusb OS-specific setup for a specific usb device.
Perform the operating system-specific opening of the interface in os_setupusb(). As a result, some parameters should be set in kb (name, serial, fwversion, epcount = number of usb endpoints), and all endpoints should be claimed with usbclaim(). Claiming is the only point where os_setupusb() can produce an error (-1).
< Try to reset the device and recall the function
< Don't do this endless in recursion
< os_setupusb() has a return value (used as boolean)
Definition at line 548 of file usb_linux.c.
References ckb_err, ckb_info, devpath, usbdevice::epcount, usbdevice::fwversion, INDEX_OF, KB_NAME_LEN, keyboard, usbdevice::name, usbdevice::serial, SERIAL_LEN, strtrim(), usbdevice::udev, usb_tryreset(), and usbclaim().
Referenced by _setupusb().
kb | THE usbdevice* |
in_msg | the buffer to fill with the message received |
file | for debugging |
line | for debugging |
os_usbrecv does what its name says:
The comment at the beginning of the procedure causes the suspicion that the firmware versionspecific distinction is missing for receiving from usb endpoint 3 or 4. The commented code contains only the reception from EP4, but this may be wrong for a software version 2.0 or higher (see the code for os-usbsend ()).
So all the receiving is done via an ioctl() like in os_usbsend. The ioctl() is given a struct usbdevfs_ctrltransfer, in which the relevant parameters are entered:
bRequestType | bRequest | wValue | EP | size | Timeout | data |
---|---|---|---|---|---|---|
0xA1 | 0x01 | 0x0200 | endpoint to be addressed from epcount - 1 | MSG_SIZE | 5ms | the message buffer pointer |
Device to Host, Type=Class, Recipient=Interface | 1 = RECEIVE? | specific | Interface # | 64 | 5000 | in_msg |
The ioctl() returns the number of bytes received. Here is the usual check again:
If this is not the entire blocksize (MSG_SIZE bytes), an error message is issued on the standard error channel [warning "Read YY bytes (expected 64)"].
Definition at line 130 of file usb_linux.c.
References ckb_err_fn, ckb_warn_fn, usbdevice::epcount, usbdevice::handle, and MSG_SIZE.
Referenced by _usbrecv().
kb | THE usbdevice* |
out_msg | the MSGSIZE char long buffer to send |
is_recv | if true, just send an ioctl for further reading packets. If false, send the data at out_msg. |
file | for debugging |
line | for debugging |
os_usbsend has two functions:
The functionality for sending distinguishes two cases, depending on the version number of the firmware of the connected device:
If the firmware is less or equal 1.2, the transmission is done via an ioctl(). The ioctl() is given a struct usbdevfs_ctrltransfer, in which the relevant parameters are entered:
bRequestType | bRequest | wValue | EP | size | Timeout | data |
---|---|---|---|---|---|---|
0x21 | 0x09 | 0x0200 | endpoint / IF to be addressed from epcount-1 | MSG_SIZE | 5000 (=5ms) | the message buffer pointer |
Host to Device, Type=Class, Recipient=Interface | 9 = Send data? | specific | last or pre-last device # | 64 | 5000 | out_msg |
The ioctl command is USBDEVFS_CONTROL.
The same constellation is used if the device is requested to send its data (is_recv = true).
For a more recent firmware and is_recv = false, the ioctl command USBDEVFS_CONTROL is not used (this tells the bus to enter the control mode), but the bulk method is used: USBDEVFS_BULK. This is astonishing, because all of the endpoints are type Interrupt, not bulk.
Anyhow, forthis purpose a different structure is used for the ioctl() (struct usbdevfs_bulktransfer) and this is also initialized differently:
The length and timeout parameters are given the same values as above. The formal parameter out_msg is also passed as a buffer pointer. For the endpoints, the firmware version is differentiated again:
For a firmware version between 1.3 and <2.0 endpoint 4 is used, otherwise (it can only be >=2.0) endpoint 3 is used.
The ioctl() - no matter what type - returns the number of bytes sent. Now comes the usual check:
If this is not the entire blocksize (MSG_SIZE bytes), an error message is issued on the standard error channel [warning "Wrote YY bytes (expected 64)"].
If DEBUG_USB_SEND is set during compilation, the number of bytes sent and their representation are logged to the error channel.
Definition at line 68 of file usb_linux.c.
References ckb_err_fn, ckb_warn_fn, usbdevice::epcount, usbdevice::fwversion, usbdevice::handle, IS_V2_OVERRIDE, and MSG_SIZE.
Referenced by _usbrecv(), and _usbsend().
const char* product_str | ( | short | product | ) |
product | is the short USB device product ID |
product_str returns a condensed view on what type of device we have.
At present, various models and their properties are known from corsair products. Some models differ in principle (mice and keyboards), others differ in the way they function (for example, RGB and non RGB), but they are very similar.
Here, only the first point is taken into consideration and we return a unified model string. If the model is not known with its number, product_str returns an empty string.
The model numbers and corresponding strings wwith the numbers in hex-string are defined in usb.h
At present, this function is used to initialize kb->name
and to give information in debug strings.
Definition at line 70 of file usb.c.
References P_GLAIVE, P_HARPOON, P_K63_NRGB, P_K65, P_K65_LUX, P_K65_NRGB, P_K65_RFIRE, P_K68, P_K70, P_K70_LUX, P_K70_LUX_NRGB, P_K70_NRGB, P_K70_RFIRE, P_K70_RFIRE_NRGB, P_K95, P_K95_NRGB, P_K95_PLATINUM, P_M65, P_M65_PRO, P_SABRE_L, P_SABRE_N, P_SABRE_O, P_SABRE_O2, P_SCIMITAR, P_SCIMITAR_PRO, P_STRAFE, P_STRAFE_NRGB, and P_STRAFE_NRGB_2.
Referenced by _mkdevpath(), and _setupusb().
int revertusb | ( | usbdevice * | kb | ) |
kb | THE usbdevice* |
revertusb sets a given device to inactive (hardware controlled) mode if not a fw-ugrade is indicated
First is checked, whether a firmware-upgrade is indicated for the device. If so, revertusb() returns 0.
Anyway, the following steps are similar to some other procs, dealing with low level usb handling:
Definition at line 417 of file usb.c.
References FEAT_RGB, HAS_FEATURES, NEEDS_FW_UPDATE, NK95_HWON, nk95cmd, and setactive.
Referenced by quitWithLock().
void setupusb | ( | usbdevice * | kb | ) |
kb | THE usbdevice* used everywhere |
OUT] | kb->thread is used to store the thread ID of the fresh created thread. |
setupusb starts a thread with kb as parameter and _setupusb() as entrypoint.
Set up a USB device after its handle is open. Spawns a new thread _setupusb() with standard parameter kb. dmutex must be locked prior to calling this function. The function will unlock it when finished. In kb->thread the thread id is mentioned, because closeusb() needs this info for joining that thread again.
Definition at line 396 of file usb.c.
References _setupusb(), ckb_err, imutex, and usbdevice::thread.
Referenced by usbadd().
int usb_tryreset | ( | usbdevice * | kb | ) |
[in,out] | kb | THE usbdevice* |
[in] | reset_stop | global variable is read |
usb_tryreset does what the name means: Try to reset the usb via resetusb()
This function is called if an usb command ran into an error in case of one of the following two situations:
In an endless loop usb_tryreset() tries to reset the given usb device via the macro resetusb().
This macro calls _resetusb() with debugging information.
_resetusb() sends a command via the operating system dependent function os_resetusb() and - if successful - reinitializes the device. os_resetusb() returns -2 to indicate a broken device and all structures should be removed for it.
In that case, the loop is terminated, an error message is produced and usb_tryreset() returns -1.
In case resetusb() has success, the endless loop is left via a return 0 (success).
If the return value from resetusb() is -1, the loop is continued with the next try.
If the global variable reset_stop is set directly when the function is called or after each try, usb_tryreset() stops working and returns -1.
Definition at line 475 of file usb.c.
References ckb_err, ckb_info, reset_stop, and resetusb.
Referenced by _setupusb(), cmd_fwupdate(), os_sendindicators(), and os_setupusb().
void usbkill | ( | ) |
Definition at line 853 of file usb_linux.c.
Referenced by quitWithLock().
int usbmain | ( | ) |
Start the USB main loop. Returns program exit code when finished.
usbmain is called by main() after setting up all other stuff.
First check whether the uinput module is loaded by the kernel.
Create the udev object with udev_new() (is a function from libudev.h) terminate -1 if error
Enumerate all currently connected devices
Definition at line 793 of file usb_linux.c.
References ckb_fatal, ckb_warn, udev_enum(), usb_add_device(), and usb_rm_device().
Referenced by main().
const char* vendor_str | ( | short | vendor | ) |
uncomment to see USB packets received from the device vendor_str Vendor/product string representations
vendor | short vendor ID |
uncomment to see USB packets sent to the device
vendor_str returns "corsair" if the given vendor argument is equal to V_CORSAIR (0x1bc) else it returns ""
Definition at line 43 of file usb.c.
References V_CORSAIR.
Referenced by _mkdevpath(), and _setupusb().