<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                合規國際互聯網加速 OSASE為企業客戶提供高速穩定SD-WAN國際加速解決方案。 廣告
                ## 18.4.?ioctls 函數 在 struct tty_driver 中的 ioctl 函數被 tty 核心調用當 ioctl(2) 被在設備節點上調用. 如果這個 tty 驅動不知道如何處理傳遞給它的 ioctl 值, 它應當返回 -ENOIOCTLCMD 來試圖讓 tty 核心實現一個通用的調用版本. 2.6 內核定義了大約 70 個不同的 tty ioctls, 可被用來發送給一個 tty 驅動. 大部分的 tty 驅動不處理它們全部, 但是只有一個小的更普通的子集. 這是一個更通用的 tty ioctls 列表, 它們的含義, 以及如何實現它們: TIOCSERGETLSR 獲得這個 tty 設備的線路狀態寄存器( LSR )的值. TIOCGSERIAL 獲得串口線信息. 調用者可以潛在地從 tty 設備獲得許多串口線路信息, 在這個調用中一次全部. 一些程序( 例如 setserial 和 dip) 調用這個函數來確保波特率被正確設置, 以及來獲得通常的關于驅動控制的設備類型信息. 調用者傳遞一個指向一個大的 serial_struct 結構的指針, 這個結構應當由 tty 驅動填充正確的值. 這是一個如何實現這個的例子: ~~~ static int tiny_ioctl(struct tty_struct *tty, struct file *file, unsigned int cmd, unsigned long arg) { struct tiny_serial *tiny = tty->driver_data; if (cmd == TIOCGSERIAL) { struct serial_struct tmp; if (!arg) return -EFAULT; memset(&tmp, 0, sizeof(tmp)); tmp.type = tiny->serial.type; tmp.line = tiny->serial.line; tmp.port = tiny->serial.port; tmp.irq = tiny->serial.irq; tmp.flags = ASYNC_SKIP_TEST | ASYNC_AUTO_IRQ; tmp.xmit_fifo_size = tiny->serial.xmit_fifo_size; tmp.baud_base = tiny->serial.baud_base; tmp.close_delay = 5*HZ; tmp.closing_wait = 30*HZ; tmp.custom_divisor = tiny->serial.custom_divisor; tmp.hub6 = tiny->serial.hub6; tmp.io_type = tiny->serial.io_type; if (copy_to_user((void __user *)arg, &tmp, sizeof(tmp))) return -EFAULT; return 0; } return -ENOIOCTLCMD; } ~~~ TIOCSSERIAL 設置串口線路信息. 這是 IOCGSERIAL 的反面, 并且允許用戶一次全部設置 tty 設備的串口線狀態. 一個指向 struct serial_struct 的指針被傳遞給這個調用, 填滿這個 tty 設備應當被設置的數據. 如果這個 tty 驅動沒有實現這個調用, 大部分程序仍然正確工作. TIOCMIWAIT 等待 MSR 改變. 用戶在非尋常的情況下請求這個 ioctl, 它想在內核中睡眠直到這個 tty 設備的 MSR 寄存器發生某些事情. arg 參數包含用戶在等待的事件類型. 這通常用來等待直到一個狀態線變化, 指示有更多的數據發送給設備. 當實現這個 ioctl 時要小心, 并且不要使用 interruptible_sleep_on 調用, 因為它是不安全的(有很多不好的競爭條件涉及它). 相反, 一個 wait_queue 應當用來避免這個問題. 這是一個如何實現這個 ioctl 的例子: ~~~ static int tiny_ioctl(struct tty_struct *tty, struct file *file, unsigned int cmd, unsigned long arg) { struct tiny_serial *tiny = tty->driver_data; if (cmd == TIOCMIWAIT) { DECLARE_WAITQUEUE(wait, current); struct async_icount cnow; struct async_icount cprev; cprev = tiny->icount; while (1) { add_wait_queue(&tiny->wait, &wait); set_current_state(TASK_INTERRUPTIBLE); schedule(); remove_wait_queue(&tiny->wait, &wait); /* see if a signal woke us up */ if (signal_pending(current)) return -ERESTARTSYS; cnow = tiny->icount; if (cnow.rng == cprev.rng && cnow.dsr == cprev.dsr && cnow.dcd == cprev.dcd && cnow.cts == cprev.cts) return -EIO; /* no change => error */ if (((arg & TIOCM_RNG) && (cnow.rng != cprev.rng)) || ((arg & TIOCM_DSR) && (cnow.dsr != cprev.dsr)) || ((arg & TIOCM_CD) && (cnow.dcd != cprev.dcd)) || ((arg & TIOCM_CTS) && (cnow.cts != cprev.cts)) ) { return 0; } cprev = cnow; } } return -ENOIOCTLCMD; } ~~~ 在 tty 驅動的代碼中能知道 MSR 寄存器改變的某些地方, 下面的代碼行必須調用以便這個代碼能正常工作: ~~~ wake_up_interruptible(&tp->wait); ~~~ TIOCGICOUNT 獲得中斷計數. 當用戶要知道已經產生多少串口線中斷時調用. 如果驅動有一個中斷處理, 它應當定義一個內部計數器結構來跟蹤這些統計和遞增適當的計數器, 每次這個函數被內核運行時. 這個 ioctl 調用傳遞內核一個指向結構 serial_icounter_struct 的指針, 它應當被 tty 驅動填充. 這個調用常常和之前的 IOCMIWAIT ioctl 調用結合使用. 如果 tty 驅動跟蹤所有的這些中斷在驅動操作時, 實現這個調用的代碼會非常簡單: ~~~ static int tiny_ioctl(struct tty_struct *tty, struct file *file, unsigned int cmd, unsigned long arg) { struct tiny_serial *tiny = tty->driver_data; if (cmd == TIOCGICOUNT) { struct async_icount cnow = tiny->icount; struct serial_icounter_struct icount; icount.cts = cnow.cts; icount.dsr = cnow.dsr; icount.rng = cnow.rng; icount.dcd = cnow.dcd; icount.rx = cnow.rx; icount.tx = cnow.tx; icount.frame = cnow.frame; icount.overrun = cnow.overrun; icount.parity = cnow.parity; icount.brk = cnow.brk; icount.buf_overrun = cnow.buf_overrun; if (copy_to_user((void __user *)arg, &icount, sizeof(icount))) return -EFAULT; return 0; } return -ENOIOCTLCMD; } ~~~
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看