| Create fb and vga character devices if available. |
| |
| diff -ru --exclude-from freebsd-src-diff-exclude-names /usr/src/sys/dev/fb/fb.c freebsd-11.1/sys/dev/fb/fb.c |
| --- /usr/src/sys/dev/fb/fb.c 2017-07-21 07:41:47.000000000 +0800 |
| +++ freebsd-11.1/sys/dev/fb/fb.c 2020-08-06 13:40:44.116549883 +0800 |
| @@ -67,6 +67,10 @@ |
| #ifdef FB_INSTALL_CDEV |
| static struct cdevsw *vidcdevsw_ini; |
| static struct cdevsw **vidcdevsw = &vidcdevsw_ini; |
| +static struct cdev *fb_dev_ini; |
| +static struct cdev **fb_dev = &fb_dev_ini; |
| +static struct cdev *va_dev_ini; |
| +static struct cdev **va_dev = &va_dev_ini; |
| #endif |
| |
| #define ARRAY_DELTA 4 |
| @@ -78,6 +82,7 @@ |
| video_switch_t **new_vidsw; |
| #ifdef FB_INSTALL_CDEV |
| struct cdevsw **new_cdevsw; |
| + struct cdev **new_fb_dev, **new_va_dev; |
| #endif |
| int newsize; |
| int s; |
| @@ -93,23 +98,33 @@ |
| #ifdef FB_INSTALL_CDEV |
| new_cdevsw = malloc(sizeof(*new_cdevsw)*newsize, M_DEVBUF, |
| M_WAITOK | M_ZERO); |
| + new_fb_dev = malloc(sizeof(struct cdev *) * newsize, M_DEVBUF, |
| + M_WAITOK | M_ZERO); |
| + new_va_dev = malloc(sizeof(struct cdev *) * newsize, M_DEVBUF, |
| + M_WAITOK | M_ZERO); |
| #endif |
| bcopy(adapter, new_adp, sizeof(*adapter)*adapters); |
| bcopy(vidsw, new_vidsw, sizeof(*vidsw)*adapters); |
| #ifdef FB_INSTALL_CDEV |
| bcopy(vidcdevsw, new_cdevsw, sizeof(*vidcdevsw)*adapters); |
| + memcpy(new_fb_dev, fb_dev, sizeof(struct cdev *) * adapters); |
| + memcpy(new_va_dev, va_dev, sizeof(struct cdev *) * adapters); |
| #endif |
| if (adapters > 1) { |
| free(adapter, M_DEVBUF); |
| free(vidsw, M_DEVBUF); |
| #ifdef FB_INSTALL_CDEV |
| free(vidcdevsw, M_DEVBUF); |
| + free(fb_dev, M_DEVBUF); |
| + free(va_dev, M_DEVBUF); |
| #endif |
| } |
| adapter = new_adp; |
| vidsw = new_vidsw; |
| #ifdef FB_INSTALL_CDEV |
| vidcdevsw = new_cdevsw; |
| + fb_dev = new_fb_dev; |
| + va_dev = new_va_dev; |
| #endif |
| adapters = newsize; |
| splx(s); |
| @@ -352,14 +367,43 @@ |
| #define FB_UNIT(dev) dev2unit(dev) |
| #define FB_MKMINOR(unit) (u) |
| |
| -#if 0 /* experimental */ |
| -static d_open_t fbopen; |
| -static d_close_t fbclose; |
| -static d_read_t fbread; |
| -static d_write_t fbwrite; |
| -static d_ioctl_t fbioctl; |
| -static d_mmap_t fbmmap; |
| +#if 1 /* experimental */ |
| +static int fbopen(struct cdev *dev, int flags, int devtype, struct thread *td) { |
| + int unit = FB_UNIT(dev); |
| + if (unit >= adapters) return ENXIO; |
| + if (vidcdevsw[unit] == NULL) return ENXIO; |
| + return vidcdevsw[unit]->d_open(va_dev[unit], flags, devtype, td); |
| +} |
| + |
| +static int fbclose(struct cdev *dev, int fflag, int devtype, struct thread *td) { |
| + int unit = FB_UNIT(dev); |
| + if (vidcdevsw[unit] == NULL) return ENXIO; |
| + return vidcdevsw[unit]->d_close(va_dev[unit], fflag, devtype, td); |
| +} |
| + |
| +static int fbread(struct cdev *dev, struct uio *uio, int flags) { |
| + int unit = FB_UNIT(dev); |
| + if (vidcdevsw[unit] == NULL) return ENXIO; |
| + return vidcdevsw[unit]->d_read(va_dev[unit], uio, flags); |
| +} |
| |
| +static int fbwrite(struct cdev *dev, struct uio *uio, int flags) { |
| + int unit = FB_UNIT(dev); |
| + if (vidcdevsw[unit] == NULL) return ENXIO; |
| + return vidcdevsw[unit]->d_write(va_dev[unit], uio, flags); |
| +} |
| + |
| +static int fbioctl(struct cdev *dev, u_long cmd, caddr_t data, int flags, struct thread *td) { |
| + int unit = FB_UNIT(dev); |
| + if (vidcdevsw[unit] == NULL) return ENXIO; |
| + return vidcdevsw[unit]->d_ioctl(va_dev[unit], cmd, data, flags, td); |
| +} |
| + |
| +static int fbmmap(struct cdev *dev, vm_ooffset_t offset, vm_paddr_t *paddr, int nprot, vm_memattr_t *memattr) { |
| + int unit = FB_UNIT(dev); |
| + if (vidcdevsw[unit] == NULL) return ENXIO; |
| + return vidcdevsw[unit]->d_mmap(va_dev[unit], offset, paddr, nprot, memattr); |
| +} |
| |
| static struct cdevsw fb_cdevsw = { |
| .d_version = D_VERSION, |
| @@ -400,7 +444,7 @@ |
| DECLARE_MODULE(fb, fb_mod, SI_SUB_PSEUDO, SI_ORDER_ANY); |
| |
| int |
| -fb_attach(int unit, video_adapter_t *adp, struct cdevsw *cdevsw) |
| +fb_attach(int unit, video_adapter_t *adp, struct cdevsw *cdevsw, struct cdev *cdev) |
| { |
| int s; |
| |
| @@ -412,6 +456,9 @@ |
| s = spltty(); |
| adp->va_minor = unit; |
| vidcdevsw[adp->va_index] = cdevsw; |
| + fb_dev[adp->va_index] = make_dev(&fb_cdevsw, adp->va_index, UID_ROOT, |
| + GID_WHEEL, 0660, "fb%d", adp->va_index); |
| + va_dev[adp->va_index] = cdev; |
| splx(s); |
| |
| printf("fb%d at %s%d\n", adp->va_index, adp->va_name, adp->va_unit); |
| @@ -432,6 +479,9 @@ |
| |
| s = spltty(); |
| vidcdevsw[adp->va_index] = NULL; |
| + destroy_dev(fb_dev[adp->va_index]); |
| + fb_dev[adp->va_index] = NULL; |
| + va_dev[adp->va_index] = NULL; |
| splx(s); |
| return 0; |
| } |
| diff -ru --exclude-from freebsd-src-diff-exclude-names /usr/src/sys/dev/fb/fbreg.h freebsd-11.1/sys/dev/fb/fbreg.h |
| --- /usr/src/sys/dev/fb/fbreg.h 2017-07-21 07:41:47.000000000 +0800 |
| +++ freebsd-11.1/sys/dev/fb/fbreg.h 2020-08-06 13:36:26.949051364 +0800 |
| @@ -303,7 +303,7 @@ |
| |
| /* virtual frame buffer driver functions */ |
| int fb_attach(int unit, video_adapter_t *adp, |
| - struct cdevsw *cdevsw); |
| + struct cdevsw *cdevsw, struct cdev *cdev); |
| int fb_detach(int unit, video_adapter_t *adp, |
| struct cdevsw *cdevsw); |
| |
| diff -ru --exclude-from freebsd-src-diff-exclude-names /usr/src/sys/isa/vga_isa.c freebsd-11.1/sys/isa/vga_isa.c |
| --- /usr/src/sys/isa/vga_isa.c 2017-07-21 07:42:12.000000000 +0800 |
| +++ freebsd-11.1/sys/isa/vga_isa.c 2020-08-06 13:35:06.550618335 +0800 |
| @@ -206,8 +206,11 @@ |
| return (error); |
| |
| #ifdef FB_INSTALL_CDEV |
| + /*sc->cdev*/ |
| + struct cdev *cdev = make_dev(&isavga_cdevsw, unit, UID_ROOT, GID_WHEEL, 0600, |
| + "%s%d", sc->adp->va_name, unit); |
| /* attach a virtual frame buffer device */ |
| - error = fb_attach(VGA_MKMINOR(unit), sc->adp, &isavga_cdevsw); |
| + error = fb_attach(VGA_MKMINOR(unit), sc->adp, &isavga_cdevsw, cdev); |
| if (error) |
| return (error); |
| #endif /* FB_INSTALL_CDEV */ |
| @@ -215,7 +218,7 @@ |
| if (0 && bootverbose) |
| vidd_diag(sc->adp, bootverbose); |
| |
| -#if 0 /* experimental */ |
| +#if 1 /* experimental */ |
| device_add_child(dev, "fb", -1); |
| bus_generic_attach(dev); |
| #endif |