[BACK]Return to udl.c CVS log [TXT][DIR] Up to [cvs.NetBSD.org] / src / sys / dev / usb

Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.

Diff for /src/sys/dev/usb/udl.c between version 1.14.2.2 and 1.15

version 1.14.2.2, 2017/01/07 08:56:42 version 1.15, 2016/10/17 19:58:42
Line 55 
Line 55 
 #include <sys/cdefs.h>  #include <sys/cdefs.h>
 __KERNEL_RCSID(0, "$NetBSD$");  __KERNEL_RCSID(0, "$NetBSD$");
   
 #ifdef _KERNEL_OPT  
 #include "opt_usb.h"  
 #endif  
   
 #include <sys/param.h>  #include <sys/param.h>
 #include <sys/device.h>  #include <sys/device.h>
 #include <sys/kernel.h>  #include <sys/kernel.h>
 #include <sys/proc.h>  #include <sys/proc.h>
 #include <sys/systm.h>  #include <sys/systm.h>
 #include <sys/kmem.h>  #include <sys/kmem.h>
 #include <sys/kthread.h>  
 #include <sys/condvar.h>  
 #include <uvm/uvm.h>  #include <uvm/uvm.h>
   
 #include <sys/bus.h>  #include <sys/bus.h>
Line 178  static uint16_t  udl_lfsr(uint16_t);
Line 172  static uint16_t  udl_lfsr(uint16_t);
 static int              udl_set_resolution(struct udl_softc *,  static int              udl_set_resolution(struct udl_softc *,
                             const struct videomode *);                              const struct videomode *);
 static const struct videomode *udl_videomode_lookup(const char *);  static const struct videomode *udl_videomode_lookup(const char *);
 static void             udl_update_thread(void *);  
 static inline void udl_startstop(struct udl_softc *, bool);  
   
 static inline void  static inline void
 udl_cmd_add_1(struct udl_softc *sc, uint8_t val)  udl_cmd_add_1(struct udl_softc *sc, uint8_t val)
Line 476  udl_attach(device_t parent, device_t sel
Line 468  udl_attach(device_t parent, device_t sel
             config_found(sc->sc_dev, &aa, wsemuldisplaydevprint);              config_found(sc->sc_dev, &aa, wsemuldisplaydevprint);
   
         usbd_add_drv_event(USB_EVENT_DRIVER_ATTACH, sc->sc_udev, sc->sc_dev);          usbd_add_drv_event(USB_EVENT_DRIVER_ATTACH, sc->sc_udev, sc->sc_dev);
   
         mutex_init(&sc->sc_thread_mtx, MUTEX_DEFAULT, IPL_NONE);  
         cv_init(&sc->sc_thread_cv, "udlcv");  
         sc->sc_dying = false;  
         sc->sc_thread_stop = true;  
         kthread_create(PRI_BIO, KTHREAD_MPSAFE | KTHREAD_MUSTJOIN, NULL,  
             udl_update_thread, sc, &sc->sc_thread, "udlupd");  
 }  }
   
 static int  static int
Line 507  udl_detach(device_t self, int flags)
Line 492  udl_detach(device_t self, int flags)
                 usbd_close_pipe(sc->sc_tx_pipeh);                  usbd_close_pipe(sc->sc_tx_pipeh);
         }          }
   
           cv_destroy(&sc->sc_cv);
           mutex_destroy(&sc->sc_mtx);
   
         /*          /*
          * Free Huffman table.           * Free Huffman table.
          */           */
Line 517  udl_detach(device_t self, int flags)
Line 505  udl_detach(device_t self, int flags)
          */           */
         udl_fbmem_free(sc);          udl_fbmem_free(sc);
   
         mutex_enter(&sc->sc_thread_mtx);  
         sc->sc_dying = true;  
         cv_broadcast(&sc->sc_thread_cv);  
         mutex_exit(&sc->sc_thread_mtx);  
         kthread_join(sc->sc_thread);  
   
         cv_destroy(&sc->sc_cv);  
         mutex_destroy(&sc->sc_mtx);  
         cv_destroy(&sc->sc_thread_cv);  
         mutex_destroy(&sc->sc_thread_mtx);  
   
         /*          /*
          * Detach wsdisplay.           * Detach wsdisplay.
          */           */
