passing arguments to drivers probe function - linux-kernel
In the call chain of module_i2c_driver() i am not able to find that where arguments are passed to the function adxl34x_i2c_probe().
static int adxl34x_i2c_probe(struct i2c_client *client,
78 const struct i2c_device_id *id)
79 {
...
99 return 0;
100 }
158 static struct i2c_driver adxl34x_driver = {
159 .driver = {
160 .name = "adxl34x",
161 .owner = THIS_MODULE,
162 .pm = &adxl34x_i2c_pm,
163 .of_match_table = of_match_ptr(adxl34x_of_id),
164 },
165 .probe = adxl34x_i2c_probe,
166 .remove = adxl34x_i2c_remove,
167 .id_table = adxl34x_id,
168 };
169
170 module_i2c_driver(adxl34x_driver);
i2c_driver's probe callback is called from i2c_device_probe function (http://lxr.free-electrons.com/source/drivers/i2c/i2c-core.c#L632).
With
.probe = adxl34x_i2c_probe
you're setting callback function pointer of probe to point to adx134x_i2c_probe, so calling driver->probe (http://lxr.free-electrons.com/source/drivers/i2c/i2c-core.c#L672) with passed arguments is actually calling adxl34x_i2c_probe with the same arguments.
Related
undefined error with calling ble_gatts_count_cfg function
I am programing my esp32 to be able to advertise my custom services/characteristics. I am failry new to esp idf and I am struggling to program bluetooth using nimBLE. during building,there is no error thrown but while monitoring, i receive the following error from the function in main: I (391) heap_init: At 3FFB6388 len 00001C78 (7 KiB): DRAM I (397) heap_init: At 3FFB9A20 len 00004108 (16 KiB): DRAM I (403) heap_init: At 3FFC49F0 len 0001B610 (109 KiB): DRAM I (409) heap_init: At 3FFE0440 len 00003AE0 (14 KiB): D/IRAM I (415) heap_init: At 3FFE4350 len 0001BCB0 (111 KiB): D/IRAM I (422) heap_init: At 40096DB0 len 00009250 (36 KiB): IRAM I (429) spi_flash: detected chip: generic I (433) spi_flash: flash io: dio I (438) cpu_start: Starting scheduler on PRO CPU. I (0) cpu_start: Starting scheduler on APP CPU. I (484) BTDM_INIT: BT controller compile version [1342a48] I (484) system_api: Base MAC address is not set I (484) system_api: read default base MAC address from EFUSE I (494) phy_init: phy_version 4670,719f9f6,Feb 18 2021,17:07:07 ESP_ERROR_CHECK failed: esp_err_t 0x3 (ERROR) at 0x4008e6f4 0x4008e6f4: _esp_error_check_failed at C:/Users/Kanimba/Desktop/esp-idf/components/esp_common/src/esp_err.c:41 file: "../main/main.c" line 35 func: app_main expression: gatt_svrs_init() abort() was called at PC 0x4008e6f7 on core 0 0x4008e6f7: _esp_error_check_failed at C:/Users/Kanimba/Desktop/esp-idf/components/esp_common/src/esp_err.c:42 Backtrace:0x4008f64b:0x3ffbc340 0x4008fe1d:0x3ffbc360 0x400951f2:0x3ffbc380 0x4008e6f7:0x3ffbc3f0 0x400d5a86:0x3ffbc410 0x401205ed:0x3ffbc430 0x40092e45:0x3ffbc450 0x4008f64b: panic_abort at C:/Users/Kanimba/Desktop/esp-idf/components/esp_system/panic.c:356 0x4008fe1d: esp_system_abort at C:/Users/Kanimba/Desktop/esp-idf/components/esp_system/system_api.c:112 0x400951f2: abort at C:/Users/Kanimba/Desktop/esp-idf/components/newlib/abort.c:46 0x4008e6f7: _esp_error_check_failed at C:/Users/Kanimba/Desktop/esp-idf/components/esp_common/src/esp_err.c:42 0x400d5a86: app_main at C:\Users\Kanimba\Desktop\work_project\esp\embedded-test-ble\build/../main/main.c:35 (discriminator 1) 0x401205ed: main_task at C:/Users/Kanimba/Desktop/esp-idf/components/freertos/port/port_common.c:133 (discriminator 2) 0x40092e45: vPortTaskWrapper at C:/Users/Kanimba/Desktop/esp-idf/components/freertos/port/xtensa/port.c:168 whereby gatt_svrs_init() is called to initializes the following; int gatt_svrs_init(void) { int rc; ble_svc_gap_init(); ble_svc_gatt_init(); rc = ble_gatts_count_cfg(gatt_svsc); if (rc != 0) { return rc; } rc = ble_gatts_add_svcs(gatt_svsc); if (rc != 0) { return rc; } return 0; } my main,c file looks like this #include "config.h" #include "gatt_svr.h" #include "esp_log.h" #include "esp_nimble_hci.h" #include "freertos/FreeRTOS.h" #include "freertos/task.h" #include "nvs_flash.h" void app_main() { int rc; /* initalise non-valatile storage NVS*/ esp_err_t ret = nvs_flash_init(); if (ret == ESP_ERR_NVS_NO_FREE_PAGES || ret == ESP_ERR_NVS_NEW_VERSION_FOUND) { ESP_ERROR_CHECK(nvs_flash_erase()); ret = nvs_flash_init(); } ESP_ERROR_CHECK(ret); /* initialise nimble */ ESP_ERROR_CHECK(esp_nimble_hci_and_controller_init()); /* initialise apache port to nimble */ nimble_port_init(); /*Initialize the NimBLE host configuration */ ble_hs_cfg.reset_cb = ble_on_reset; ble_hs_cfg.sync_cb = ble_on_sync; ble_hs_cfg.gatts_register_cb = gatt_svr_register_cb; ble_hs_cfg.store_status_cb = ble_store_util_status_rr; // said to not be useful, need to do more, ESP_ERROR_CHECK(gatt_svrs_init()); // assert(rc == 0); /*set the default device name*/ ESP_ERROR_CHECK(ble_svc_gap_device_name_set(DEVICE_NAME)); // storing configuration "quite not sure how this function works" ble_store_config_init(); nimble_port_freertos_init(host_task); } and the structure of the service: static const struct ble_gatt_svc_def gatt_svsc[] = { {/* Device info service/ SIG */ .type = BLE_GATT_SVC_TYPE_PRIMARY, .uuid = BLE_UUID16_DECLARE(DEVICE_INFO_SERVICE), .characteristics = (struct ble_gatt_chr_def[]){ {/* manufacturer name characteristic */ .uuid = BLE_UUID16_DECLARE(MANUFACTURER_NAME), .flags = BLE_GATT_CHR_F_READ, .access_cb = gatt_svr_access_device_info}, {/*serial number characteristic */ .uuid = BLE_UUID16_DECLARE(DEVICE_SERIAL_NUMBER), .flags = BLE_GATT_CHR_F_READ, .access_cb = gatt_svr_access_device_info}, {/*software version characteristic */ .uuid = BLE_UUID16_DECLARE(SOFTWARE_VERSION), .flags = BLE_GATT_CHR_F_READ | BLE_GATT_CHR_F_READ_ENC, .access_cb = gatt_svr_access_device_info}, {0}}}, {.type = BLE_GATT_SVC_TYPE_PRIMARY, .uuid = &DEVICE_STATE_SERVICE.u, .characteristics = (struct ble_gatt_chr_def[]){{ /* manufacturer name characteristic */ .uuid = &CURRENT_SPECTRUM.u, .flags = BLE_GATT_CHR_F_READ, }, { /* manufacturer name characteristic */ .uuid = &DEVICE_TEMPERATURE.u, .flags = BLE_GATT_CHR_F_READ, }, { /* manufacturer name characteristic */ .uuid = &CURRENT_INTESITY.u, .flags = BLE_GATT_CHR_F_READ, }, {0}}}, {.type = BLE_GATT_SVC_TYPE_PRIMARY, .uuid = &MANUAL_SERVICE.u, .characteristics = (struct ble_gatt_chr_def[]){{ /* manula spectrum characteristic */ .uuid = &MANUAL_SPECTRUM.u, .flags = BLE_GATT_CHR_F_READ, }, { /* light intensity characteristic */ .uuid = &LIGHT_INTESITY.u, .flags = BLE_GATT_CHR_F_READ, }, { /* manual power characteristic */ .uuid = &MANUAL_POWER.u, .flags = BLE_GATT_CHR_F_READ, }, {0}}}, {.type = BLE_GATT_SVC_TYPE_PRIMARY, .uuid = &SCHEDULER_SERVICE.u, .characteristics = (struct ble_gatt_chr_def[]){{ /* Start_stage characteristic */ .uuid = &STAGE_START.u, .flags = BLE_GATT_CHR_F_WRITE, }, { /* start day hours characteristic */ .uuid = &DAY_START_HOURS.u, .flags = BLE_GATT_CHR_F_WRITE, }, { /* manufacturer name characteristic */ .uuid = &DAY_END_HOURS.u, .flags = BLE_GATT_CHR_F_WRITE, }, { /* Light intensity characteristic */ .uuid = &LIGHT_INTESITY.u, .flags = BLE_GATT_CHR_F_WRITE, }, {0}}}, {0}};
I think there should be a access_cb associated for a characteristic which has a read or write flag . Can you try adding a access_cb to the characteristic with UUID SCHEDULER_SERVICE , MANUAL_SERVICE and DEVICE_STATE_SERVICE to see if it helps.
Get Driver Locked memory programmatically
How can I get Driver Locked memory programmatically? WMI, WinApi anyway?
really not hard debug RAMMap[64].exe and view how it get this results. note - all used structures and api classes here undocumented. so as is. all data types declared in processhacker project. i will be use it as is : #include <phnt.h> also in ntmmapi.h we can view next constants: #define MMPFNUSE_PROCESSPRIVATE 0 #define MMPFNUSE_FILE 1 #define MMPFNUSE_PAGEFILEMAPPED 2 #define MMPFNUSE_PAGETABLE 3 #define MMPFNUSE_PAGEDPOOL 4 #define MMPFNUSE_NONPAGEDPOOL 5 #define MMPFNUSE_SYSTEMPTE 6 #define MMPFNUSE_SESSIONPRIVATE 7 #define MMPFNUSE_METAFILE 8 #define MMPFNUSE_AWEPAGE 9 #define MMPFNUSE_DRIVERLOCKPAGE 10 #define MMPFNUSE_KERNELSTACK 11 if compare it with screenshot - visible match. tool first query physical memory ranges (displayed in 5 tab ) via (SystemSuperfetchInformation, SuperfetchMemoryRangesQuery) and than for every page (range) do query SuperfetchPfnQuery. minimal code can look like: NTSTATUS Rammap(PF_PHYSICAL_MEMORY_RANGE_INFO* ppmri, ULONGLONG Use[16], DWORD dwPageSize) { if (ULONG RangeCount = ppmri->RangeCount) { WCHAR kb[64]; ULONG_PTR TotalSize = 0; PF_PHYSICAL_MEMORY_RANGE* Range = ppmri->Ranges; PF_PFN_PRIO_REQUEST pprr = { PF_PFN_PRIO_REQUEST_VERSION }; SUPERFETCH_INFORMATION spi = { SUPERFETCH_INFORMATION_VERSION, SUPERFETCH_INFORMATION_MAGIC, SuperfetchPfnQuery, &pprr, sizeof(pprr) }; do { if (ULONG_PTR PageCount = Range->PageCount) { ULONG_PTR PfnCount; ULONG_PTR BasePfn = Range->BasePfn; ULONG_PTR Start = BasePfn * dwPageSize, Size = PageCount * dwPageSize, End = Start + Size; TotalSize += Size; StrFormatKBSize(Size, kb, RTL_NUMBER_OF(kb)); DbgPrint("0x%016I64x\t0x%016I64x\t%S\n", Start, End, kb); do { pprr.PfnCount = PfnCount = min(PageCount, RTL_NUMBER_OF(pprr.PageData)); MMPFN_IDENTITY* PageData = pprr.PageData; do { PageData++->PageFrameIndex = BasePfn++; } while (--PfnCount); ULONG cb; NTSTATUS status = NtQuerySystemInformation(SystemSuperfetchInformation, &spi, sizeof(spi), &cb); if (0 <= status) { PageData = pprr.PageData; PfnCount = pprr.PfnCount; do { Use[PageData++->u1.e1.UseDescription]++; } while (--PfnCount); } else { return status; } } while (PageCount -= pprr.PfnCount); } } while (Range++, --RangeCount); StrFormatKBSize(TotalSize, kb, RTL_NUMBER_OF(kb)); DbgPrint("-------------\nTotalSize: %S\n", kb); } return STATUS_SUCCESS; } NTSTATUS Rammap(ULONGLONG Use[16], DWORD dwPageSize) { BOOLEAN b; NTSTATUS status = RtlAdjustPrivilege(SE_PROF_SINGLE_PROCESS_PRIVILEGE, TRUE, FALSE, &b); if (0 <= status) { SUPERFETCH_INFORMATION spi = { SUPERFETCH_INFORMATION_VERSION, SUPERFETCH_INFORMATION_MAGIC, SuperfetchMemoryRangesQuery }; ULONG rcb = sizeof(PF_PHYSICAL_MEMORY_RANGE_INFO); static volatile UCHAR guz = 0; PVOID stack = alloca(guz); PF_PHYSICAL_MEMORY_RANGE_INFO* ppmri = 0; do { if (spi.Length < rcb) { spi.Length = RtlPointerToOffset(spi.Data = alloca(rcb - spi.Length), stack); ppmri = (PF_PHYSICAL_MEMORY_RANGE_INFO*)spi.Data; ppmri->Version = PF_PHYSICAL_MEMORY_RANGE_INFO_VERSION; } if (0 <= (status = NtQuerySystemInformation(SystemSuperfetchInformation, &spi, sizeof(spi), &rcb))) { status = Rammap(ppmri, Use, dwPageSize); break; } } while (status == STATUS_BUFFER_TOO_SMALL); } return status; } void Rammap() { SYSTEM_INFO sbi; GetSystemInfo(&sbi); ULONGLONG Use[16]={}; if (0 <= Rammap(Use, sbi.dwPageSize)) { WCHAR sz[16], kb[32]; PCWSTR Name; ULONG n = MMPFNUSE_KERNELSTACK; do { ULONGLONG u = Use[n]; switch (n) { case MMPFNUSE_PROCESSPRIVATE: Name = L"Process Private"; break; case MMPFNUSE_FILE: Name = L"Mapped File"; break; case MMPFNUSE_PAGEFILEMAPPED: Name = L"Shareable"; break; case MMPFNUSE_PAGETABLE: Name = L"Page Tabe"; break; case MMPFNUSE_PAGEDPOOL: Name = L"Page Pool"; break; case MMPFNUSE_NONPAGEDPOOL: Name = L"NonPaged Pool"; break; case MMPFNUSE_SYSTEMPTE: Name = L"System PTE"; break; case MMPFNUSE_SESSIONPRIVATE: Name = L"Session Private"; break; case MMPFNUSE_METAFILE: Name = L"Metafile"; break; case MMPFNUSE_AWEPAGE: Name = L"AWE"; break; case MMPFNUSE_DRIVERLOCKPAGE: Name = L"DriverLocked"; break; case MMPFNUSE_KERNELSTACK: Name = L"KernelStack"; break; default: swprintf(sz, L"[%x]", n); Name = sz; } StrFormatKBSize(u * sbi.dwPageSize, kb, RTL_NUMBER_OF(kb)); DbgPrint("%16S %S\n", Name, kb); } while (n--); } } for self system i got 0x0000000000001000 0x0000000000058000 348 KB 0x0000000000059000 0x000000000009f000 280 KB 0x0000000000100000 0x000000008122c000 2,114,736 KB 0x000000008122e000 0x000000008a2d1000 148,108 KB 0x000000008a60a000 0x000000008a772000 1,440 KB 0x000000008b3ff000 0x000000008b400000 4 KB 0x0000000100000000 0x000000046f000000 14,401,536 KB ------------- TotalSize: 16,666,452 KB KernelStack 24,400 KB DriverLocked 13,768 KB AWE 0 KB Metafile 667,932 KB Session Private 24,048 KB System PTE 50,332 KB NonPaged Pool 323,104 KB Page Pool 314,032 KB Page Tabe 69,020 KB Shareable 243,288 KB Mapped File 4,391,092 KB Process Private 10,545,436 KB
request_mem_region fails on Raspberry Pi
The call to request_mem_region is failing (returns null). I would say that the memory region I'm trying to access (GPIO starting at 0x3f20000) is being used. I removed (rmmod) the module bcm28795_gpio but the request is still failing. The modules I have loaded are (lsmod): Module Size Used by cfg80211 427817 0 rfkill 16018 1 cfg80211 snd_bcm2835 20511 0 snd_pcm 75890 1 snd_bcm2835 snd_timer 19160 1 snd_pcm snd 51908 3 snd_bcm2835,snd_timer,snd_pcm bcm2835_wdt 3225 0 uio_pdrv_genirq 3164 0 uio 8000 1 uio_pdrv_genirq i2c_dev 5859 0 ipv6 347473 30` cat /proc/iomem is returning the following: 00000000-3affffff : System RAM 00008000-007e7483 : Kernel code 00860000-0098e1ab : Kernel data 3f006000-3f006fff : dwc_otg 3f007000-3f007eff : /soc/dma#7e007000 3f00b840-3f00b84e : /soc/vchiq 3f00b880-3f00b8bf : /soc/mailbox#7e00b800 3f200000-3f2000b3 : /soc/gpio#7e200000 3f201000-3f201fff : /soc/uart#7e201000 3f201000-3f201fff : /soc/uart#7e201000 3f202000-3f2020ff : /soc/sdhost#7e202000 3f980000-3f98ffff : dwc_otg` I think this issue is related to the Device Tree, but I'm not sure what do next. The driver code: #include <linux/module.h> #include <linux/init.h> #include <linux/fs.h> #include <linux/errno.h> #include <linux/io.h> #include <linux/platform_device.h> #include <linux/miscdevice.h> #include <linux/of.h> #include <linux/of_address.h> #define DRIVER_NAME "tsgpio" struct tsgpio_dev { struct resource res; void __iomem *virtbase; } dev; static const struct file_operations tsgpio_fops = { .owner = THIS_MODULE, }; static struct miscdevice tsgpio_misc_device = { .minor = MISC_DYNAMIC_MINOR, .name = DRIVER_NAME, .fops = &tsgpio_fops, }; static const struct of_device_id tsgpio_of_match[] = { { .compatible = "brcm,bcm2835-gpiomem" }, {}, }; MODULE_DEVICE_TABLE(of, tsgpio_of_match); int __init tsgpio_probe(struct platform_device *pdev) { int ret; ret = misc_register(&tsgpio_misc_device); if (ret) return ENODEV; // Find address range in device tree ret = of_address_to_resource(pdev->dev.of_node, 0, &dev.res); if (ret) { ret = ENOENT; goto out_deregister; } // Request access to memory if (request_mem_region(dev.res.start, resource_size(&dev.res), DRIVER_NAME) == NULL) { ret = EBUSY; goto out_deregister; } /* Arrange access to our registers (calls ioremap) */ dev.virtbase = of_iomap(pdev->dev.of_node, 0); if (dev.virtbase == NULL) { ret = ENOMEM; goto out_release_mem_region; } return 0; out_release_mem_region: release_mem_region(dev.res.start, resource_size(&dev.res)); out_deregister: misc_deregister(&tsgpio_misc_device); return ret; } int tsgpio_remove(struct platform_device *pdev) { iounmap(dev.virtbase); release_mem_region(dev.res.start, resource_size(&dev.res)); misc_deregister(&tsgpio_misc_device); return 0; } static struct platform_driver tsgpio_driver = { .driver = { .name = DRIVER_NAME, .owner = THIS_MODULE, .of_match_table = of_match_ptr(tsgpio_of_match), }, .remove = __exit_p(tsgpio_remove), }; static int __init tsgpio_init(void) { return platform_driver_probe(&tsgpio_driver, tsgpio_probe); } static void __exit tsgpio_exit(void) { platform_driver_unregister(&tsgpio_driver); } module_init(tsgpio_init); module_exit(tsgpio_exit); MODULE_LICENSE("GPL"); MODULE_AUTHOR("Emanuel Oliveira"); Output from dmesg: [ 1745.126636] tsgpio: init [ 1745.130025] tsgpio: probe of 3f200000.gpiomem failed with error 16 Thank you!
Why this proc driver crashes?
I am trying to write a proc driver that will print the driver history up till 10 last updates. In this driver, I haven't added the kernel data structure that I want to print. But, I am relying on the 'i' value to print the value up till 10. Here is my code. #include <linux/init.h> #include <linux/module.h> /** needed by all modules **/ #include <linux/kernel.h> /** This is for KERN_ALERT **/ #include <linux/proc_fs.h> /** This is for procfs **/ #include <linux/seq_file.h> #include <linux/cdev.h> /** character device **/ #include <linux/device.h> /** for sys device registration in /dev/ and /sys/class **/ /** For class registration to work, you need GPL license **/ MODULE_LICENSE("GPL"); #define PROCFS_NAME "basicProcfs1" static struct cdev basicCdev; static struct class *basicDriverClass; struct proc_dir_entry *procFileEntry = NULL; static int basicMajorNumber = 0; #define NUMBER_OF_MINOR_DEVICE (0) #define NUM_MSG_HIST_ENTRIES (10) static int gui32CmdMsgHistoryStartIndex=0; /** This File operation table for proc file system **/ static int av_cmd_hist_show( struct seq_file *filp, void *v ) { int i = *((int *)v); printk("the av_cmd_hist_show called\r\n"); if ( i == 0) { seq_printf(filp, "Sequential print for debugging-- called for i-times i.e. 10 times \r\n"); } seq_printf(filp, "Hello SJ proc! %d\r\n", i); return 0; } static void av_cmd_hist_stop( struct seq_file *filp, void *v ) { printk("av_cmd_hist_stop called..\r\n"); } /* av_cmd_hist_stop */ static void *av_cmd_hist_next( struct seq_file *filp, void *v, loff_t *pos ) { (*pos)++; printk("av_cmd_hist_next called..\r\n"); return( ( *pos < NUM_MSG_HIST_ENTRIES ) ? pos : NULL ); } /* av_cmd_hist_next */ static void *av_cmd_hist_start( struct seq_file *filp, loff_t *pos ) { if( *pos == 0 ) { printk("av_cmd_hist_start.. Initial..\r\n"); gui32CmdMsgHistoryStartIndex = 5; } printk("av_cmd_hist_start.. the *pos=0..\r\n"); return( ( *pos < NUM_MSG_HIST_ENTRIES ) ? pos : NULL ); } /* av_cmd_hist_start */ static struct seq_operations av_seq_cmd_hist_fops = { .start = av_cmd_hist_start, .next = av_cmd_hist_next, .stop = av_cmd_hist_stop, .show = av_cmd_hist_show }; static int basicProcShow(struct seq_file *m, void *v) { seq_printf(m, "Hello SJ proc!\n"); return 0; } static int basicProcOpen(struct inode *inode, struct file *file) { int i; i = seq_open( file, &av_seq_cmd_hist_fops ); return i; //return single_open(file, basicProcShow, NULL); } /** Put data into the proc fs file **/ static const struct file_operations basic_proc_fops = { .owner = THIS_MODULE, .open = basicProcOpen, .read = seq_read, .llseek = seq_lseek, .release = single_release, }; static struct file_operations fops = { .read = NULL, .write = NULL, .open = NULL, .release = NULL }; static void setup_cdev(struct cdev *dev, int minor, struct file_operations *fops) { int err = -1; /** MKDEV call creates a device number i.e. combination of major and minor number **/ int devno = MKDEV(basicMajorNumber, minor); /** Initiliaze character dev with fops **/ cdev_init(dev, fops); /**owner and operations initialized **/ dev->owner = THIS_MODULE; dev->ops = fops; /** add the character device to the system**/ /** Here 1 means only 1 minor number, you can give 2 for 2 minor device, the last param is the count of minor number enrolled **/ err = cdev_add (dev, devno, 1); if (err) { printk (KERN_NOTICE "Couldn't add cdev"); } } static int chrDriverInit(void) { int result; dev_t dev; printk("Welcome!! Device Init now.."); /** int alloc_chrdev_region(dev_t *dev, unsigned int firstminor,unsigned int count, char *name); **/ /** dev -> The dev_t variable type,which will get the major number that the kernel allocates. **/ /**The same name will appear in /proc/devices. **/ /** it is registering the character device **/ /** a major number will be dynamically allocated here **/ /** alloc_chrdev_region(&dev_num, FIRST_MINOR, COUNT, DEVICE_NAME); **/ result = alloc_chrdev_region(&dev, 0, NUMBER_OF_MINOR_DEVICE, "pSeudoDrv1"); if( result < 0 ) { printk("Error in allocating device"); return -1; } /** From these two if's we are avoiding the manual mknod command to create the /dev/<driver> **/ /** creating class, and then device created removes the dependency of calling mknod **/ /** A good method - the mknod way is depreciated **/ /** mknod way is - mknod /dev/<driver_name> c <majorNumber> <minorNumber> /** add the driver to /sys/class/chardrv **/ if ((basicDriverClass = class_create(THIS_MODULE, "chardrv")) == NULL) //$ls /sys/class { unregister_chrdev_region(dev, 1); return -1; } /** add the driver to /dev/pSeudoDrv -- here **/ if (device_create(basicDriverClass, NULL, dev, NULL, "pSeudoDrv") == NULL) //$ls /dev/ { class_destroy(basicDriverClass); unregister_chrdev_region(dev, 1); return -1; } /** let's see what major number was assigned by the Kernel **/ basicMajorNumber = MAJOR(dev); printk("Kernel assigned major number is %d ..\r\n",basicMajorNumber ); /** Now setup the cdev **/ setup_cdev(&basicCdev,NUMBER_OF_MINOR_DEVICE, &fops); /** Setup Proc Entry here **/ /** 0644 means - * 0 - owning (user) : read and write - 110 * Group - only read - 100 * Other - only read - 100 **/ procFileEntry = proc_create(PROCFS_NAME, 0, NULL, &basic_proc_fops); if ( procFileEntry == NULL) { remove_proc_entry(PROCFS_NAME, NULL); } return 0; } static void chrDriverExit(void) { /** A reverse - destroy mechansim -- the way it was created **/ printk("Releasing Simple Devs -- %s\r\n", __FUNCTION__); /** delete the character driver added **/ cdev_del(&basicCdev); /** destroy the device created **/ device_destroy(basicDriverClass, MKDEV(basicMajorNumber, 0)); /** destroy the class created **/ class_destroy(basicDriverClass); /** unregister the chr dev **/ unregister_chrdev(basicMajorNumber, NUMBER_OF_MINOR_DEVICE); remove_proc_entry(PROCFS_NAME, NULL); } module_init(chrDriverInit); module_exit(chrDriverExit); The dmesg logs are the following. # dmesg [14102.921743] Releasing Simple Devs -- chrDriverExit [14163.285107] Welcome!! Device Init now..Kernel assigned major number is 244 .. [14174.979098] av_cmd_hist_start.. Initial.. [14174.979103] av_cmd_hist_start.. the *pos=0.. [14174.979104] the av_cmd_hist_show called [14174.979107] av_cmd_hist_next called.. [14174.979108] the av_cmd_hist_show called [14174.979109] av_cmd_hist_next called.. [14174.979110] the av_cmd_hist_show called [14174.979112] av_cmd_hist_next called.. [14174.979113] the av_cmd_hist_show called [14174.979114] av_cmd_hist_next called.. [14174.979115] the av_cmd_hist_show called [14174.979117] av_cmd_hist_next called.. [14174.979118] the av_cmd_hist_show called [14174.979119] av_cmd_hist_next called.. [14174.979120] the av_cmd_hist_show called [14174.979121] av_cmd_hist_next called.. [14174.979122] the av_cmd_hist_show called [14174.979124] av_cmd_hist_next called.. [14174.979125] the av_cmd_hist_show called [14174.979126] av_cmd_hist_next called.. [14174.979127] the av_cmd_hist_show called [14174.979128] av_cmd_hist_next called.. [14174.979130] av_cmd_hist_stop called.. [14174.979231] av_cmd_hist_start.. the *pos=0.. [14174.979233] av_cmd_hist_stop called.. [14174.979250] ------------[ cut here ]------------ [14174.979252] kernel BUG at mm/slub.c:3483! [14174.979254] invalid opcode: 0000 [#2] SMP [14174.979258] Modules linked in: procfs_driver1(O) procfs_driver(O-) tcp_lp nfsv3 nfsv4 nfs fscache dns_resolver fuse vboxpci(O) vboxnetadp(O) vboxnetflt(O) 8021q garp stp llc binfmt_misc vboxdrv(O) tpm_bios snd_hda_codec_hdmi snd_hda_codec_realtek fglrx(PO) snd_hda_intel snd_hda_codec snd_hwdep snd_seq snd_seq_device snd_pcm iTCO_wdt iTCO_vendor_support r8169 snd_timer mii e1000e snd i2c_i801 lpc_ich i2c_core soundcore snd_page_alloc coretemp kvm_intel kvm serio_raw video dcdbas microcode uinput nfsd lockd nfs_acl auth_rpcgss sunrpc crc32c_intel [last unloaded: procfs_driver1] [14174.979297] Pid: 19055, comm: cat Tainted: P B D C O 3.6.11-4.fc16.i686 #1 Dell Inc. OptiPlex 9010/00F82W [14174.979300] EIP: 0060:[<c0530891>] EFLAGS: 00210246 CPU: 5 The proc output is the following - # cat /proc/basicProcfs1 Sequential print for debugging-- called for i-times i.e. 10 times Hello SJ proc! 0 Hello SJ proc! 1 Hello SJ proc! 2 Hello SJ proc! 3 Hello SJ proc! 4 Hello SJ proc! 5 Hello SJ proc! 6 Hello SJ proc! 7 Hello SJ proc! 8 Hello SJ proc! 9 Segmentation fault
Sorry, I got the fix. Erroneous code static const struct file_operations basic_proc_fops = { .owner = THIS_MODULE, .open = basicProcOpen, .read = seq_read, .llseek = seq_lseek, .release = single_release, }; Right code- static const struct file_operations basic_proc_fops = { .owner = THIS_MODULE, .open = basicProcOpen, .read = seq_read, .llseek = seq_lseek, .release = seq_release, }; I would appreciate, if someone can explain why it makes the difference.
It is crashing becasue of this return( ( *pos < NUM_MSG_HIST_ENTRIES ) ? pos : NULL );
(I do not have enough reputation to comment, so adding it as an answer) Regarding your question on why seq_release and not single_release, 'release' functions should compliment 'open' functions. Your open function here 'basicProcOpen' calls 'seq_open' so you should be calling seq_release. If you look at single_release, in addition to seq_release, there is a kfree(op) which causes your crash. 623 int single_release(struct inode *inode, struct file *file) 624 { 625 const struct seq_operations *op = ((struct seq_file *)file->private_data)->op; 626 int res = seq_release(inode, file); 627 kfree(op); 628 return res; 629 } 630 EXPORT_SYMBOL(single_release);
Storing Latin Characters through Linq 2 SQL on WP7
I am using SQL CE database in WP7. I have a table with nvarchar column. When I insert entity through linq, I see symbol � stored for latin characters. Database Connection String: "Data Source=test.sdf;Locale Identifier=1035" Expected to be stored: Tuulispäät As seen through SSMS: Tuulisp��t I tried to set the culture of thread but issue still persists. When I executed insert SQL statement from SSMS, it gets inserted as expected. So why is it an issue when inserted with Linq2SQL? Can someone throw light on what am I missing? Any workarounds or pointers?
You just need to convert your data to UTF8 Encoding. Use this class for conversion on wp7. using System; using System.Collections.Generic; using System.Linq; using System.Text; public class ISO88591Encoding : Encoding { /// <summary> /// Gets the name registered with the /// Internet Assigned Numbers Authority (IANA) for the current encoding. /// </summary> /// <returns> /// The IANA name for the current <see cref="System.Text.Encoding"/>. /// </returns> public override string WebName { get { return "iso-8859-1"; } } private char? fallbackCharacter; /// <summary> /// A character that can be set in order to make the encoding class /// more fault tolerant. If this property is set, the encoding class will /// use this property instead of throwing an exception if an unsupported /// byte value is being passed for decoding. /// </summary> public char? FallbackCharacter { get { return fallbackCharacter; } set { fallbackCharacter = value; if (value.HasValue && !charToByte.ContainsKey(value.Value)) { string msg = "Cannot use the character [{0}] (int value {1}) as fallback value " + "- the fallback character itself is not supported by the encoding."; msg = String.Format(msg, value.Value, (int)value.Value); throw new EncoderFallbackException(msg); } FallbackByte = value.HasValue ? charToByte[value.Value] : (byte?)null; } } /// <summary> /// A byte value that corresponds to the <see cref="FallbackCharacter"/>. /// It is used in encoding scenarios in case an unsupported character is /// being passed for encoding. /// </summary> public byte? FallbackByte { get; private set; } public ISO88591Encoding() { FallbackCharacter = '?'; } /// <summary> /// Encodes a set of characters from the specified character array into the specified byte array. /// </summary> /// <returns> /// The actual number of bytes written into <paramref name="bytes"/>. /// </returns> /// <param name="chars">The character array containing the set of characters to encode. /// </param><param name="charIndex">The index of the first character to encode. /// </param><param name="charCount">The number of characters to encode. /// </param><param name="bytes">The byte array to contain the resulting sequence of bytes. /// </param><param name="byteIndex">The index at which to start writing the resulting sequence of bytes. /// </param> public override int GetBytes(char[] chars, int charIndex, int charCount, byte[] bytes, int byteIndex) { return FallbackByte.HasValue ? GetBytesWithFallBack(chars, charIndex, charCount, bytes, byteIndex) : GetBytesWithoutFallback(chars, charIndex, charCount, bytes, byteIndex); } private int GetBytesWithFallBack(char[] chars, int charIndex, int charCount, byte[] bytes, int byteIndex) { for (int i = 0; i < charCount; i++) { var character = chars[i + charIndex]; byte byteValue; bool status = charToByte.TryGetValue(character, out byteValue); bytes[byteIndex + i] = status ? byteValue : FallbackByte.Value; } return charCount; } private int GetBytesWithoutFallback(char[] chars, int charIndex, int charCount, byte[] bytes, int byteIndex) { for (int i = 0; i < charCount; i++) { var character = chars[i + charIndex]; byte byteValue; bool status = charToByte.TryGetValue(character, out byteValue); if (!status) { //throw exception string msg = "The encoding [{0}] cannot encode the character [{1}] (int value {2}). Set the FallbackCharacter property in order to suppress this exception and encode a default character instead."; msg = String.Format(msg, WebName, character, (int)character); throw new EncoderFallbackException(msg); } bytes[byteIndex + i] = byteValue; } return charCount; } /// <summary> /// Decodes a sequence of bytes from the specified byte array into the specified character array. /// </summary> /// <returns> /// The actual number of characters written into <paramref name="chars"/>. /// </returns> /// <param name="bytes">The byte array containing the sequence of bytes to decode. /// </param><param name="byteIndex">The index of the first byte to decode. /// </param><param name="byteCount">The number of bytes to decode. /// </param><param name="chars">The character array to contain the resulting set of characters. /// </param><param name="charIndex">The index at which to start writing the resulting set of characters. /// </param> public override int GetChars(byte[] bytes, int byteIndex, int byteCount, char[] chars, int charIndex) { return FallbackCharacter.HasValue ? GetCharsWithFallback(bytes, byteIndex, byteCount, chars, charIndex) : GetCharsWithoutFallback(bytes, byteIndex, byteCount, chars, charIndex); } private int GetCharsWithFallback(byte[] bytes, int byteIndex, int byteCount, char[] chars, int charIndex) { for (int i = 0; i < byteCount; i++) { byte lookupIndex = bytes[i + byteIndex]; //if the byte value is not in our lookup array, fall back to default character char result = lookupIndex >= byteToChar.Length ? FallbackCharacter.Value : byteToChar[lookupIndex]; chars[charIndex + i] = result; } return byteCount; } private int GetCharsWithoutFallback(byte[] bytes, int byteIndex, int byteCount, char[] chars, int charIndex) { for (int i = 0; i < byteCount; i++) { byte lookupIndex = bytes[i + byteIndex]; if (lookupIndex >= byteToChar.Length) { //throw exception string msg = "The encoding [{0}] cannot decode byte value [{1}]. Set the FallbackCharacter property in order to suppress this exception and decode the value as a default character instead."; msg = String.Format(msg, WebName, lookupIndex); throw new EncoderFallbackException(msg); } chars[charIndex + i] = byteToChar[lookupIndex]; } return byteCount; } /// <summary> /// Calculates the number of bytes produced by encoding a set of characters /// from the specified character array. /// </summary> /// <returns> /// The number of bytes produced by encoding the specified characters. This class /// alwas returns the value of <paramref name="count"/>. /// </returns> public override int GetByteCount(char[] chars, int index, int count) { return count; } /// <summary> /// Calculates the number of characters produced by decoding a sequence /// of bytes from the specified byte array. /// </summary> /// <returns> /// The number of characters produced by decoding the specified sequence of bytes. This class /// alwas returns the value of <paramref name="count"/>. /// </returns> public override int GetCharCount(byte[] bytes, int index, int count) { return count; } /// <summary> /// Calculates the maximum number of bytes produced by encoding the specified number of characters. /// </summary> /// <returns> /// The maximum number of bytes produced by encoding the specified number of characters. This /// class alwas returns the value of <paramref name="charCount"/>. /// </returns> /// <param name="charCount">The number of characters to encode. /// </param> public override int GetMaxByteCount(int charCount) { return charCount; } /// <summary> /// Calculates the maximum number of characters produced by decoding the specified number of bytes. /// </summary> /// <returns> /// The maximum number of characters produced by decoding the specified number of bytes. This class /// alwas returns the value of <paramref name="byteCount"/>. /// </returns> /// <param name="byteCount">The number of bytes to decode.</param> public override int GetMaxCharCount(int byteCount) { return byteCount; } /// <summary> /// Gets the number of characters that are supported by this encoding. /// This property returns a maximum value of 256, as the encoding class /// only supports single byte encodings (1 byte == 256 possible values). /// </summary> public static int CharacterCount { get { return byteToChar.Length; } } #region Character Table /// <summary> /// This table contains characters in an array. The index within the /// array corresponds to the encoding's mapping of bytes to characters /// (e.g. if a byte value of 5 is used to encode the character 'x', this /// character will be stored at the array index 5. /// </summary> private static char[] byteToChar = new char[] { (char)0 /* byte 0 */ , (char)1 /* byte 1 */ , (char)2 /* byte 2 */ , (char)3 /* byte 3 */ , (char)4 /* byte 4 */ , (char)5 /* byte 5 */ , (char)6 /* byte 6 */ , (char)7 /* byte 7 */ , (char)8 /* byte 8 */ , (char)9 /* byte 9 */ , (char)10 /* byte 10 */ , (char)11 /* byte 11 */ , (char)12 /* byte 12 */ , (char)13 /* byte 13 */ , (char)14 /* byte 14 */ , (char)15 /* byte 15 */ , (char)16 /* byte 16 */ , (char)17 /* byte 17 */ , (char)18 /* byte 18 */ , (char)19 /* byte 19 */ , (char)20 /* byte 20 */ , (char)21 /* byte 21 */ , (char)22 /* byte 22 */ , (char)23 /* byte 23 */ , (char)24 /* byte 24 */ , (char)25 /* byte 25 */ , (char)26 /* byte 26 */ , (char)27 /* byte 27 */ , (char)28 /* byte 28 */ , (char)29 /* byte 29 */ , (char)30 /* byte 30 */ , (char)31 /* byte 31 */ , (char)32 /* byte 32 */ , (char)33 /* byte 33 */ , (char)34 /* byte 34 */ , (char)35 /* byte 35 */ , (char)36 /* byte 36 */ , (char)37 /* byte 37 */ , (char)38 /* byte 38 */ , (char)39 /* byte 39 */ , (char)40 /* byte 40 */ , (char)41 /* byte 41 */ , (char)42 /* byte 42 */ , (char)43 /* byte 43 */ , (char)44 /* byte 44 */ , (char)45 /* byte 45 */ , (char)46 /* byte 46 */ , (char)47 /* byte 47 */ , (char)48 /* byte 48 */ , (char)49 /* byte 49 */ , (char)50 /* byte 50 */ , (char)51 /* byte 51 */ , (char)52 /* byte 52 */ , (char)53 /* byte 53 */ , (char)54 /* byte 54 */ , (char)55 /* byte 55 */ , (char)56 /* byte 56 */ , (char)57 /* byte 57 */ , (char)58 /* byte 58 */ , (char)59 /* byte 59 */ , (char)60 /* byte 60 */ , (char)61 /* byte 61 */ , (char)62 /* byte 62 */ , (char)63 /* byte 63 */ , (char)64 /* byte 64 */ , (char)65 /* byte 65 */ , (char)66 /* byte 66 */ , (char)67 /* byte 67 */ , (char)68 /* byte 68 */ , (char)69 /* byte 69 */ , (char)70 /* byte 70 */ , (char)71 /* byte 71 */ , (char)72 /* byte 72 */ , (char)73 /* byte 73 */ , (char)74 /* byte 74 */ , (char)75 /* byte 75 */ , (char)76 /* byte 76 */ , (char)77 /* byte 77 */ , (char)78 /* byte 78 */ , (char)79 /* byte 79 */ , (char)80 /* byte 80 */ , (char)81 /* byte 81 */ , (char)82 /* byte 82 */ , (char)83 /* byte 83 */ , (char)84 /* byte 84 */ , (char)85 /* byte 85 */ , (char)86 /* byte 86 */ , (char)87 /* byte 87 */ , (char)88 /* byte 88 */ , (char)89 /* byte 89 */ , (char)90 /* byte 90 */ , (char)91 /* byte 91 */ , (char)92 /* byte 92 */ , (char)93 /* byte 93 */ , (char)94 /* byte 94 */ , (char)95 /* byte 95 */ , (char)96 /* byte 96 */ , (char)97 /* byte 97 */ , (char)98 /* byte 98 */ , (char)99 /* byte 99 */ , (char)100 /* byte 100 */ , (char)101 /* byte 101 */ , (char)102 /* byte 102 */ , (char)103 /* byte 103 */ , (char)104 /* byte 104 */ , (char)105 /* byte 105 */ , (char)106 /* byte 106 */ , (char)107 /* byte 107 */ , (char)108 /* byte 108 */ , (char)109 /* byte 109 */ , (char)110 /* byte 110 */ , (char)111 /* byte 111 */ , (char)112 /* byte 112 */ , (char)113 /* byte 113 */ , (char)114 /* byte 114 */ , (char)115 /* byte 115 */ , (char)116 /* byte 116 */ , (char)117 /* byte 117 */ , (char)118 /* byte 118 */ , (char)119 /* byte 119 */ , (char)120 /* byte 120 */ , (char)121 /* byte 121 */ , (char)122 /* byte 122 */ , (char)123 /* byte 123 */ , (char)124 /* byte 124 */ , (char)125 /* byte 125 */ , (char)126 /* byte 126 */ , (char)127 /* byte 127 */ , (char)128 /* byte 128 */ , (char)129 /* byte 129 */ , (char)130 /* byte 130 */ , (char)131 /* byte 131 */ , (char)132 /* byte 132 */ , (char)133 /* byte 133 */ , (char)134 /* byte 134 */ , (char)135 /* byte 135 */ , (char)136 /* byte 136 */ , (char)137 /* byte 137 */ , (char)138 /* byte 138 */ , (char)139 /* byte 139 */ , (char)140 /* byte 140 */ , (char)141 /* byte 141 */ , (char)142 /* byte 142 */ , (char)143 /* byte 143 */ , (char)144 /* byte 144 */ , (char)145 /* byte 145 */ , (char)146 /* byte 146 */ , (char)147 /* byte 147 */ , (char)148 /* byte 148 */ , (char)149 /* byte 149 */ , (char)150 /* byte 150 */ , (char)151 /* byte 151 */ , (char)152 /* byte 152 */ , (char)153 /* byte 153 */ , (char)154 /* byte 154 */ , (char)155 /* byte 155 */ , (char)156 /* byte 156 */ , (char)157 /* byte 157 */ , (char)158 /* byte 158 */ , (char)159 /* byte 159 */ , (char)160 /* byte 160 */ , (char)161 /* byte 161 */ , (char)162 /* byte 162 */ , (char)163 /* byte 163 */ , (char)164 /* byte 164 */ , (char)165 /* byte 165 */ , (char)166 /* byte 166 */ , (char)167 /* byte 167 */ , (char)168 /* byte 168 */ , (char)169 /* byte 169 */ , (char)170 /* byte 170 */ , (char)171 /* byte 171 */ , (char)172 /* byte 172 */ , (char)173 /* byte 173 */ , (char)174 /* byte 174 */ , (char)175 /* byte 175 */ , (char)176 /* byte 176 */ , (char)177 /* byte 177 */ , (char)178 /* byte 178 */ , (char)179 /* byte 179 */ , (char)180 /* byte 180 */ , (char)181 /* byte 181 */ , (char)182 /* byte 182 */ , (char)183 /* byte 183 */ , (char)184 /* byte 184 */ , (char)185 /* byte 185 */ , (char)186 /* byte 186 */ , (char)187 /* byte 187 */ , (char)188 /* byte 188 */ , (char)189 /* byte 189 */ , (char)190 /* byte 190 */ , (char)191 /* byte 191 */ , (char)192 /* byte 192 */ , (char)193 /* byte 193 */ , (char)194 /* byte 194 */ , (char)195 /* byte 195 */ , (char)196 /* byte 196 */ , (char)197 /* byte 197 */ , (char)198 /* byte 198 */ , (char)199 /* byte 199 */ , (char)200 /* byte 200 */ , (char)201 /* byte 201 */ , (char)202 /* byte 202 */ , (char)203 /* byte 203 */ , (char)204 /* byte 204 */ , (char)205 /* byte 205 */ , (char)206 /* byte 206 */ , (char)207 /* byte 207 */ , (char)208 /* byte 208 */ , (char)209 /* byte 209 */ , (char)210 /* byte 210 */ , (char)211 /* byte 211 */ , (char)212 /* byte 212 */ , (char)213 /* byte 213 */ , (char)214 /* byte 214 */ , (char)215 /* byte 215 */ , (char)216 /* byte 216 */ , (char)217 /* byte 217 */ , (char)218 /* byte 218 */ , (char)219 /* byte 219 */ , (char)220 /* byte 220 */ , (char)221 /* byte 221 */ , (char)222 /* byte 222 */ , (char)223 /* byte 223 */ , (char)224 /* byte 224 */ , (char)225 /* byte 225 */ , (char)226 /* byte 226 */ , (char)227 /* byte 227 */ , (char)228 /* byte 228 */ , (char)229 /* byte 229 */ , (char)230 /* byte 230 */ , (char)231 /* byte 231 */ , (char)232 /* byte 232 */ , (char)233 /* byte 233 */ , (char)234 /* byte 234 */ , (char)235 /* byte 235 */ , (char)236 /* byte 236 */ , (char)237 /* byte 237 */ , (char)238 /* byte 238 */ , (char)239 /* byte 239 */ , (char)240 /* byte 240 */ , (char)241 /* byte 241 */ , (char)242 /* byte 242 */ , (char)243 /* byte 243 */ , (char)244 /* byte 244 */ , (char)245 /* byte 245 */ , (char)246 /* byte 246 */ , (char)247 /* byte 247 */ , (char)248 /* byte 248 */ , (char)249 /* byte 249 */ , (char)250 /* byte 250 */ , (char)251 /* byte 251 */ , (char)252 /* byte 252 */ , (char)253 /* byte 253 */ , (char)254 /* byte 254 */ , (char)255 /* byte 255 */ }; #endregion #region Byte Lookup Dictionary /// <summary> /// This dictionary is used to resolve byte values for a given character. /// </summary> private static Dictionary<char, byte> charToByte = new Dictionary<char, byte> { { (char)0, 0 }, { (char)1, 1 }, { (char)2, 2 }, { (char)3, 3 }, { (char)4, 4 }, { (char)5, 5 }, { (char)6, 6 }, { (char)7, 7 }, { (char)8, 8 }, { (char)9, 9 }, { (char)10, 10 }, { (char)11, 11 }, { (char)12, 12 }, { (char)13, 13 }, { (char)14, 14 }, { (char)15, 15 }, { (char)16, 16 }, { (char)17, 17 }, { (char)18, 18 }, { (char)19, 19 }, { (char)20, 20 }, { (char)21, 21 }, { (char)22, 22 }, { (char)23, 23 }, { (char)24, 24 }, { (char)25, 25 }, { (char)26, 26 }, { (char)27, 27 }, { (char)28, 28 }, { (char)29, 29 }, { (char)30, 30 }, { (char)31, 31 }, { (char)32, 32 }, { (char)33, 33 }, { (char)34, 34 }, { (char)35, 35 }, { (char)36, 36 }, { (char)37, 37 }, { (char)38, 38 }, { (char)39, 39 }, { (char)40, 40 }, { (char)41, 41 }, { (char)42, 42 }, { (char)43, 43 }, { (char)44, 44 }, { (char)45, 45 }, { (char)46, 46 }, { (char)47, 47 }, { (char)48, 48 }, { (char)49, 49 }, { (char)50, 50 }, { (char)51, 51 }, { (char)52, 52 }, { (char)53, 53 }, { (char)54, 54 }, { (char)55, 55 }, { (char)56, 56 }, { (char)57, 57 }, { (char)58, 58 }, { (char)59, 59 }, { (char)60, 60 }, { (char)61, 61 }, { (char)62, 62 }, { (char)63, 63 }, { (char)64, 64 }, { (char)65, 65 }, { (char)66, 66 }, { (char)67, 67 }, { (char)68, 68 }, { (char)69, 69 }, { (char)70, 70 }, { (char)71, 71 }, { (char)72, 72 }, { (char)73, 73 }, { (char)74, 74 }, { (char)75, 75 }, { (char)76, 76 }, { (char)77, 77 }, { (char)78, 78 }, { (char)79, 79 }, { (char)80, 80 }, { (char)81, 81 }, { (char)82, 82 }, { (char)83, 83 }, { (char)84, 84 }, { (char)85, 85 }, { (char)86, 86 }, { (char)87, 87 }, { (char)88, 88 }, { (char)89, 89 }, { (char)90, 90 }, { (char)91, 91 }, { (char)92, 92 }, { (char)93, 93 }, { (char)94, 94 }, { (char)95, 95 }, { (char)96, 96 }, { (char)97, 97 }, { (char)98, 98 }, { (char)99, 99 }, { (char)100, 100 }, { (char)101, 101 }, { (char)102, 102 }, { (char)103, 103 }, { (char)104, 104 }, { (char)105, 105 }, { (char)106, 106 }, { (char)107, 107 }, { (char)108, 108 }, { (char)109, 109 }, { (char)110, 110 }, { (char)111, 111 }, { (char)112, 112 }, { (char)113, 113 }, { (char)114, 114 }, { (char)115, 115 }, { (char)116, 116 }, { (char)117, 117 }, { (char)118, 118 }, { (char)119, 119 }, { (char)120, 120 }, { (char)121, 121 }, { (char)122, 122 }, { (char)123, 123 }, { (char)124, 124 }, { (char)125, 125 }, { (char)126, 126 }, { (char)127, 127 }, { (char)128, 128 }, { (char)129, 129 }, { (char)130, 130 }, { (char)131, 131 }, { (char)132, 132 }, { (char)133, 133 }, { (char)134, 134 }, { (char)135, 135 }, { (char)136, 136 }, { (char)137, 137 }, { (char)138, 138 }, { (char)139, 139 }, { (char)140, 140 }, { (char)141, 141 }, { (char)142, 142 }, { (char)143, 143 }, { (char)144, 144 }, { (char)145, 145 }, { (char)146, 146 }, { (char)147, 147 }, { (char)148, 148 }, { (char)149, 149 }, { (char)150, 150 }, { (char)151, 151 }, { (char)152, 152 }, { (char)153, 153 }, { (char)154, 154 }, { (char)155, 155 }, { (char)156, 156 }, { (char)157, 157 }, { (char)158, 158 }, { (char)159, 159 }, { (char)160, 160 }, { (char)161, 161 }, { (char)162, 162 }, { (char)163, 163 }, { (char)164, 164 }, { (char)165, 165 }, { (char)166, 166 }, { (char)167, 167 }, { (char)168, 168 }, { (char)169, 169 }, { (char)170, 170 }, { (char)171, 171 }, { (char)172, 172 }, { (char)173, 173 }, { (char)174, 174 }, { (char)175, 175 }, { (char)176, 176 }, { (char)177, 177 }, { (char)178, 178 }, { (char)179, 179 }, { (char)180, 180 }, { (char)181, 181 }, { (char)182, 182 }, { (char)183, 183 }, { (char)184, 184 }, { (char)185, 185 }, { (char)186, 186 }, { (char)187, 187 }, { (char)188, 188 }, { (char)189, 189 }, { (char)190, 190 }, { (char)191, 191 }, { (char)192, 192 }, { (char)193, 193 }, { (char)194, 194 }, { (char)195, 195 }, { (char)196, 196 }, { (char)197, 197 }, { (char)198, 198 }, { (char)199, 199 }, { (char)200, 200 }, { (char)201, 201 }, { (char)202, 202 }, { (char)203, 203 }, { (char)204, 204 }, { (char)205, 205 }, { (char)206, 206 }, { (char)207, 207 }, { (char)208, 208 }, { (char)209, 209 }, { (char)210, 210 }, { (char)211, 211 }, { (char)212, 212 }, { (char)213, 213 }, { (char)214, 214 }, { (char)215, 215 }, { (char)216, 216 }, { (char)217, 217 }, { (char)218, 218 }, { (char)219, 219 }, { (char)220, 220 }, { (char)221, 221 }, { (char)222, 222 }, { (char)223, 223 }, { (char)224, 224 }, { (char)225, 225 }, { (char)226, 226 }, { (char)227, 227 }, { (char)228, 228 }, { (char)229, 229 }, { (char)230, 230 }, { (char)231, 231 }, { (char)232, 232 }, { (char)233, 233 }, { (char)234, 234 }, { (char)235, 235 }, { (char)236, 236 }, { (char)237, 237 }, { (char)238, 238 }, { (char)239, 239 }, { (char)240, 240 }, { (char)241, 241 }, { (char)242, 242 }, { (char)243, 243 }, { (char)244, 244 }, { (char)245, 245 }, { (char)246, 246 }, { (char)247, 247 }, { (char)248, 248 }, { (char)249, 249 }, { (char)250, 250 }, { (char)251, 251 }, { (char)252, 252 }, { (char)253, 253 }, { (char)254, 254 }, { (char)255, 255 } }; #endregion }