tty/module.c
changeset 1786 7198caede741
parent 1782 2ba454c790c5
child 1787 439f186185be
equal deleted inserted replaced
1785:9ed0334edaf9 1786:7198caede741
    64 
    64 
    65 static struct tty_driver *tty_driver = NULL;
    65 static struct tty_driver *tty_driver = NULL;
    66 ec_tty_t *ttys[EC_TTY_MAX_DEVICES];
    66 ec_tty_t *ttys[EC_TTY_MAX_DEVICES];
    67 struct semaphore tty_sem;
    67 struct semaphore tty_sem;
    68 
    68 
       
    69 void ec_tty_wakeup(unsigned long);
       
    70 
    69 /*****************************************************************************/
    71 /*****************************************************************************/
    70 
    72 
    71 /** \cond */
    73 /** \cond */
    72 
    74 
    73 MODULE_AUTHOR("Florian Pose <fp@igh-essen.com>");
    75 MODULE_AUTHOR("Florian Pose <fp@igh-essen.com>");
   175     tty_unregister_driver(tty_driver);
   177     tty_unregister_driver(tty_driver);
   176     put_tty_driver(tty_driver);
   178     put_tty_driver(tty_driver);
   177     printk(KERN_INFO PFX "Module unloading.\n");
   179     printk(KERN_INFO PFX "Module unloading.\n");
   178 }
   180 }
   179 
   181 
   180 /*****************************************************************************/
   182 /******************************************************************************
   181 
   183  * ec_tty_t methods.
   182 unsigned int ec_tty_tx_size(ec_tty_t *tty)
   184  *****************************************************************************/
   183 {
       
   184     unsigned int ret;
       
   185     
       
   186     if (tty->tx_write_idx >= tty->tx_read_idx) {
       
   187         ret = tty->tx_write_idx - tty->tx_read_idx;
       
   188     } else {
       
   189         ret = EC_TTY_TX_BUFFER_SIZE + tty->tx_write_idx - tty->tx_read_idx;
       
   190     }
       
   191 
       
   192     return ret;
       
   193 }
       
   194 
       
   195 /*****************************************************************************/
       
   196 
       
   197 unsigned int ec_tty_tx_space(ec_tty_t *tty)
       
   198 {
       
   199     return EC_TTY_TX_BUFFER_SIZE - 1 - ec_tty_tx_size(tty);
       
   200 }
       
   201 
       
   202 /*****************************************************************************/
       
   203 
       
   204 unsigned int ec_tty_rx_size(ec_tty_t *tty)
       
   205 {
       
   206     unsigned int ret;
       
   207     
       
   208     if (tty->rx_write_idx >= tty->rx_read_idx) {
       
   209         ret = tty->rx_write_idx - tty->rx_read_idx;
       
   210     } else {
       
   211         ret = EC_TTY_RX_BUFFER_SIZE + tty->rx_write_idx - tty->rx_read_idx;
       
   212     }
       
   213 
       
   214     return ret;
       
   215 }
       
   216 
       
   217 /*****************************************************************************/
       
   218 
       
   219 unsigned int ec_tty_rx_space(ec_tty_t *tty)
       
   220 {
       
   221     return EC_TTY_RX_BUFFER_SIZE - 1 - ec_tty_rx_size(tty);
       
   222 }
       
   223 
       
   224 /*****************************************************************************/
       
   225 
       
   226 void ec_tty_wakeup(unsigned long data)
       
   227 {
       
   228     ec_tty_t *tty = (ec_tty_t *) data;
       
   229     size_t to_recv;
       
   230 
       
   231     /* Wake up any process waiting to send data */
       
   232     if (tty->wakeup) {
       
   233         if (tty->tty) {
       
   234 #if EC_TTY_DEBUG >= 1
       
   235             printk(KERN_INFO PFX "Waking up.\n");
       
   236 #endif
       
   237             tty_wakeup(tty->tty);
       
   238         }
       
   239         tty->wakeup = 0;
       
   240     }
       
   241 
       
   242     /* Push received data into TTY core. */
       
   243     to_recv = ec_tty_rx_size(tty);
       
   244     if (to_recv && tty->tty) {
       
   245         unsigned char *cbuf;
       
   246         int space = tty_prepare_flip_string(tty->tty, &cbuf, to_recv);
       
   247 
       
   248         if (space < to_recv) {
       
   249             printk(KERN_WARNING PFX "Insufficient space to_recv=%d space=%d\n",
       
   250                     to_recv, space);
       
   251         }
       
   252 
       
   253         if (space < 0) {
       
   254             to_recv = 0;
       
   255         } else {
       
   256             to_recv = space;
       
   257         }
       
   258 
       
   259         if (to_recv) {
       
   260             unsigned int i;
       
   261 
       
   262 #if EC_TTY_DEBUG >= 1
       
   263             printk(KERN_INFO PFX "Pushing %u bytes to TTY core.\n", to_recv);
       
   264 #endif
       
   265 
       
   266             for (i = 0; i < to_recv; i++) {
       
   267                 cbuf[i] = tty->rx_buffer[tty->rx_read_idx];
       
   268                 tty->rx_read_idx = (tty->rx_read_idx + 1) % EC_TTY_RX_BUFFER_SIZE;
       
   269             }
       
   270             tty_flip_buffer_push(tty->tty);
       
   271         }
       
   272     }
       
   273     
       
   274     tty->timer.expires += 1;
       
   275     add_timer(&tty->timer);
       
   276 }
       
   277 
       
   278 /*****************************************************************************/
       
   279 
   185 
   280 int ec_tty_init(ec_tty_t *tty, int minor,
   186 int ec_tty_init(ec_tty_t *tty, int minor,
   281         int (*cflag_cb)(void *, tcflag_t), void *cb_data)
   187         int (*cflag_cb)(void *, tcflag_t), void *cb_data)
   282 {
   188 {
   283     tty->minor = minor;
   189     tty->minor = minor;
   312     tty_unregister_device(tty_driver, tty->minor);
   218     tty_unregister_device(tty_driver, tty->minor);
   313 }
   219 }
   314 
   220 
   315 /*****************************************************************************/
   221 /*****************************************************************************/
   316 
   222 
       
   223 unsigned int ec_tty_tx_size(ec_tty_t *tty)
       
   224 {
       
   225     unsigned int ret;
       
   226     
       
   227     if (tty->tx_write_idx >= tty->tx_read_idx) {
       
   228         ret = tty->tx_write_idx - tty->tx_read_idx;
       
   229     } else {
       
   230         ret = EC_TTY_TX_BUFFER_SIZE + tty->tx_write_idx - tty->tx_read_idx;
       
   231     }
       
   232 
       
   233     return ret;
       
   234 }
       
   235 
       
   236 /*****************************************************************************/
       
   237 
       
   238 unsigned int ec_tty_tx_space(ec_tty_t *tty)
       
   239 {
       
   240     return EC_TTY_TX_BUFFER_SIZE - 1 - ec_tty_tx_size(tty);
       
   241 }
       
   242 
       
   243 /*****************************************************************************/
       
   244 
       
   245 unsigned int ec_tty_rx_size(ec_tty_t *tty)
       
   246 {
       
   247     unsigned int ret;
       
   248     
       
   249     if (tty->rx_write_idx >= tty->rx_read_idx) {
       
   250         ret = tty->rx_write_idx - tty->rx_read_idx;
       
   251     } else {
       
   252         ret = EC_TTY_RX_BUFFER_SIZE + tty->rx_write_idx - tty->rx_read_idx;
       
   253     }
       
   254 
       
   255     return ret;
       
   256 }
       
   257 
       
   258 /*****************************************************************************/
       
   259 
       
   260 unsigned int ec_tty_rx_space(ec_tty_t *tty)
       
   261 {
       
   262     return EC_TTY_RX_BUFFER_SIZE - 1 - ec_tty_rx_size(tty);
       
   263 }
       
   264 
       
   265 /*****************************************************************************/
       
   266 
   317 int ec_tty_get_serial_info(ec_tty_t *tty, struct serial_struct *data)
   267 int ec_tty_get_serial_info(ec_tty_t *tty, struct serial_struct *data)
   318 {
   268 {
   319     struct serial_struct tmp;
   269     struct serial_struct tmp;
   320 
   270 
   321     if (!data)
   271     if (!data)
   325 
   275 
   326     if (copy_to_user(data, &tmp, sizeof(*data))) {
   276     if (copy_to_user(data, &tmp, sizeof(*data))) {
   327         return -EFAULT;
   277         return -EFAULT;
   328     }
   278     }
   329     return 0;
   279     return 0;
       
   280 }
       
   281 
       
   282 /*****************************************************************************/
       
   283 
       
   284 /** Timer function.
       
   285  */
       
   286 void ec_tty_wakeup(unsigned long data)
       
   287 {
       
   288     ec_tty_t *tty = (ec_tty_t *) data;
       
   289     size_t to_recv;
       
   290 
       
   291     /* Wake up any process waiting to send data */
       
   292     if (tty->wakeup) {
       
   293         if (tty->tty) {
       
   294 #if EC_TTY_DEBUG >= 1
       
   295             printk(KERN_INFO PFX "Waking up.\n");
       
   296 #endif
       
   297             tty_wakeup(tty->tty);
       
   298         }
       
   299         tty->wakeup = 0;
       
   300     }
       
   301 
       
   302     /* Push received data into TTY core. */
       
   303     to_recv = ec_tty_rx_size(tty);
       
   304     if (to_recv && tty->tty) {
       
   305         unsigned char *cbuf;
       
   306         int space = tty_prepare_flip_string(tty->tty, &cbuf, to_recv);
       
   307 
       
   308         if (space < to_recv) {
       
   309             printk(KERN_WARNING PFX "Insufficient space to_recv=%d space=%d\n",
       
   310                     to_recv, space);
       
   311         }
       
   312 
       
   313         if (space < 0) {
       
   314             to_recv = 0;
       
   315         } else {
       
   316             to_recv = space;
       
   317         }
       
   318 
       
   319         if (to_recv) {
       
   320             unsigned int i;
       
   321 
       
   322 #if EC_TTY_DEBUG >= 1
       
   323             printk(KERN_INFO PFX "Pushing %u bytes to TTY core.\n", to_recv);
       
   324 #endif
       
   325 
       
   326             for (i = 0; i < to_recv; i++) {
       
   327                 cbuf[i] = tty->rx_buffer[tty->rx_read_idx];
       
   328                 tty->rx_read_idx =
       
   329                     (tty->rx_read_idx + 1) % EC_TTY_RX_BUFFER_SIZE;
       
   330             }
       
   331             tty_flip_buffer_push(tty->tty);
       
   332         }
       
   333     }
       
   334     
       
   335     tty->timer.expires += 1;
       
   336     add_timer(&tty->timer);
   330 }
   337 }
   331 
   338 
   332 /******************************************************************************
   339 /******************************************************************************
   333  * Device callbacks
   340  * Device callbacks
   334  *****************************************************************************/
   341  *****************************************************************************/
   731             printk(KERN_WARNING PFX "Dropping %u bytes.\n", size - to_recv);
   738             printk(KERN_WARNING PFX "Dropping %u bytes.\n", size - to_recv);
   732         }
   739         }
   733 
   740 
   734         for (i = 0; i < size; i++) {
   741         for (i = 0; i < size; i++) {
   735             tty->rx_buffer[tty->rx_write_idx] = buffer[i];
   742             tty->rx_buffer[tty->rx_write_idx] = buffer[i];
   736             tty->rx_write_idx = (tty->rx_write_idx + 1) % EC_TTY_RX_BUFFER_SIZE;
   743             tty->rx_write_idx =
       
   744                 (tty->rx_write_idx + 1) % EC_TTY_RX_BUFFER_SIZE;
   737         }
   745         }
   738     }
   746     }
   739 }
   747 }
   740 
   748 
   741 /*****************************************************************************/
   749 /*****************************************************************************/