Line 579  udl_ioctl(void *v, void *vs, u_long cmd,
Line 556  udl_ioctl(void *v, void *vs, u_long cmd,
                         return 0;                          return 0;
                 switch (mode) {                  switch (mode) {
                 case WSDISPLAYIO_VIDEO_OFF:                  case WSDISPLAYIO_VIDEO_OFF:
                         udl_startstop(sc, true);  
                         udl_blank(sc, 1);                          udl_blank(sc, 1);
                         break;                          break;
                 case WSDISPLAYIO_VIDEO_ON:                  case WSDISPLAYIO_VIDEO_ON:
Line 588  udl_ioctl(void *v, void *vs, u_long cmd,
Line 564  udl_ioctl(void *v, void *vs, u_long cmd,
                 default:                  default:
                         return EINVAL;                          return EINVAL;
                 }                  }
                 if (UDL_CMD_BUFSIZE(sc) > 0)                  udl_cmd_send_async(sc);
                         udl_cmd_send_async(sc);  
                 udl_cmdq_flush(sc);                  udl_cmdq_flush(sc);
                 sc->sc_blank = mode;                  sc->sc_blank = mode;
                 return 0;                  return 0;
Line 600  udl_ioctl(void *v, void *vs, u_long cmd,
Line 575  udl_ioctl(void *v, void *vs, u_long cmd,
                         return 0;                          return 0;
                 switch (mode) {                  switch (mode) {
                 case WSDISPLAYIO_MODE_EMUL:                  case WSDISPLAYIO_MODE_EMUL:
                         udl_startstop(sc, true);  
                         /* clear screen */                          /* clear screen */
                         udl_fill_rect(sc, 0, 0, 0, sc->sc_width,                          udl_fill_rect(sc, 0, 0, 0, sc->sc_width,
                             sc->sc_height);                              sc->sc_height);
                         if (UDL_CMD_BUFSIZE(sc) > 0)                          udl_cmd_send_async(sc);
                                 udl_cmd_send_async(sc);  
                         udl_cmdq_flush(sc);                          udl_cmdq_flush(sc);
                         udl_comp_unload(sc);                          udl_comp_unload(sc);
                         break;                          break;
Line 614  udl_ioctl(void *v, void *vs, u_long cmd,
Line 587  udl_ioctl(void *v, void *vs, u_long cmd,
                                 udl_cmd_send_async(sc);                                  udl_cmd_send_async(sc);
                         udl_cmdq_flush(sc);                          udl_cmdq_flush(sc);
                         udl_comp_load(sc);                          udl_comp_load(sc);
                         udl_startstop(sc, false);  
                         break;                          break;
                 default:                  default:
                         return EINVAL;                          return EINVAL;
Line 665  udl_mmap(void *v, void *vs, off_t off, i
Line 637  udl_mmap(void *v, void *vs, off_t off, i
         if (udl_fbmem_alloc(sc) != 0)          if (udl_fbmem_alloc(sc) != 0)
                 return -1;                  return -1;
   
         udl_startstop(sc, false);  
   
         vaddr = (vaddr_t)sc->sc_fbmem + off;          vaddr = (vaddr_t)sc->sc_fbmem + off;
         rv = pmap_extract(pmap_kernel(), vaddr, &paddr);          rv = pmap_extract(pmap_kernel(), vaddr, &paddr);
         KASSERT(rv);          KASSERT(rv);
Line 840  static int
Line 810  static int
 udl_fbmem_alloc(struct udl_softc *sc)  udl_fbmem_alloc(struct udl_softc *sc)
 {  {
   
         mutex_enter(&sc->sc_thread_mtx);  
         if (sc->sc_fbmem == NULL) {          if (sc->sc_fbmem == NULL) {
                 sc->sc_fbmem = kmem_zalloc(UDL_FBMEM_SIZE(sc), KM_SLEEP);                  sc->sc_fbmem = kmem_alloc(UDL_FBMEM_SIZE(sc), KM_SLEEP);
                 if (sc->sc_fbmem == NULL) {                  if (sc->sc_fbmem == NULL)
                         mutex_exit(&sc->sc_thread_mtx);  
                         return -1;  
                 }  
         }  
         if (sc->sc_fbmem_prev == NULL) {  
                 sc->sc_fbmem_prev = kmem_zalloc(UDL_FBMEM_SIZE(sc), KM_SLEEP);  
                 if (sc->sc_fbmem_prev == NULL) {  
                         kmem_free(sc->sc_fbmem, UDL_FBMEM_SIZE(sc));  
                         sc->sc_fbmem = NULL;  
                         mutex_exit(&sc->sc_thread_mtx);  
                         return -1;                          return -1;
                 }  
         }          }
         mutex_exit(&sc->sc_thread_mtx);  
   
         return 0;          return 0;
 }  }
Line 866  static void
Line 823  static void
 udl_fbmem_free(struct udl_softc *sc)  udl_fbmem_free(struct udl_softc *sc)
 {  {
   
         mutex_enter(&sc->sc_thread_mtx);  
         if (sc->sc_fbmem != NULL) {          if (sc->sc_fbmem != NULL) {
                 kmem_free(sc->sc_fbmem, UDL_FBMEM_SIZE(sc));                  kmem_free(sc->sc_fbmem, UDL_FBMEM_SIZE(sc));
                 sc->sc_fbmem = NULL;                  sc->sc_fbmem = NULL;
         }          }
         if (sc->sc_fbmem_prev != NULL) {  
                 kmem_free(sc->sc_fbmem_prev, UDL_FBMEM_SIZE(sc));  
                 sc->sc_fbmem_prev = NULL;  
         }  
         mutex_exit(&sc->sc_thread_mtx);  
 }  }
   
 static int  static int
Line 1415  udl_cmd_add_buf_comp(struct udl_softc *s
Line 1366  udl_cmd_add_buf_comp(struct udl_softc *s
         }          }
   
         /*          /*
          * If we have bits left in our last byte, round up to the next           * If we have bits left in our last byte, round up to the next
          * byte, so we don't overwrite them.           * byte, so we don't overwrite them.
          */           */
         if (bit_pos > 0) {          if (bit_pos > 0) {
                 sc->sc_cmd_buf++;                  sc->sc_cmd_buf++;
                 sc->sc_cmd_cblen++;                  sc->sc_cmd_cblen++;
Line 1812  udl_videomode_lookup(const char *name)
Line 1763  udl_videomode_lookup(const char *name)
   
         return NULL;          return NULL;
 }  }
   
 static void  
 udl_update_thread(void *v)  
 {  
         struct udl_softc *sc = v;  
         int stride;  
 #ifdef notyet  
         bool update = false;  
         int linecount, x, y;  
         uint16_t *fb, *fbcopy;  
         uint8_t *curfb;  
 #else  
         uint16_t *fb;  
         int offs;  
 #endif  
   
         mutex_enter(&sc->sc_thread_mtx);  
   
         for (;;) {  
                 stride = min(sc->sc_width, UDL_CMD_WIDTH_MAX - 8);  
                 if (sc->sc_dying == true) {  
                         mutex_exit(&sc->sc_thread_mtx);  
                         kthread_exit(0);  
                 }  
   
                 if (sc->sc_thread_stop == true || sc->sc_fbmem == NULL)  
                         goto thread_wait;  
   
 #ifdef notyet  
                 curfb = kmem_zalloc(UDL_FBMEM_SIZE(sc), KM_SLEEP);  
                 memcpy(curfb, sc->sc_fbmem, sc->sc_height * sc->sc_width * 2);  
                 fb = (uint16_t *)curfb;  
                 fbcopy = (uint16_t *)sc->sc_fbmem_prev;  
                 for (y = 0; y < sc->sc_height; y++) {  
                         linecount = 0;  
                         update = false;  
                         for (x = 0; x < sc->sc_width; x++) {  
                                 if (linecount >= stride) {  
                                         udl_draw_line(sc, &fb[y * sc->sc_width  
                                             + x - linecount], y * sc->sc_width  
                                             + x - linecount, linecount);  
                                         linecount = 0;  
                                         update = false;  
                                 }  
                                 if (fb[y * sc->sc_width + x] ^ fbcopy[y *  
                                     sc->sc_width + x]) {  
                                         update = true;  
                                         linecount ++;  
                                 } else if (update == true) {  
                                         udl_draw_line(sc, &fb[y * sc->sc_width  
                                             + x - linecount], y * sc->sc_width  
                                             + x - linecount, linecount);  
                                         linecount = 0;  
                                         update = false;  
                                 }  
                         }  
                         if (linecount) {  
                                 udl_draw_line(sc, &fb[y * sc->sc_width + x -  
                                     linecount], y * sc->sc_width  + x -  
                                     linecount, linecount);  
                         }  
                 }  
                 memcpy(sc->sc_fbmem_prev, curfb, sc->sc_height * sc->sc_width  
                     * 2);  
                 kmem_free(curfb, UDL_FBMEM_SIZE(sc));  
 #else  
                 fb = (uint16_t *)sc->sc_fbmem;  
                 for (offs = 0; offs < sc->sc_height * sc->sc_width; offs += stride)  
                         udl_draw_line(sc, &fb[offs], offs, stride);  
   
 #endif  
   
                 kpause("udlslp", false, (40 * hz)/1000 + 1, &sc->sc_thread_mtx);  
                 continue;  
   
 thread_wait:  
                 cv_wait(&sc->sc_thread_cv, &sc->sc_thread_mtx);  
         }  
 }  
   
 static inline void  
 udl_startstop(struct udl_softc *sc, bool stop)  
 {  
         mutex_enter(&sc->sc_thread_mtx);  
         sc->sc_thread_stop = stop;  
         if (!stop)  
                 cv_broadcast(&sc->sc_thread_cv);  
         mutex_exit(&sc->sc_thread_mtx);  
 }  

Legend:
Removed from v.1.14.2.2  
changed lines
  Added in v.1.15

CVSweb <webmaster@jp.NetBSD.org>