home *** CD-ROM | disk | FTP | other *** search
/ NetNews Usenet Archive 1992 #19 / NN_1992_19.iso / spool / comp / unix / internal / 1754 < prev    next >
Encoding:
Internet Message Format  |  1992-08-27  |  2.8 KB

  1. From: aakash@hpcupt3.cup.hp.com (Aakash Sahai)
  2. Date: Wed, 26 Aug 1992 18:14:19 GMT
  3. Subject: Re: How to sleep in device driver with a time out
  4. Message-ID: <46520024@hpcupt3.cup.hp.com>
  5. Organization: Hewlett Packard, Cupertino
  6. Path: sparky!uunet!usc!sdd.hp.com!hpscdc!hplextra!hpcc05!hpcuhb!hpcupt3!aakash
  7. Newsgroups: comp.unix.internals
  8. References: <1992Aug24.024748.865@candle.uucp>
  9. Lines: 97
  10.  
  11. > I assume you call timeout(function_address, int_parameter, time_in_ms)
  12. > and then go to sleep().  If the timeout period expires, the function
  13. > gets called with your parameter and you can return to user mode normally.
  14. > Is this correct?  Do I have the parameters correct?
  15.  
  16. The last argument to timeout is generally specified in terms of HZ parameter.
  17. where HZ = number of ticks per second generated by timer. For example, if HZ
  18. equals 100 and you specify the last parameter as 7 then the timeout will occur
  19. after 7/100 th of a second ( 70 ms ).
  20.  
  21. Normally, in such condition when an operation has to be aborted mid-way because
  22. of timeout, a code sequence of the following form can be used -
  23.  
  24. /* Routine called by timeout.  */
  25.  
  26. int    ErrorOccurred;
  27.  
  28. OpnTimedOut(SleepAddr)
  29. caddr_t    SleepAddr;
  30. {
  31.     ErrorOccurred++;
  32.     wakeup (SleepAddr);
  33. }
  34.  
  35.     ...
  36. /* Routine doing actual I/O and setting the timeout */
  37. {
  38.     ...
  39.  
  40.     /* Start the actual I/O */
  41.     /* Block device interrupts */
  42.     if ( ! I/O Done ) {    /* No need to sleep if we have already got */
  43.                 /* an interrupt quick enough */
  44.         ErrorOccurred = 0;
  45.         /* Block Clock interrupts */
  46.         id = timeout ( OpnTimedOut, SleepAddr, timeout_value );
  47.         sleep ( SleepAddr, priority );
  48.         if ( ! ErrorOcurred ) { /* Device responded and we were */
  49.                     /* woken up by ISR */
  50.             untimeout ( id );
  51.             /* Unblock clock and device interrupts */
  52.             /* Do the normal processing */
  53.         } else {
  54.             ErrorOcurred = 0;
  55.             /* Unblock clock interrupt */
  56.             /* Code to reset the controller etc. */
  57.             /* Unblock device interrupt */
  58.             /* Return error etc.*/
  59.         }
  60.     }
  61.         ....
  62. }
  63.  
  64. NOTE :    This is just a skeleton and actual code may vary depending on the
  65.     capability of the controller and/or driver design style. 
  66.     
  67. > Also, how do I return a status to a C program from a device driver
  68. > ioctl function?
  69.  
  70. Probably, you can declare a structure and pass a pointer to this structure
  71. from the user level program as the third argument to ioctl. Then in your
  72. driver you can do a "copyout()" of the status to the area pointed to by
  73. this pointer.
  74.  
  75. That is -
  76.  
  77. /* User program */
  78. struct    status    ret_status;
  79.  
  80.         ....
  81.         ....
  82.  
  83.     ret = ioctl ( fd, cmd, &ret_status );
  84.  
  85.         ...
  86.  
  87. /* Kernel code in the driver */
  88.  
  89. dev_ioctl ( dev, cmd, arg )
  90. {
  91. struct    status    dev_status;
  92.         ....
  93.         ....
  94.  
  95.     copyout (dev_status, (struct status *)arg, sizeof(struct status));
  96.         
  97.         ....
  98. }
  99.  
  100.  
  101. -- Aakash Sahai
  102.  
  103. /*
  104.  * Yeah, you are right - HP is not responsible for what I write.
  105.  */
  106.