Driver/tiny_tty/tiny_ioctl()

Last-modified: 2007-09-26 (水) 14:11:45

387 :#define tiny_ioctl tiny_ioctl_tiocgserial
388 :static int tiny_ioctl(struct tty_struct *tty, struct file *file,
389 : unsigned int cmd, unsigned long arg)
390 :{
391 : struct tiny_serial *tiny = tty->driver_data;
392 :
393 : if (cmd == TIOCGSERIAL) {

get Serial.

394 : struct serial_struct tmp;
395 :
396 : if (!arg)
397 : return -EFAULT;
398 :
399 : memset(&tmp, 0, sizeof(tmp));
400 :
401 : tmp.type = tiny->serial.type;
402 : tmp.line = tiny->serial.line;
403 : tmp.port = tiny->serial.port;
404 : tmp.irq = tiny->serial.irq;
405 : tmp.flags = ASYNC_SKIP_TEST | ASYNC_AUTO_IRQ;
406 : tmp.xmit_fifo_size = tiny->serial.xmit_fifo_size;
407 : tmp.baud_base = tiny->serial.baud_base;
408 : tmp.close_delay = 5*HZ;
409 : tmp.closing_wait = 30*HZ;
410 : tmp.custom_divisor = tiny->serial.custom_divisor;
411 : tmp.hub6 = tiny->serial.hub6;
412 : tmp.io_type = tiny->serial.io_type;
413 :
414 : if (copy_to_user*1)

取得したtmp構造体をユーザスペースへ送る

415 : return -EFAULT;
416 : return 0;
417 : }
418 : return -ENOIOCTLCMD;
419 :}
420 :#undef tiny_ioctl
421 :
422 :#define tiny_ioctl tiny_ioctl_tiocmiwait
423 :static int tiny_ioctl(struct tty_struct *tty, struct file *file,
424 : unsigned int cmd, unsigned long arg)

これって指定時間だけ待つということ?

425 :{
426 : struct tiny_serial *tiny = tty->driver_data;
427 :
428 : if (cmd == TIOCMIWAIT) {
429 : DECLARE_WAITQUEUE(wait, current);
430 : struct async_icount cnow;
431 : struct async_icount cprev;
432 :
433 : cprev = tiny->icount;
434 : while (1) {
435 : add_wait_queue(&tiny->wait, &wait);
436 : set_current_state(TASK_INTERRUPTIBLE);
437 : schedule();
438 : remove_wait_queue(&tiny->wait, &wait);
439 :
440 : /* see if a signal woke us up */
441 : if (signal_pending(current))
442 : return -ERESTARTSYS;
443 :
444 : cnow = tiny->icount;
445 : if (cnow.rng == cprev.rng && cnow.dsr == cprev.dsr &&
446 : cnow.dcd == cprev.dcd && cnow.cts == cprev.cts)
447 : return -EIO; /* no change => error */
448 : if *2 ||
449 : *3 ||
450 : *4 ||
451 : *5 ) {
452 : return 0;
453 : }
454 : cprev = cnow;
455 : }
456 :
457 : }
458 : return -ENOIOCTLCMD;
459 :}
460 :#undef tiny_ioctl
462 :#define tiny_ioctl tiny_ioctl_tiocgicount
463 :static int tiny_ioctl(struct tty_struct *tty, struct file *file,
464 : unsigned int cmd, unsigned long arg)
465 :{
466 : struct tiny_serial *tiny = tty->driver_data;
467 :
468 : if (cmd == TIOCGICOUNT) {
469 : struct async_icount cnow = tiny->icount;

async_icountを返すけど、これは何の情報?

470 : struct serial_icounter_struct icount;
471 :
472 : icount.cts = cnow.cts;
473 : icount.dsr = cnow.dsr;
474 : icount.rng = cnow.rng;
475 : icount.dcd = cnow.dcd;
476 : icount.rx = cnow.rx;
477 : icount.tx = cnow.tx;
478 : icount.frame = cnow.frame;
479 : icount.overrun = cnow.overrun;
480 : icount.parity = cnow.parity;
481 : icount.brk = cnow.brk;
482 : icount.buf_overrun = cnow.buf_overrun;
483 :
484 : if (copy_to_user*6)
485 : return -EFAULT;
486 : return 0;
487 : }
488 : return -ENOIOCTLCMD;
489 :}
490 :#undef tiny_ioctl

492 :/* the real tiny_ioctl function. The above is done to get the small functions in the book */
493 :static int tiny_ioctl(struct tty_struct *tty, struct file *file,
494 : unsigned int cmd, unsigned long arg)
495 :{
496 : switch (cmd) {
497 : case TIOCGSERIAL:
498 : return tiny_ioctl_tiocgserial(tty, file, cmd, arg);
499 : case TIOCMIWAIT:
500 : return tiny_ioctl_tiocmiwait(tty, file, cmd, arg);
501 : case TIOCGICOUNT:
502 : return tiny_ioctl_tiocgicount(tty, file, cmd, arg);
503 : }
504 :
505 : return -ENOIOCTLCMD;
506 :}


*1 void __user *)arg, &tmp, sizeof(struct serial_struct
*2 (arg & TIOCM_RNG) && (cnow.rng != cprev.rng
*3 arg & TIOCM_DSR) && (cnow.dsr != cprev.dsr
*4 arg & TIOCM_CD) && (cnow.dcd != cprev.dcd
*5 arg & TIOCM_CTS) && (cnow.cts != cprev.cts
*6 void __user *)arg, &icount, sizeof(icount