lkml.org 
[lkml]   [2016]   [Aug]   [12]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
/
Date
From
Subjectdrivers/gpu/drm/udl/udl_fb.c:206:2: note: in expansion of macro 'if'
tree:   https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git master
head: 4b9eaf33d83d91430b7ca45d0ebf8241da489c92
commit: c0f0c177b5a9aa6d3791aa497a64a20a297ebc6f drm/udl: make fbdev support really optional
date: 4 weeks ago
config: x86_64-randconfig-n0-08130055 (attached as .config)
compiler: gcc-6 (Debian 6.1.1-9) 6.1.1 20160705
reproduce:
git checkout c0f0c177b5a9aa6d3791aa497a64a20a297ebc6f
# save the attached .config to linux build tree
make ARCH=x86_64

All warnings (new ones prefixed by >>):

In file included from include/uapi/linux/stddef.h:1:0,
from include/linux/stddef.h:4,
from include/uapi/linux/posix_types.h:4,
from include/uapi/linux/types.h:13,
from include/linux/types.h:5,
from include/linux/list.h:4,
from include/linux/module.h:9,
from drivers/gpu/drm/udl/udl_fb.c:13:
drivers/gpu/drm/udl/udl_fb.c: In function 'udl_fb_open':
drivers/gpu/drm/udl/udl_fb.c:206:23: error: 'struct fb_info' has no member named 'fbdefio'
if (fb_defio && (info->fbdefio == NULL)) {
^
include/linux/compiler.h:151:30: note: in definition of macro '__trace_if'
if (__builtin_constant_p(!!(cond)) ? !!(cond) : \
^~~~
>> drivers/gpu/drm/udl/udl_fb.c:206:2: note: in expansion of macro 'if'
if (fb_defio && (info->fbdefio == NULL)) {
^~
drivers/gpu/drm/udl/udl_fb.c:206:23: error: 'struct fb_info' has no member named 'fbdefio'
if (fb_defio && (info->fbdefio == NULL)) {
^
include/linux/compiler.h:151:42: note: in definition of macro '__trace_if'
if (__builtin_constant_p(!!(cond)) ? !!(cond) : \
^~~~
>> drivers/gpu/drm/udl/udl_fb.c:206:2: note: in expansion of macro 'if'
if (fb_defio && (info->fbdefio == NULL)) {
^~
drivers/gpu/drm/udl/udl_fb.c:206:23: error: 'struct fb_info' has no member named 'fbdefio'
if (fb_defio && (info->fbdefio == NULL)) {
^
include/linux/compiler.h:162:16: note: in definition of macro '__trace_if'
______r = !!(cond); \
^~~~
>> drivers/gpu/drm/udl/udl_fb.c:206:2: note: in expansion of macro 'if'
if (fb_defio && (info->fbdefio == NULL)) {
^~
drivers/gpu/drm/udl/udl_fb.c:211:28: error: invalid application of 'sizeof' to incomplete type 'struct fb_deferred_io'
fbdefio = kmalloc(sizeof(struct fb_deferred_io), GFP_KERNEL);
^~~~~~
drivers/gpu/drm/udl/udl_fb.c:214:11: error: dereferencing pointer to incomplete type 'struct fb_deferred_io'
fbdefio->delay = DL_DEFIO_WRITE_DELAY;
^~
drivers/gpu/drm/udl/udl_fb.c:218:7: error: 'struct fb_info' has no member named 'fbdefio'
info->fbdefio = fbdefio;
^~
In file included from include/uapi/linux/stddef.h:1:0,
from include/linux/stddef.h:4,
from include/uapi/linux/posix_types.h:4,
from include/uapi/linux/types.h:13,
from include/linux/types.h:5,
from include/linux/list.h:4,
from include/linux/module.h:9,
from drivers/gpu/drm/udl/udl_fb.c:13:
drivers/gpu/drm/udl/udl_fb.c: In function 'udl_fb_release':
drivers/gpu/drm/udl/udl_fb.c:238:38: error: 'struct fb_info' has no member named 'fbdefio'
if ((ufbdev->fb_count == 0) && (info->fbdefio)) {
^
include/linux/compiler.h:151:30: note: in definition of macro '__trace_if'
if (__builtin_constant_p(!!(cond)) ? !!(cond) : \
^~~~
drivers/gpu/drm/udl/udl_fb.c:238:2: note: in expansion of macro 'if'
if ((ufbdev->fb_count == 0) && (info->fbdefio)) {
^~
drivers/gpu/drm/udl/udl_fb.c:238:38: error: 'struct fb_info' has no member named 'fbdefio'
if ((ufbdev->fb_count == 0) && (info->fbdefio)) {
^
include/linux/compiler.h:151:42: note: in definition of macro '__trace_if'
if (__builtin_constant_p(!!(cond)) ? !!(cond) : \
^~~~
drivers/gpu/drm/udl/udl_fb.c:238:2: note: in expansion of macro 'if'
if ((ufbdev->fb_count == 0) && (info->fbdefio)) {
^~
drivers/gpu/drm/udl/udl_fb.c:238:38: error: 'struct fb_info' has no member named 'fbdefio'
if ((ufbdev->fb_count == 0) && (info->fbdefio)) {
^
include/linux/compiler.h:162:16: note: in definition of macro '__trace_if'
______r = !!(cond); \
^~~~
drivers/gpu/drm/udl/udl_fb.c:238:2: note: in expansion of macro 'if'
if ((ufbdev->fb_count == 0) && (info->fbdefio)) {
^~
drivers/gpu/drm/udl/udl_fb.c:240:13: error: 'struct fb_info' has no member named 'fbdefio'
kfree(info->fbdefio);
^~
drivers/gpu/drm/udl/udl_fb.c:241:7: error: 'struct fb_info' has no member named 'fbdefio'
info->fbdefio = NULL;
^~

vim +/if +206 drivers/gpu/drm/udl/udl_fb.c

5320918b9 Dave Airlie 2010-12-15 7 * Copyright (C) 2009 Bernie Thompson <bernie@plugable.com>
5320918b9 Dave Airlie 2010-12-15 8 *
5320918b9 Dave Airlie 2010-12-15 9 * This file is subject to the terms and conditions of the GNU General Public
5320918b9 Dave Airlie 2010-12-15 10 * License v2. See the file COPYING in the main directory of this archive for
5320918b9 Dave Airlie 2010-12-15 11 * more details.
5320918b9 Dave Airlie 2010-12-15 12 */
5320918b9 Dave Airlie 2010-12-15 @13 #include <linux/module.h>
5320918b9 Dave Airlie 2010-12-15 14 #include <linux/slab.h>
5320918b9 Dave Airlie 2010-12-15 15 #include <linux/fb.h>
32ecd2426 Dave Airlie 2012-07-30 16 #include <linux/dma-buf.h>
5320918b9 Dave Airlie 2010-12-15 17
760285e7e David Howells 2012-10-02 18 #include <drm/drmP.h>
760285e7e David Howells 2012-10-02 19 #include <drm/drm_crtc.h>
760285e7e David Howells 2012-10-02 20 #include <drm/drm_crtc_helper.h>
5320918b9 Dave Airlie 2010-12-15 21 #include "udl_drv.h"
5320918b9 Dave Airlie 2010-12-15 22
760285e7e David Howells 2012-10-02 23 #include <drm/drm_fb_helper.h>
5320918b9 Dave Airlie 2010-12-15 24
677d23b70 Dave Airlie 2013-02-07 25 #define DL_DEFIO_WRITE_DELAY (HZ/20) /* fb_deferred_io.delay in jiffies */
5320918b9 Dave Airlie 2010-12-15 26
677d23b70 Dave Airlie 2013-02-07 27 static int fb_defio = 0; /* Optionally enable experimental fb_defio mmap support */
5320918b9 Dave Airlie 2010-12-15 28 static int fb_bpp = 16;
5320918b9 Dave Airlie 2010-12-15 29
5320918b9 Dave Airlie 2010-12-15 30 module_param(fb_bpp, int, S_IWUSR | S_IRUSR | S_IWGRP | S_IRGRP);
5320918b9 Dave Airlie 2010-12-15 31 module_param(fb_defio, int, S_IWUSR | S_IRUSR | S_IWGRP | S_IRGRP);
5320918b9 Dave Airlie 2010-12-15 32
5320918b9 Dave Airlie 2010-12-15 33 struct udl_fbdev {
5320918b9 Dave Airlie 2010-12-15 34 struct drm_fb_helper helper;
5320918b9 Dave Airlie 2010-12-15 35 struct udl_framebuffer ufb;
5320918b9 Dave Airlie 2010-12-15 36 int fb_count;
5320918b9 Dave Airlie 2010-12-15 37 };
5320918b9 Dave Airlie 2010-12-15 38
5320918b9 Dave Airlie 2010-12-15 39 #define DL_ALIGN_UP(x, a) ALIGN(x, a)
5320918b9 Dave Airlie 2010-12-15 40 #define DL_ALIGN_DOWN(x, a) ALIGN(x-(a-1), a)
5320918b9 Dave Airlie 2010-12-15 41
5320918b9 Dave Airlie 2010-12-15 42 /** Read the red component (0..255) of a 32 bpp colour. */
5320918b9 Dave Airlie 2010-12-15 43 #define DLO_RGB_GETRED(col) (uint8_t)((col) & 0xFF)
5320918b9 Dave Airlie 2010-12-15 44
5320918b9 Dave Airlie 2010-12-15 45 /** Read the green component (0..255) of a 32 bpp colour. */
5320918b9 Dave Airlie 2010-12-15 46 #define DLO_RGB_GETGRN(col) (uint8_t)(((col) >> 8) & 0xFF)
5320918b9 Dave Airlie 2010-12-15 47
5320918b9 Dave Airlie 2010-12-15 48 /** Read the blue component (0..255) of a 32 bpp colour. */
5320918b9 Dave Airlie 2010-12-15 49 #define DLO_RGB_GETBLU(col) (uint8_t)(((col) >> 16) & 0xFF)
5320918b9 Dave Airlie 2010-12-15 50
5320918b9 Dave Airlie 2010-12-15 51 /** Return red/green component of a 16 bpp colour number. */
5320918b9 Dave Airlie 2010-12-15 52 #define DLO_RG16(red, grn) (uint8_t)((((red) & 0xF8) | ((grn) >> 5)) & 0xFF)
5320918b9 Dave Airlie 2010-12-15 53
5320918b9 Dave Airlie 2010-12-15 54 /** Return green/blue component of a 16 bpp colour number. */
5320918b9 Dave Airlie 2010-12-15 55 #define DLO_GB16(grn, blu) (uint8_t)(((((grn) & 0x1C) << 3) | ((blu) >> 3)) & 0xFF)
5320918b9 Dave Airlie 2010-12-15 56
5320918b9 Dave Airlie 2010-12-15 57 /** Return 8 bpp colour number from red, green and blue components. */
5320918b9 Dave Airlie 2010-12-15 58 #define DLO_RGB8(red, grn, blu) ((((red) << 5) | (((grn) & 3) << 3) | ((blu) & 7)) & 0xFF)
5320918b9 Dave Airlie 2010-12-15 59
5320918b9 Dave Airlie 2010-12-15 60 #if 0
5320918b9 Dave Airlie 2010-12-15 61 static uint8_t rgb8(uint32_t col)
5320918b9 Dave Airlie 2010-12-15 62 {
5320918b9 Dave Airlie 2010-12-15 63 uint8_t red = DLO_RGB_GETRED(col);
5320918b9 Dave Airlie 2010-12-15 64 uint8_t grn = DLO_RGB_GETGRN(col);
5320918b9 Dave Airlie 2010-12-15 65 uint8_t blu = DLO_RGB_GETBLU(col);
5320918b9 Dave Airlie 2010-12-15 66
5320918b9 Dave Airlie 2010-12-15 67 return DLO_RGB8(red, grn, blu);
5320918b9 Dave Airlie 2010-12-15 68 }
5320918b9 Dave Airlie 2010-12-15 69
5320918b9 Dave Airlie 2010-12-15 70 static uint16_t rgb16(uint32_t col)
5320918b9 Dave Airlie 2010-12-15 71 {
5320918b9 Dave Airlie 2010-12-15 72 uint8_t red = DLO_RGB_GETRED(col);
5320918b9 Dave Airlie 2010-12-15 73 uint8_t grn = DLO_RGB_GETGRN(col);
5320918b9 Dave Airlie 2010-12-15 74 uint8_t blu = DLO_RGB_GETBLU(col);
5320918b9 Dave Airlie 2010-12-15 75
5320918b9 Dave Airlie 2010-12-15 76 return (DLO_RG16(red, grn) << 8) + DLO_GB16(grn, blu);
5320918b9 Dave Airlie 2010-12-15 77 }
5320918b9 Dave Airlie 2010-12-15 78 #endif
5320918b9 Dave Airlie 2010-12-15 79
5320918b9 Dave Airlie 2010-12-15 80 int udl_handle_damage(struct udl_framebuffer *fb, int x, int y,
5320918b9 Dave Airlie 2010-12-15 81 int width, int height)
5320918b9 Dave Airlie 2010-12-15 82 {
5320918b9 Dave Airlie 2010-12-15 83 struct drm_device *dev = fb->base.dev;
5320918b9 Dave Airlie 2010-12-15 84 struct udl_device *udl = dev->dev_private;
5320918b9 Dave Airlie 2010-12-15 85 int i, ret;
5320918b9 Dave Airlie 2010-12-15 86 char *cmd;
5320918b9 Dave Airlie 2010-12-15 87 cycles_t start_cycles, end_cycles;
5320918b9 Dave Airlie 2010-12-15 88 int bytes_sent = 0;
5320918b9 Dave Airlie 2010-12-15 89 int bytes_identical = 0;
5320918b9 Dave Airlie 2010-12-15 90 struct urb *urb;
5320918b9 Dave Airlie 2010-12-15 91 int aligned_x;
5320918b9 Dave Airlie 2010-12-15 92 int bpp = (fb->base.bits_per_pixel / 8);
5320918b9 Dave Airlie 2010-12-15 93
5320918b9 Dave Airlie 2010-12-15 94 if (!fb->active_16)
5320918b9 Dave Airlie 2010-12-15 95 return 0;
5320918b9 Dave Airlie 2010-12-15 96
e8aa1d1eb Dave Airlie 2012-03-26 97 if (!fb->obj->vmapping) {
e8aa1d1eb Dave Airlie 2012-03-26 98 ret = udl_gem_vmap(fb->obj);
e8aa1d1eb Dave Airlie 2012-03-26 99 if (ret == -ENOMEM) {
e8aa1d1eb Dave Airlie 2012-03-26 100 DRM_ERROR("failed to vmap fb\n");
e8aa1d1eb Dave Airlie 2012-03-26 101 return 0;
e8aa1d1eb Dave Airlie 2012-03-26 102 }
e8aa1d1eb Dave Airlie 2012-03-26 103 if (!fb->obj->vmapping) {
e8aa1d1eb Dave Airlie 2012-03-26 104 DRM_ERROR("failed to vmapping\n");
e8aa1d1eb Dave Airlie 2012-03-26 105 return 0;
e8aa1d1eb Dave Airlie 2012-03-26 106 }
e8aa1d1eb Dave Airlie 2012-03-26 107 }
5320918b9 Dave Airlie 2010-12-15 108
5320918b9 Dave Airlie 2010-12-15 109 aligned_x = DL_ALIGN_DOWN(x, sizeof(unsigned long));
5320918b9 Dave Airlie 2010-12-15 110 width = DL_ALIGN_UP(width + (x-aligned_x), sizeof(unsigned long));
5320918b9 Dave Airlie 2010-12-15 111 x = aligned_x;
5320918b9 Dave Airlie 2010-12-15 112
5320918b9 Dave Airlie 2010-12-15 113 if ((width <= 0) ||
5320918b9 Dave Airlie 2010-12-15 114 (x + width > fb->base.width) ||
5320918b9 Dave Airlie 2010-12-15 115 (y + height > fb->base.height))
5320918b9 Dave Airlie 2010-12-15 116 return -EINVAL;
5320918b9 Dave Airlie 2010-12-15 117
bcb39af44 Dave Airlie 2013-02-07 118 start_cycles = get_cycles();
bcb39af44 Dave Airlie 2013-02-07 119
5320918b9 Dave Airlie 2010-12-15 120 urb = udl_get_urb(dev);
5320918b9 Dave Airlie 2010-12-15 121 if (!urb)
5320918b9 Dave Airlie 2010-12-15 122 return 0;
5320918b9 Dave Airlie 2010-12-15 123 cmd = urb->transfer_buffer;
5320918b9 Dave Airlie 2010-12-15 124
e37588240 Noralf Trønnes 2016-04-28 125 for (i = y; i < height ; i++) {
5320918b9 Dave Airlie 2010-12-15 126 const int line_offset = fb->base.pitches[0] * i;
5320918b9 Dave Airlie 2010-12-15 127 const int byte_offset = line_offset + (x * bpp);
3916e1d71 Dave Airlie 2012-11-01 128 const int dev_byte_offset = (fb->base.width * bpp * i) + (x * bpp);
5320918b9 Dave Airlie 2010-12-15 129 if (udl_render_hline(dev, bpp, &urb,
5320918b9 Dave Airlie 2010-12-15 130 (char *) fb->obj->vmapping,
3916e1d71 Dave Airlie 2012-11-01 131 &cmd, byte_offset, dev_byte_offset,
e37588240 Noralf Trønnes 2016-04-28 132 width * bpp,
5320918b9 Dave Airlie 2010-12-15 133 &bytes_identical, &bytes_sent))
5320918b9 Dave Airlie 2010-12-15 134 goto error;
5320918b9 Dave Airlie 2010-12-15 135 }
5320918b9 Dave Airlie 2010-12-15 136
5320918b9 Dave Airlie 2010-12-15 137 if (cmd > (char *) urb->transfer_buffer) {
5320918b9 Dave Airlie 2010-12-15 138 /* Send partial buffer remaining before exiting */
5320918b9 Dave Airlie 2010-12-15 139 int len = cmd - (char *) urb->transfer_buffer;
5320918b9 Dave Airlie 2010-12-15 140 ret = udl_submit_urb(dev, urb, len);
5320918b9 Dave Airlie 2010-12-15 141 bytes_sent += len;
5320918b9 Dave Airlie 2010-12-15 142 } else
5320918b9 Dave Airlie 2010-12-15 143 udl_urb_completion(urb);
5320918b9 Dave Airlie 2010-12-15 144
5320918b9 Dave Airlie 2010-12-15 145 error:
5320918b9 Dave Airlie 2010-12-15 146 atomic_add(bytes_sent, &udl->bytes_sent);
5320918b9 Dave Airlie 2010-12-15 147 atomic_add(bytes_identical, &udl->bytes_identical);
5320918b9 Dave Airlie 2010-12-15 148 atomic_add(width*height*bpp, &udl->bytes_rendered);
5320918b9 Dave Airlie 2010-12-15 149 end_cycles = get_cycles();
5320918b9 Dave Airlie 2010-12-15 150 atomic_add(((unsigned int) ((end_cycles - start_cycles)
5320918b9 Dave Airlie 2010-12-15 151 >> 10)), /* Kcycles */
5320918b9 Dave Airlie 2010-12-15 152 &udl->cpu_kcycles_used);
5320918b9 Dave Airlie 2010-12-15 153
5320918b9 Dave Airlie 2010-12-15 154 return 0;
5320918b9 Dave Airlie 2010-12-15 155 }
5320918b9 Dave Airlie 2010-12-15 156
5320918b9 Dave Airlie 2010-12-15 157 static int udl_fb_mmap(struct fb_info *info, struct vm_area_struct *vma)
5320918b9 Dave Airlie 2010-12-15 158 {
5320918b9 Dave Airlie 2010-12-15 159 unsigned long start = vma->vm_start;
5320918b9 Dave Airlie 2010-12-15 160 unsigned long size = vma->vm_end - vma->vm_start;
5320918b9 Dave Airlie 2010-12-15 161 unsigned long offset = vma->vm_pgoff << PAGE_SHIFT;
5320918b9 Dave Airlie 2010-12-15 162 unsigned long page, pos;
5320918b9 Dave Airlie 2010-12-15 163
5320918b9 Dave Airlie 2010-12-15 164 if (offset + size > info->fix.smem_len)
5320918b9 Dave Airlie 2010-12-15 165 return -EINVAL;
5320918b9 Dave Airlie 2010-12-15 166
5320918b9 Dave Airlie 2010-12-15 167 pos = (unsigned long)info->fix.smem_start + offset;
5320918b9 Dave Airlie 2010-12-15 168
5320918b9 Dave Airlie 2010-12-15 169 pr_notice("mmap() framebuffer addr:%lu size:%lu\n",
5320918b9 Dave Airlie 2010-12-15 170 pos, size);
5320918b9 Dave Airlie 2010-12-15 171
5320918b9 Dave Airlie 2010-12-15 172 while (size > 0) {
5320918b9 Dave Airlie 2010-12-15 173 page = vmalloc_to_pfn((void *)pos);
5320918b9 Dave Airlie 2010-12-15 174 if (remap_pfn_range(vma, start, page, PAGE_SIZE, PAGE_SHARED))
5320918b9 Dave Airlie 2010-12-15 175 return -EAGAIN;
5320918b9 Dave Airlie 2010-12-15 176
5320918b9 Dave Airlie 2010-12-15 177 start += PAGE_SIZE;
5320918b9 Dave Airlie 2010-12-15 178 pos += PAGE_SIZE;
5320918b9 Dave Airlie 2010-12-15 179 if (size > PAGE_SIZE)
5320918b9 Dave Airlie 2010-12-15 180 size -= PAGE_SIZE;
5320918b9 Dave Airlie 2010-12-15 181 else
5320918b9 Dave Airlie 2010-12-15 182 size = 0;
5320918b9 Dave Airlie 2010-12-15 183 }
5320918b9 Dave Airlie 2010-12-15 184
314e51b98 Konstantin Khlebnikov 2012-10-08 185 /* VM_IO | VM_DONTEXPAND | VM_DONTDUMP are set by remap_pfn_range() */
5320918b9 Dave Airlie 2010-12-15 186 return 0;
5320918b9 Dave Airlie 2010-12-15 187 }
5320918b9 Dave Airlie 2010-12-15 188
5320918b9 Dave Airlie 2010-12-15 189 /*
5320918b9 Dave Airlie 2010-12-15 190 * It's common for several clients to have framebuffer open simultaneously.
5320918b9 Dave Airlie 2010-12-15 191 * e.g. both fbcon and X. Makes things interesting.
5320918b9 Dave Airlie 2010-12-15 192 * Assumes caller is holding info->lock (for open and release at least)
5320918b9 Dave Airlie 2010-12-15 193 */
5320918b9 Dave Airlie 2010-12-15 194 static int udl_fb_open(struct fb_info *info, int user)
5320918b9 Dave Airlie 2010-12-15 195 {
5320918b9 Dave Airlie 2010-12-15 196 struct udl_fbdev *ufbdev = info->par;
5320918b9 Dave Airlie 2010-12-15 197 struct drm_device *dev = ufbdev->ufb.base.dev;
5320918b9 Dave Airlie 2010-12-15 198 struct udl_device *udl = dev->dev_private;
5320918b9 Dave Airlie 2010-12-15 199
5320918b9 Dave Airlie 2010-12-15 200 /* If the USB device is gone, we don't accept new opens */
5320918b9 Dave Airlie 2010-12-15 201 if (drm_device_is_unplugged(udl->ddev))
5320918b9 Dave Airlie 2010-12-15 202 return -ENODEV;
5320918b9 Dave Airlie 2010-12-15 203
5320918b9 Dave Airlie 2010-12-15 204 ufbdev->fb_count++;
5320918b9 Dave Airlie 2010-12-15 205
5320918b9 Dave Airlie 2010-12-15 @206 if (fb_defio && (info->fbdefio == NULL)) {
5320918b9 Dave Airlie 2010-12-15 207 /* enable defio at last moment if not disabled by client */
5320918b9 Dave Airlie 2010-12-15 208
5320918b9 Dave Airlie 2010-12-15 209 struct fb_deferred_io *fbdefio;

:::::: The code at line 206 was first introduced by commit
:::::: 5320918b9a87865223fd6b228e530bf30bc64d9d drm/udl: initial UDL driver (v4)

:::::: TO: Dave Airlie <airlied@gmail.com>
:::::: CC: Dave Airlie <airlied@redhat.com>

---
0-DAY kernel test infrastructure Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all Intel Corporation
[unhandled content-type:application/octet-stream]
\
 
 \ /
  Last update: 2016-09-17 09:56    [W:0.511 / U:0.900 seconds]
©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site