int vmw_fallback_wait(struct vmw_private *dev_priv, bool lazy, bool fifo_idle, uint32_t seqno, bool interruptible, unsigned long timeout) { struct vmw_fifo_state *fifo_state = &dev_priv->fifo; uint32_t count = 0; uint32_t signal_seq; int ret; unsigned long end_jiffies = GetTimerTicks() + timeout; bool (*wait_condition)(struct vmw_private *, uint32_t); DEFINE_WAIT(__wait); wait_condition = (fifo_idle) ? &vmw_fifo_idle : &vmw_seqno_passed; /** * Block command submission while waiting for idle. */ // if (fifo_idle) // down_read(&fifo_state->rwsem); signal_seq = atomic_read(&dev_priv->marker_seq); ret = 0; for (;;) { // prepare_to_wait(&dev_priv->fence_queue, &__wait, // (interruptible) ? // TASK_INTERRUPTIBLE : TASK_UNINTERRUPTIBLE); if (wait_condition(dev_priv, seqno)) break; if (time_after_eq(GetTimerTicks(), end_jiffies)) { DRM_ERROR("SVGA device lockup.\n"); break; } if (lazy) delay(1); else if ((++count & 0x0F) == 0) { /** * FIXME: Use schedule_hr_timeout here for * newer kernels and lower CPU utilization. */ delay(1); } } // finish_wait(&dev_priv->fence_queue, &__wait); if (ret == 0 && fifo_idle) { __le32 __iomem *fifo_mem = dev_priv->mmio_virt; iowrite32(signal_seq, fifo_mem + SVGA_FIFO_FENCE); } wake_up_all(&dev_priv->fence_queue); // if (fifo_idle) // up_read(&fifo_state->rwsem); return ret; }
DLL_EXPORT int log_read(char **buffer, int *msgindex, int block) { int bytes_returned; obtain_lock(&logger_lock); if(*msgindex == logger_currmsg && block) { if(logger_active) { wait_condition(&logger_cond, &logger_lock); } else { *msgindex = logger_currmsg; *buffer = logger_buffer + logger_currmsg; release_lock(&logger_lock); return 0; } } if(*msgindex != logger_currmsg) { if(*msgindex < 0) *msgindex = logger_wrapped ? logger_currmsg : 0; if(*msgindex < 0 || *msgindex >= logger_bufsize) *msgindex = 0; *buffer = logger_buffer + *msgindex; if(*msgindex >= logger_currmsg) { bytes_returned = logger_bufsize - *msgindex; *msgindex = 0; } else { bytes_returned = logger_currmsg - *msgindex; *msgindex = logger_currmsg; } } else bytes_returned = 0; release_lock(&logger_lock); return bytes_returned; }
DLL_EXPORT void logger_init(void) { int rc; initialize_condition (&logger_cond); initialize_lock (&logger_lock); logger_init_flg = TRUE; /* this is a conditional macro based upon OPTION_MSGLCK */ INIT_MSGLCK; obtain_lock(&logger_lock); if(fileno(stdin)>=0 || fileno(stdout)>=0 || fileno(stderr)>=0) { logger_syslog[LOG_WRITE] = stderr; /* If standard error is redirected, then use standard error as the log file. */ if(!isatty(STDOUT_FILENO) && !isatty(STDERR_FILENO)) { /* Ignore standard output to the extent that it is treated as standard error */ logger_hrdcpyfd = dup(STDOUT_FILENO); strlcpy(logger_filename, "STDOUT redirected from command line", sizeof(logger_filename)); if(dup2(STDERR_FILENO,STDOUT_FILENO) == -1) { fprintf(stderr, MSG(HHC02102, "E", "dup2()", strerror(errno))); exit(1); } } else { if(!isatty(STDOUT_FILENO)) { logger_hrdcpyfd = dup(STDOUT_FILENO); strlcpy(logger_filename, "STDOUT redirected from command line", sizeof(logger_filename)); if(dup2(STDERR_FILENO,STDOUT_FILENO) == -1) { fprintf(stderr, MSG(HHC02102, "E", "dup2()", strerror(errno))); exit(1); } } if(!isatty(STDERR_FILENO)) { strlcpy(logger_filename, "STDERR redirected from command line", sizeof(logger_filename)); logger_hrdcpyfd = dup(STDERR_FILENO); if(dup2(STDOUT_FILENO,STDERR_FILENO) == -1) { fprintf(stderr, MSG(HHC02102, "E", "dup2()", strerror(errno))); exit(1); } } } if(logger_hrdcpyfd == -1) { logger_hrdcpyfd = 0; fprintf(stderr, MSG(HHC02102, "E", "dup()", strerror(errno))); } if(logger_hrdcpyfd) { if(!(logger_hrdcpy = fdopen(logger_hrdcpyfd,"w"))) fprintf(stderr, MSG(HHC02102, "E", "fdopen()", strerror(errno))); } if(logger_hrdcpy) setvbuf(logger_hrdcpy, NULL, _IONBF, 0); } else { logger_syslog[LOG_WRITE]=fopen("LOG","a"); } logger_bufsize = LOG_DEFSIZE; if(!(logger_buffer = malloc(logger_bufsize))) { char buf[40]; MSGBUF(buf, "malloc(%d)", logger_bufsize); fprintf(stderr, MSG(HHC02102, "E", buf, strerror(errno))); exit(1); } if(create_pipe(logger_syslogfd)) { fprintf(stderr, MSG(HHC02102, "E", "create_pipe()", strerror(errno))); exit(1); /* Hercules running without syslog */ } setvbuf (logger_syslog[LOG_WRITE], NULL, _IONBF, 0); rc = create_thread (&logger_tid, JOINABLE, logger_thread, NULL, "logger_thread"); if (rc) { fprintf(stderr, MSG(HHC00102, "E", strerror(rc))); exit(1); } wait_condition(&logger_cond, &logger_lock); release_lock(&logger_lock); /* call logger_term on system shutdown */ hdl_adsc("logger_term",logger_term, NULL); }
/*-------------------------------------------------------------------*/ static void con1052_execute_ccw ( DEVBLK *dev, BYTE code, BYTE flags, BYTE chained, U32 count, BYTE prevcode, int ccwseq, BYTE *iobuf, BYTE *more, BYTE *unitstat, U32 *residual ) { U32 len; /* Length of data */ U32 num; /* Number of bytes to move */ BYTE c; /* Print character */ UNREFERENCED(chained); UNREFERENCED(prevcode); UNREFERENCED(ccwseq); /* Unit check with intervention required if no client connected */ if (dev->connected == 0 && !IS_CCW_SENSE(code)) { dev->sense[0] = SENSE_IR; *unitstat = CSW_UC; return; } /* Process depending on CCW opcode */ switch (code) { case 0x01: /*---------------------------------------------------------------*/ /* WRITE NO CARRIER RETURN */ /*---------------------------------------------------------------*/ case 0x09: /*---------------------------------------------------------------*/ /* WRITE AUTO CARRIER RETURN */ /*---------------------------------------------------------------*/ /* Calculate number of bytes to write and set residual count */ num = (count < BUFLEN_1052) ? count : BUFLEN_1052; *residual = count - num; /* Translate data in channel buffer to ASCII */ for (len = 0; len < num; len++) { c = guest_to_host(iobuf[len]); if (!isprint(c) && c != 0x0a && c != 0x0d) c = SPACE; iobuf[len] = c; } /* end for(len) */ /* Perform end of record processing if not data-chaining, and append carriage return and newline if required */ if ((flags & CCW_FLAGS_CD) == 0 && len < BUFLEN_1052 && 0x09 == code) iobuf[len++] = '\n'; iobuf[len] = '\0'; /* process multiline messages */ { char * str = (char *) iobuf; for (; str && *str;) { char * t = strchr(str, '\n'); if (t) *t++ = 0; #ifdef OPTION_MSGCLR #define CLR "<pnl,color(green,black)>" #else #define CLR "" #endif #ifdef OPTION_SCP_MSG_PREFIX WRCMSG (CLR, HHC00001, "I", str); #else /*!OPTION_SCP_MSG_PREFIX*/ logmsg (CLR "%s%s", str, (t ? "\n" : "")); #endif /*OPTION_SCP_MSG_PREFIX*/ str = t; } } /* Return normal status */ *unitstat = CSW_CE | CSW_DE; break; case 0x03: /*---------------------------------------------------------------*/ /* CONTROL NO-OPERATION */ /*---------------------------------------------------------------*/ *unitstat = CSW_CE | CSW_DE; break; case 0x0A: /*---------------------------------------------------------------*/ /* READ INQUIRY */ /*---------------------------------------------------------------*/ /* Solicit console input if no data in the device buffer */ if (!dev->keybdrem) { /* Display prompting message on console if allowed */ if (dev->prompt1052) WRCMSG ("<pnl,color(lightyellow,black)>", HHC00010, "A", SSID_TO_LCSS(dev->ssid), dev->devnum); obtain_lock(&dev->lock); dev->iowaiters++; wait_condition(&dev->iocond, &dev->lock); dev->iowaiters--; release_lock(&dev->lock); } /* Calculate number of bytes to move and residual byte count */ len = dev->keybdrem; num = (count < len) ? count : len; *residual = count - num; if (count < len) *more = 1; /* Copy data from device buffer to channel buffer */ memcpy (iobuf, dev->buf, num); /* If data chaining is specified, save remaining data */ if ((flags & CCW_FLAGS_CD) && len > count) { memmove (dev->buf, dev->buf + count, len - count); dev->keybdrem = len - count; } else { dev->keybdrem = 0; } /* Return normal status */ *unitstat = CSW_CE | CSW_DE; break; case 0x0B: /*---------------------------------------------------------------*/ /* AUDIBLE ALARM */ /*---------------------------------------------------------------*/ WRCMSG ("<pnl,color(lightred,black)>", HHC00009, "I"); /* *residual = 0; */ *unitstat = CSW_CE | CSW_DE; break; case 0x04: /*---------------------------------------------------------------*/ /* SENSE */ /*---------------------------------------------------------------*/ /* Calculate residual byte count */ num = (count < dev->numsense) ? count : dev->numsense; *residual = count - num; if (count < dev->numsense) *more = 1; /* Copy device sense bytes to channel I/O buffer */ memcpy (iobuf, dev->sense, num); /* Clear the device sense bytes */ memset( dev->sense, 0, sizeof(dev->sense) ); /* Return unit status */ *unitstat = CSW_CE | CSW_DE; break; case 0xE4: /*---------------------------------------------------------------*/ /* SENSE ID */ /*---------------------------------------------------------------*/ /* Calculate residual byte count */ num = (count < dev->numdevid) ? count : dev->numdevid; *residual = count - num; if (count < dev->numdevid) *more = 1; /* Copy device identifier bytes to channel I/O buffer */ memcpy (iobuf, dev->devid, num); /* Return unit status */ *unitstat = CSW_CE | CSW_DE; break; default: /*---------------------------------------------------------------*/ /* INVALID OPERATION */ /*---------------------------------------------------------------*/ /* Set command reject sense byte, and unit check status */ dev->sense[0] = SENSE_CR; *unitstat = CSW_CE | CSW_DE | CSW_UC; } /* end switch(code) */ } /* end function con1052_execute_ccw */
int vmw_fallback_wait(struct vmw_private *dev_priv, bool lazy, bool fifo_idle, uint32_t sequence, bool interruptible, unsigned long timeout) { struct vmw_fifo_state *fifo_state = &dev_priv->fifo; uint32_t count = 0; uint32_t signal_seq; int ret; unsigned long end_jiffies = jiffies + timeout; bool (*wait_condition)(struct vmw_private *, uint32_t); DEFINE_WAIT(__wait); wait_condition = (fifo_idle) ? &vmw_fifo_idle : &vmw_fence_signaled; /** * Block command submission while waiting for idle. */ if (fifo_idle) down_read(&fifo_state->rwsem); signal_seq = atomic_read(&dev_priv->fence_seq); ret = 0; for (;;) { prepare_to_wait(&dev_priv->fence_queue, &__wait, (interruptible) ? TASK_INTERRUPTIBLE : TASK_UNINTERRUPTIBLE); if (wait_condition(dev_priv, sequence)) break; if (time_after_eq(jiffies, end_jiffies)) { DRM_ERROR("SVGA device lockup.\n"); break; } if (lazy) schedule_timeout(1); else if ((++count & 0x0F) == 0) { /** * FIXME: Use schedule_hr_timeout here for * newer kernels and lower CPU utilization. */ __set_current_state(TASK_RUNNING); schedule(); __set_current_state((interruptible) ? TASK_INTERRUPTIBLE : TASK_UNINTERRUPTIBLE); } if (interruptible && signal_pending(current)) { ret = -ERESTARTSYS; break; } } finish_wait(&dev_priv->fence_queue, &__wait); if (ret == 0 && fifo_idle) { __le32 __iomem *fifo_mem = dev_priv->mmio_virt; iowrite32(signal_seq, fifo_mem + SVGA_FIFO_FENCE); } wake_up_all(&dev_priv->fence_queue); if (fifo_idle) up_read(&fifo_state->rwsem); return ret; }