sanpai

Device Drivers notes

May 22nd, 2016
84
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 42.91 KB | None | 0 0
  1. User and Kernel space
  2.  
  3. When you write device drivers, it’s important to make the distinction between “user space" and “kernel space".
  4.  
  5. Kernel space
  6. Linux (which is a kernel) manages the machine's hardware in a simple and efficient manner, offering the user a simple and uniform programming interface.
  7. In the same way, the kernel, and in particular its device drivers, form a bridge or interface between the end-user/programmer and the hardware.
  8. Any subroutines or functions forming part of the kernel (modules and device drivers, for example) are considered to be part of kernel space.
  9.  
  10. User space
  11. End-user programs, like the UNIX shell or other GUI based applications (kpresenter for example), are part of the user space.
  12. Obviously, these applications need to interact with the system's hardware .
  13. However, they don’t do so directly, but through the kernel supported functions.
  14.  
  15. Interfacing functions between user space and kernel space
  16.  
  17. The kernel offers several subroutines or functions in user space, which allow the end-user application programmer to interact with the hardware.
  18. Usually, in UNIX or Linux systems, this dialogue is performed through functions or subroutines in order to read and write files.
  19. The reason for this is that in Unix devices are seen, from the point of view of the user, as files.
  20.  
  21. On the other hand, in kernel space Linux also offers several functions or subroutines to perform the low level interactions directly with the hardware, and allow the transfer of information from kernel to user space.
  22.  
  23. User space(apps ) <--> Kernel space (drivers and modules) <--> hardware
  24.  
  25. The insmod command allows the installation of the module in the kernel.
  26. ex # insmod nothing.ko
  27.  
  28. lsmod - Used to list the modules inztalled in the system .
  29.  
  30. rmmod - used to remove module from the kernel .
  31.  
  32. modprobe
  33.  
  34. --Modprobe utility is used to add loadable modules to the Linux kernel. You can also view and remove modules using modprobe command.
  35.  
  36. modprobe -l will display all available modules as shown below.
  37.  
  38. $ modprobe -l | less
  39. kernel/arch/x86/kernel/cpu/mcheck/mce-inject.ko
  40. kernel/arch/x86/kernel/cpu/cpufreq/e_powersaver.ko
  41. kernel/arch/x86/kernel/cpu/cpufreq/p4-clockmod.ko
  42. kernel/arch/x86/kernel/msr.ko
  43. kernel/arch/x86/kernel/cpuid.ko
  44. kernel/arch/x86/kernel/apm.ko
  45. kernel/arch/x86/kernel/scx200.ko
  46. kernel/arch/x86/kernel/microcode.ko
  47. kernel/arch/x86/crypto/aes-i586.ko
  48. kernel/arch/x86/crypto/twofish-i586.ko
  49.  
  50. Following example loads vmhgfs module to Linux kernel
  51.  
  52. sudo modprobe vmhgfs
  53.  
  54. modprobe -r option to unload a module from the kernel
  55.  
  56. modprobe -r vmhgfs
  57.  
  58. Classes of Devices and Modules
  59.  
  60. The Linux way of looking at devices distinguishes between three fundamental device types. Each module usually implements one of these types, and thus is classifiable as a char module, a block module, or a network module.
  61.  
  62. Character devices
  63.  
  64. --A character (char) device is one that can be accessed as a stream of bytes (like a file).
  65. -- The only relevant difference between a char device and a regular file is that you can always move back and forth in the regular file, whereas most char devices are just data channels.
  66.  
  67. Block devices
  68.  
  69. A block device is a device (e.g., a disk) that can host a filesystem. In most Unix systems, a block device can only handle I/O operations that transfer one or more whole blocks, which are usually 512 bytes (or a larger power of two) bytes in length.
  70.  
  71. Linux, instead, allows the application to read and write a block device like a char device—it permits the transfer of any number of bytes at a time. As a result, block and char devices differ only in the way data is managed internally by the kernel, and thus in the kernel/driver software interface.
  72.  
  73. Network interfaces
  74.  
  75. Any network transaction is made through an interface, that is, a device that is able to exchange data with other hosts. Usually, an interface is a hardware device, but it might also be a pure software device, like the loopback interface. A network interface is in charge of sending and receiving data packets, driven by the network subsystem of the kernel, without knowing how individual transactions map to the actual packets being transmitted. Many network connections (especially those using TCP) are stream-oriented, but network devices are, usually, designed around the transmission and receipt of packets.
  76.  
  77. The “Hello world" driver: loading and removing the driver in kernel space
  78.  
  79. When a module device driver is loaded into the kernel, some preliminary tasks are usually performed like resetting the device, reserving RAM, reserving interrupts, and reserving input/output ports, etc.
  80.  
  81. These tasks are performed, in kernel space, by two functions which need to be present (and explicitly declared): module_init and module_exit; they correspond to the user space commands insmod and rmmod , which are used when installing or removing a module.
  82. To sum up, the user commands insmod and rmmod use the kernel space functions module_init and module_exit.
  83.  
  84.  
  85. #include <linux/init.h>
  86. #include <linux/module.h>
  87. #include <linux/kernel.h>
  88.  
  89. MODULE_LICENSE("Dual BSD/GPL");
  90.  
  91. static int hello_init(void) {
  92. printk("<1> Hello world!\n");
  93. return 0;
  94. }
  95.  
  96. static void hello_exit(void) {
  97. printk("<1> Bye, cruel world\n");
  98. }
  99.  
  100. module_init(hello_init);
  101. module_exit(hello_exit);
  102.  
  103. In order for functions to be identified as the corresponding loading and removing functions, they have to be passed as parameters to the functions module_init and module_exit.
  104.  
  105. The printk function has also been introduced. It is very similar to the well known printf apart from the fact that it only works inside the kernel.
  106. The <1> symbol shows the high priority of the message (low number).
  107. In this way, besides getting the message in the kernel system log files, you should also receive this message in the system console.
  108.  
  109. When the module is loaded or removed, the messages that were written in the printk statement will be displayed in the system console.
  110. If these messages do not appear in the console, you can view them by issuing the dmesg command or by looking at the system log file with cat /var/log/syslog.
  111.  
  112. In UNIX and Linux, devices are accessed from user space in exactly the same way as files are accessed. These device files are normally subdirectories of the /dev directory.
  113.  
  114. -To link normal files with a kernel module two numbers are used: major number and minor number. The major number is the one the kernel uses to link a file with its driver.
  115. The minor number is for internal use of the device.
  116.  
  117. -The major number identifies the driver associated with the device.
  118. -The minor number is used by the kernel to determine exactly which device is being referred to.
  119.  
  120. To achieve this, a file (which will be used to access the device driver) must be created, by typing the following command as root:
  121.  
  122. # mknod /dev/memory c 60 0
  123.  
  124. In the above, c means that a char device is to be created, 60 is the major number and 0 is the minor number.
  125.  
  126. Within the driver, in order to link it with its corresponding /dev file in kernel space, the register_chrdev function is used.
  127. It is called with three arguments: major number, a string of characters showing the module name, and a file_operations structure which links the call with the file functions it defines
  128.  
  129. int memory_init(void) {
  130. int result;
  131.  
  132. /* Registering device */
  133. result = register_chrdev(memory_major, "memory", &memory_fops);
  134. if (result < 0) {
  135. printk(
  136. "<1>memory: cannot obtain major number %d\n", memory_major);
  137. return result;
  138. }
  139.  
  140. /* Allocating memory for the buffer */
  141. memory_buffer = kmalloc(1, GFP_KERNEL);
  142. if (!memory_buffer) {
  143. result = -ENOMEM;
  144. goto fail;
  145. }
  146. memset(memory_buffer, 0, 1);
  147.  
  148. printk("<1>Inserting memory module\n");
  149. return 0;
  150.  
  151. fail:
  152. memory_exit();
  153. return result;
  154. }
  155.  
  156. If you pass a major number of 0 to register_chrdev, the return value will be the dynamically allocated major number. The downside is that you can't make a device file in advance, since you don't know what the major number will be. There are a couple of ways to do this. First, the driver itself can print the newly assigned number and we can make the device file by hand. Second, the newly registered device will have an entry in /proc/devices, and we can either make the device file by hand or write a shell script to read the file in and make the device file. The third method is we can have our driver make the the device file using the mknod system call after a successful registration and rm during the call to cleanup_module.
  157.  
  158.  
  159.  
  160. Also, note the use of the kmalloc function. This function is used for memory allocation of the buffer in the device driver which resides in kernel space.
  161. Its use is very similar to the well known malloc function. Finally, if registering the major number or allocating the memory fails, the module acts accordingly.
  162.  
  163.  
  164. In order to remove the module inside the memory_exit function, the function unregsiter_chrdev needs to be present. This will free the major number for the kernel.
  165.  
  166. <memory exit module> =
  167.  
  168. void memory_exit(void) {
  169. /* Freeing the major number */
  170. unregister_chrdev(memory_major, "memory");
  171.  
  172. /* Freeing buffer memory */
  173. if (memory_buffer) {
  174. kfree(memory_buffer);
  175. }
  176.  
  177. printk("<1>Removing memory module\n");
  178.  
  179. }
  180.  
  181. Open
  182.  
  183. The kernel space function, which corresponds to opening a file in user space (fopen), is the member open: of the file_operations structure in the call to register_chrdev.
  184. In this case, it is the memory_open function. It takes as arguments: an inode structure(data structure holds information about a file or directory on disk.), which sends information to the kernel regarding the major number and minor number; and a file structure with information relative to the different operations that can be performed on a file.
  185.  
  186. int memory_open(struct inode *inode, struct file *filp) {
  187.  
  188. /* Success */
  189. return 0;
  190. }
  191.  
  192. Close
  193.  
  194. The corresponding function for closing a file in user space (fclose) is the release: member of the file_operations structure in the call to register_chrdev.
  195. In this particular case, it is the function memory_release, which has as arguments an inode structure and a file structure, just like before.
  196.  
  197. When a file is closed, it’s usually necessary to free the used memory and any variables related to the opening of the device.
  198.  
  199.  
  200. int memory_release(struct inode *inode, struct file *filp) {
  201.  
  202. /* Success */
  203. return 0;
  204. }
  205.  
  206. Read
  207.  
  208. o read a device with the user function fread or similar, the member read: of the file_operations structure is used in the call to register_chrdev.
  209. This time, it is the function memory_read. Its arguments are: a type file structure; a buffer (buf), from which the user space function (fread) will read; a counter with the number of bytes to transfer (count), which has the same value as the usual counter in the user space function (fread);
  210. and finally, the position of where to start reading the file (f_pos).
  211.  
  212.  
  213. ssize_t memory_read(struct file *filp, char *buf,
  214. size_t count, loff_t *f_pos) {
  215.  
  216. /* Transfering data to user space */
  217. copy_to_user(buf,memory_buffer,1);
  218.  
  219. /* Changing reading position as best suits */
  220. if (*f_pos == 0) {
  221. *f_pos+=1;
  222. return 1;
  223. } else {
  224. return 0;
  225. }
  226. }
  227.  
  228. Write
  229.  
  230. To write to a device with the user function fwrite or similar, the member write: of the file_operations structure is used in the call to register_chrdev.
  231. It is the function memory_write, in this particular example, which has the following as arguments: a type file structure; buf, a buffer in which the user space function (fwrite) will write;
  232. count, a counter with the number of bytes to transfer, which has the same values as the usual counter in the user space function (fwrite); and finally, f_pos, the position of where to start writing in the file.
  233.  
  234. <memory write> =
  235.  
  236. ssize_t memory_write( struct file *filp, char *buf,
  237. size_t count, loff_t *f_pos) {
  238.  
  239. char *tmp;
  240.  
  241. tmp=buf+count-1; // writes only the last charecter to the device .
  242. copy_from_user(memory_buffer,tmp,1);
  243. return 1;
  244. }
  245.  
  246. Communicating with hardware
  247.  
  248. I/O Ports and I/O Memory
  249.  
  250. Every peripheral device is controlled by writing and reading its registers.
  251. Most of the time a device has several registers, and they are accessed at consecutive addresses, either in the memory address space or in the I/O address space.
  252.  
  253. At the hardware level, there is no conceptual difference between memory regions and I/O regions: both of them are accessed by asserting electrical signals on the address bus and control bus (i.e., the read and write signals)[1]
  254. and by reading from or writing to the data bus.
  255.  
  256. Memory Barriers
  257.  
  258. Memory barriers are used to provide control over the order of memory accesses.
  259. This is necessary sometimes because optimizations performed by the compiler and hardware can cause memory to be accessed in a different order than intended by the developer.
  260.  
  261. A memory barrier affects instructions that access memory in two ways:
  262.  
  263. provides control over the order that memory access instructions are performed, and
  264. provides control over when memory access instructions will complete.
  265.  
  266. Memory access instructions, such as loads and stores, typically take longer to execute than other instructions. Therefore, compilers use registers to hold frequently used values and processors use high speed caches to hold the most frequently used memory locations.
  267. Another common optimization is for compilers and processors to rearrange the order that instructions are executed so that the processor does not have to wait for memory accesses to complete.
  268. This can result in memory being accessed in a different order than specified in the source code.
  269. While this typically will not cause a problem in a single thread of execution, it can cause a problem if the location can also be accessed from another processor or device.
  270.  
  271. As mentioned above, both compilers and processors can optimize the execution of instructions in a way that necessitates the use of a memory barrier.
  272. A memory barrier that affects both the compiler and the processor is a hardware memory barrier, and a memory barrier that only affects the compiler is a software memory barrier.
  273.  
  274. In addition to hardware and software memory barriers, a memory barrier can be restricted to memory reads, memory writes, or both. A memory barrier that affects both reads and writes is a full memory barrier.
  275.  
  276.  
  277. mb()
  278.  
  279. #include <asm/system.h>
  280. void mb(void);
  281. This function inserts a hardware memory barrier that prevents any memory access from being moved and executed on the other side of the barrier. It guarantees that any memory access initiated before the memory barrier will be complete before passing the barrier, and all subsequent memory accesses will be executed after the barrier.
  282.  
  283. rmb()
  284.  
  285. #include <asm/system.h>
  286. void rmb(void);
  287. This function inserts a hardware memory barrier that prevents any memory read access from being moved and executed on the other side of the barrier. It guarantees that any memory read access initiated before the memory barrier will be complete before passing the barrier, and all subsequent memory read accesses will be executed after the barrier.
  288.  
  289. wmb()
  290.  
  291. #include <asm/system.h>
  292. void wmb(void);
  293. This function inserts a hardware memory barrier that prevents any memory write access from being moved and executed on the other side of the barrier. It guarantees that any memory write access initiated before the memory barrier will be complete before passing the barrier, and all subsequent memory write accesses will be executed after the barrier.
  294.  
  295. barrier()
  296.  
  297. #include <linux/kernel.h>
  298. void barrier(void);
  299. This function inserts a software memory barrier that affects the compiler code generation, but it does not affect the hardware's execution of instructions. The compiler will save to memory any modified values that it has loaded in registers, and it will reread all values from memory the next time they are needed.
  300.  
  301. Using I/O Ports
  302.  
  303. I/O ports are the means by which drivers communicate with many devices, at least part of the time.
  304.  
  305. I/O Port Allocation
  306.  
  307. The kernel provides a registration interface that allows your driver to claim the ports it needs. The core function in that interface is request_region:
  308.  
  309. #include <linux/ioport.h>
  310. struct resource *request_region(unsigned long first, unsigned long n,
  311. const char *name);
  312.  
  313. This function tells the kernel that you would like to make use of n ports, starting with first. The name parameter should be the name of your device. The return value is non-NULL if the allocation succeeds.
  314. If you get NULL back from request_region, you will not be able to use the desired ports.
  315.  
  316. All port allocations show up in /proc/ioports
  317.  
  318. When you are done with a set of I/O ports (at module unload time, perhaps), they should be returned to the system with:
  319.  
  320. void release_region(unsigned long start, unsigned long n);
  321.  
  322. There is also a function that allows your driver to check to see whether a given set of I/O ports is available:
  323.  
  324. int check_region(unsigned long first, unsigned long n);
  325.  
  326. After a driver has requested the range of I/O ports it needs to use in its activities, it must read and/or write to those ports. To this end, most hardware differentiates between 8-bit, 16-bit, and 32-bit ports
  327.  
  328. The Linux kernel headers (specifically, the architecture-dependent header <asm/io.h>) define the following inline functions to access I/O ports:
  329.  
  330. unsigned inb(unsigned port);
  331. void outb(unsigned char byte, unsigned port);
  332. Read or write byte ports (eight bits wide). The port argument is defined as unsigned long for some platforms and unsigned short for others. The return type of inb is also different across architectures.
  333.  
  334. unsigned inw(unsigned port);
  335. void outw(unsigned short word, unsigned port);
  336. These functions access 16-bit ports (one word wide); they are not available when compiling for the S390 platform, which supports only byte I/O.
  337.  
  338. unsigned inl(unsigned port);
  339. void outl(unsigned longword, unsigned port);
  340. These functions access 32-bit ports. longword is declared as either unsigned long or unsigned int, according to the platform. Like word I/O, "long" I/O is not available on S390.
  341.  
  342. Use IO memory
  343.  
  344. -- Despite the popularity of I/O ports in the x86 world, the main mechanism used to communicate with devices is through memory-mapped registers and device memory.
  345.  
  346. -- I/O memory is simply a region of RAM-like locations that the device makes available to the processor over the bus.
  347. This memory can be used for a number of purposes, such as holding video data or Ethernet packets, as well as implementing device registers that behave just like I/O ports.
  348.  
  349. I/O Memory Allocation and Mapping
  350.  
  351. --I/O memory regions must be allocated prior to use. The interface for allocation of memory regions (defined in <linux/ioport.h>) is:
  352.  
  353. struct resource *request_mem_region(unsigned long start, unsigned long len,
  354. char *name);
  355.  
  356. This function allocates a memory region of len bytes, starting at start. If all goes well, a non-NULL pointer is returned; otherwise the return value is NULL. All I/O memory allocations are listed in /proc/iomem.
  357.  
  358. Memory regions should be freed when no longer needed:
  359.  
  360. void release_mem_region(unsigned long start, unsigned long len);
  361.  
  362. There is also an old function for checking I/O memory region availability:
  363.  
  364. int check_mem_region(unsigned long start, unsigned long len);
  365.  
  366. Allocation of I/O memory is not the only required step before that memory may be accessed. You must also ensure that this I/O memory has been made accessible to the kernel.
  367. Getting at I/O memory is not just a matter of dereferencing a pointer; on many systems, I/O memory is not directly accessible in this way at all.
  368. So a mapping must be set up first. This is the role of the ioremap function.
  369.  
  370. Once equipped with ioremap (and iounmap), a device driver can access any I/O memory address, whether or not it is directly mapped to virtual address space.
  371. Remember, though, that the addresses returned from ioremap should not be dereferenced directly; instead, accessor functions provided by the kernel should be used.
  372.  
  373.  
  374. Accessing I/O Memory
  375.  
  376. On some platforms, you may get away with using the return value from ioremap as a pointer.
  377. Such use is not portable, and, increasingly, the kernel developers have been working to eliminate any such use. The proper way of getting at I/O memory is via a set of functions (defined via <asm/io.h>) provided for that purpose.
  378.  
  379. To read from I/O memory, use one of the following:
  380.  
  381. unsigned int ioread8(void *addr);
  382. unsigned int ioread16(void *addr);
  383. unsigned int ioread32(void *addr);
  384.  
  385. Here, addr should be an address obtained from ioremap (perhaps with an integer offset); the return value is what was read from the given I/O memory.
  386.  
  387. There is a similar set of functions for writing to I/O memory:
  388.  
  389. void iowrite8(u8 value, void *addr);
  390. void iowrite16(u16 value, void *addr);
  391. void iowrite32(u32 value, void *addr);
  392.  
  393. Interrupts
  394.  
  395. -- An interrupt is simply a signal that the hardware can send when it wants the processor's attention.
  396. Linux handles interrupts in much the same way that it handles signals in user space.
  397.  
  398. --For the most part, a driver need only register a handler for its device's interrupts, and handle them properly when they arrive.
  399.  
  400. Installing interupt handler
  401.  
  402. -- Interrupt lines are a precious and often limited resource .
  403. -- kernel keeps a registry of interrupt lines, similar to the registry of I/O ports.module is expected to request an interrupt channel (or IRQ, for interrupt request) before using it and to release it when finished.
  404. -- Modules are also expected to be able to share interrupt lines with other drivers.
  405.  
  406. The interrupt registration interface:
  407.  
  408. int request_irq(unsigned int irq,
  409. irqreturn_t (*handler)(int, void *, struct pt_regs *),
  410. unsigned long flags,
  411. const char *dev_name,
  412. void *dev_id);
  413.  
  414. void free_irq(unsigned int irq, void *dev_id);
  415.  
  416. -- The value returned from request_irq to the requesting function is either 0 to indicate success or a negative error code.
  417.  
  418. unsigned int irq
  419. The interrupt number being requested.
  420.  
  421. irqreturn_t (*handler)(int, void *, struct pt_regs *)
  422. The pointer to the handling function being installed. We discuss the arguments to this function and its return value later in this chapter.
  423.  
  424. unsigned long flags
  425. As you might expect, a bit mask of options (described later) related to interrupt management.
  426.  
  427. const char *dev_name
  428. The string passed to request_irq is used in /proc/interrupts to show the owner of the interrupt (see the next section).
  429.  
  430. void *dev_id
  431. Pointer used for shared interrupt lines. It is a unique identifier that is used when the interrupt line is freed and that may also be used by the driver to point to its own private data area (to identify which device is interrupting). If the interrupt is not shared, dev_id can be set to NULL, but it a good idea anyway to use this item to point to the device structure. We'll see a practical use for dev_id in Section 10.3.
  432.  
  433. The bits that can be set in flags are as follows:
  434.  
  435. SA_INTERRUPT
  436. When set, this indicates a "fast" interrupt handler. Fast handlers are executed with interrupts disabled on the current processor.
  437.  
  438. SA_SHIRQ
  439. This bit signals that the interrupt can be shared between devices.
  440.  
  441. --The interrupt handler can be installed either at driver initialization or when the device is first opened.
  442. Although installing the interrupt handler from within the module's initialization function might sound like a good idea, it often isn't,
  443. especially if your device does not share interrupts.
  444. Because the number of interrupt lines is limited, you don't want to waste them.
  445.  
  446. --If a module requests an IRQ at initialization, it prevents any other driver from using the interrupt, even if the device holding it is never used.
  447. Requesting the interrupt at device open, on the other hand, allows some sharing of resources.
  448.  
  449. -- The correct place to call request_irq is when the device is first opened, before the hardware is instructed to generate interrupts. The place to call free_irq is the last time the device is closed, after the hardware is told not to interrupt the processor any more.
  450. The disadvantage of this technique is that you need to keep a per-device open count so that you know when interrupts can be disabled.
  451.  
  452. Example :
  453.  
  454. if (short_irq >= 0) {
  455. result = request_irq(short_irq, short_interrupt,
  456. SA_INTERRUPT, "short", NULL);
  457. if (result) {
  458. printk(KERN_INFO "short: can't get assigned irq %i\n",
  459. short_irq);
  460. short_irq = -1;
  461. }
  462. else { /* actually enable it -- assume this *is* a parallel port */
  463. outb(0x10,short_base+2);
  464. }
  465. }
  466.  
  467. Proc Interface
  468.  
  469. -- Whenever a hardware interrupt reaches the processor, an internal counter is incremented, providing a way to check whether the device is working as expected.
  470. --Reported interrupts are shown in /proc/interrupts.
  471. -- The /proc/interrupts display shows how many interrupts have been delivered to each CPU on the system.
  472.  
  473. root@montalcino:/bike/corbet/write/ldd3/src/short# m /proc/interrupts
  474. CPU0 CPU1
  475. 0: 4848108 34 IO-APIC-edge timer
  476. 2: 0 0 XT-PIC cascade
  477. 8: 3 1 IO-APIC-edge rtc
  478. 10: 4335 1 IO-APIC-level aic7xxx
  479. 11: 8903 0 IO-APIC-level uhci_hcd
  480. 12: 49 1 IO-APIC-edge i8042
  481. NMI: 0 0
  482. LOC: 4848187 4848186
  483. ERR: 0
  484. MIS: 0
  485.  
  486. Autodetecting the IRQ Number
  487.  
  488. -- One of the most challenging problems for a driver at initialization time can be how to determine which IRQ line is going to be used by the device.
  489. The driver needs the information in order to correctly install the handler.
  490.  
  491. -- Some devices are more advanced in design and simply "announce" which interrupt they're going to use.
  492. In this case, the driver retrieves the interrupt number by reading a status byte from one of the device's I/O ports or PCI configuration space.
  493.  
  494. -- When the target device is one that has the ability to tell the driver which interrupt it is going to use, autodetecting the IRQ number just means probing the device.
  495.  
  496. Probing IRQ
  497.  
  498. .0--Linux kernel offers a low-level facility for probing the interrupt number. It works for only nonshared interrupts.
  499.  
  500. Functions
  501.  
  502. unsigned long probe_irq_on(void);
  503.  
  504. This function returns a bit mask of unassigned interrupts. The driver must preserve the returned bit mask, and pass it to probe_irq_off later.
  505. After this call, the driver should arrange for its device to generate at least one interrupt.
  506.  
  507. int probe_irq_off(unsigned long);
  508.  
  509. After the device has requested an interrupt, the driver calls this function, passing as its argument the bit mask previously returned by probe_irq_on. probe_irq_off returns the number of the interrupt that was issued after "probe_on."
  510. If no interrupts occurred, 0 is returned (therefore, IRQ 0 can't be probed for, but no custom device can use it on any of the supported architectures anyway).
  511. If more than one interrupt occurred (ambiguous detection), probe_irq_off returns a negative value.
  512.  
  513. -- The programmer should be careful to enable interrupts on the device after the call to probe_irq_on and to disable them before calling probe_irq_off.
  514. Additionally, you must remember to service the pending interrupt in your device after probe_irq_off.
  515.  
  516. probing ex :
  517.  
  518.  
  519. int count = 0;
  520. do {
  521. unsigned long mask;
  522.  
  523. mask = probe_irq_on( );
  524. outb_p(0x10,short_base+2); /* enable reporting */
  525. outb_p(0x00,short_base); /* clear the bit */
  526. outb_p(0xFF,short_base); /* set the bit: interrupt! */
  527. outb_p(0x00,short_base+2); /* disable reporting */
  528. udelay(5); /* give it some time */
  529. short_irq = probe_irq_off(mask);
  530.  
  531. if (short_irq = = 0) { /* none of them? */
  532. printk(KERN_INFO "short: no irq reported by probe\n");
  533. short_irq = -1;
  534. }
  535. /*
  536. * if more than one line has been activated, the result is
  537. * negative. We should service the interrupt (no need for lpt port)
  538. * and loop over again. Loop at most five times, then give up
  539. */
  540. } while (short_irq < 0 && count++ < 5);
  541. if (short_irq < 0)
  542. printk("short: probe failed %i times, giving up\n", count);
  543.  
  544. Note the use of udelay before calling probe_irq_off. Depending on the speed of your processor, you may have to wait for a brief period to give the interrupt time to actually be delivered.
  545.  
  546. Probing might be a lengthy task.
  547. While this is not true for short, probing a frame grabber, for example, requires a delay of at least 20 ms (which is ages for the processor), and other devices might take even longer.
  548. Therefore, it's best to probe for the interrupt line only once, at module initialization, independently of whether you install the handler at device open (as you should) or within the initialization function (which is not recommended).
  549.  
  550. Fast and Slow Handlers
  551.  
  552. -- Fast interrupts were those that could be handled very quickly, whereas handling slow interrupts took significantly longer.
  553. Slow interrupts could be sufficiently demanding of the processor, and it was worthwhile to reenable interrupts while they were being handled.
  554.  
  555. -- In modern kernels, most of the differences between fast and slow interrupts have disappeared.
  556. There remains only one: fast interrupts ( SA_INTERRUPT flag) are executed with all other interrupts disabled on the current processor.
  557. Note that other processors can still handle interrupts, although you will never see two processors handling the same IRQ at the same time.
  558.  
  559. -- On modern systems, SA_INTERRUPT is intended only for use in a few, specific situations such as timer interrupts.
  560. Unless you have a strong reason to run your interrupt handler with other interrupts disabled, you should not use SA_INTERRUPT.
  561.  
  562. Implementation of interrupt handler
  563.  
  564. -- Actually, there's nothing unusual about a handler—it's ordinary C code.
  565. only peculiarity is that a handler runs at interrupt time and, therefore, suffers some restrictions on what it can do.
  566.  
  567. -- A handler can't transfer data to or from user space, because it doesn't execute in the context of a process.
  568. Handlers also cannot do anything that would sleep, such as calling wait_event, allocating memory with anything other than GFP_ATOMIC, or locking a semaphore.
  569. Finally, handlers cannot call schedule.
  570.  
  571. -- The role of an interrupt handler is to give feedback to its device about interrupt reception and to read or write data according to the meaning of the interrupt being serviced.
  572. The first step usually consists of clearing a bit on the interface board; most hardware devices won't generate other interrupts until their "interrupt-pending" bit has been cleared.
  573.  
  574. -- A typical task for an interrupt handler is awakening processes sleeping on the device if the interrupt signals the event they're waiting for,
  575. such as the arrival of new data.
  576.  
  577. -- The programmer should be careful to write a routine that executes in a minimum amount of time, independent of its being a fast or slow handler.
  578. If a long computation needs to be performed, the best approach is to use a tasklet or workqueue to schedule computation at a safer time.
  579.  
  580. Handler Arguments and Return Value
  581.  
  582. -- Three arguments are passed to an interrupt handler: irq, dev_id, and regs.
  583. -- The interrupt number (int irq) is useful as information you may print in your log messages.
  584. -- You usually pass a pointer to your device data structure in dev_id, so a driver that manages several instances of the same device doesn't need any extra code in the interrupt handler to find out which device is in charge of the current interrupt event.
  585.  
  586. example :
  587. static irqreturn_t sample_interrupt(int irq, void *dev_id, struct pt_regs
  588. *regs)
  589. {
  590. struct sample_dev *dev = dev_id;
  591.  
  592. /* now `dev' points to the right hardware item */
  593. /* .... */
  594. }
  595.  
  596. --The last argument, struct pt_regs *regs, is rarely used. It holds a snapshot of the processor's context before the processor entered interrupt code.
  597. The registers can be used for monitoring and debugging.
  598.  
  599. -- Interrupt handlers should return a value indicating whether there was actually an interrupt to handle. If the handler found that its device did, indeed, need attention, it should return IRQ_HANDLED;
  600. otherwise the return value should be IRQ_NONE.
  601.  
  602. -- where handled is nonzero if you were able to handle the interrupt. The return value is used by the kernel to detect and suppress spurious interrupts.
  603. If your device gives you no way to tell whether it really interrupted, you should return IRQ_HANDLED.
  604.  
  605. Enable and disable interrupts
  606.  
  607. -- There are times when a device driver must block the delivery of interrupts for a (hopefully short) period of time.
  608. Often, interrupts must be blocked while holding a spinlock to avoid deadlocking the system.
  609.  
  610. -- The kernel offers three functions for this purpose,Among other things, you cannot disable shared interrupt lines, and, on modern systems, shared interrupts are the norm.
  611.  
  612. void disable_irq(int irq);
  613. void disable_irq_nosync(int irq);
  614. void enable_irq(int irq);
  615.  
  616. --Calling any of these functions may update the mask for the specified irq in the programmable interrupt controller (PIC), thus disabling or enabling the specified IRQ across all processors.
  617.  
  618. -- disable_irq not only disables the given interrupt but also waits for a currently executing interrupt handler, if any, to complete.
  619.  
  620. Disabling all interrupts
  621.  
  622. -- It is possible to turn off all interrupt handling on the current processor with either of the following two functions.
  623.  
  624. void local_irq_save(unsigned long flags);
  625. void local_irq_disable(void);
  626.  
  627. -- A call to local_irq_save disables interrupt delivery on the current processor after saving the current interrupt state into flags.
  628. Note that flags is passed directly, not by pointer. local_irq_disable shuts off local interrupt delivery without saving the state.
  629.  
  630. -- Turning interrupts back on is accomplished with:
  631.  
  632. void local_irq_restore(unsigned long flags);
  633. void local_irq_enable(void);
  634.  
  635. -- The first version restores that state which was stored into flags by local_irq_save, while local_irq_enable enables interrupts unconditionally.
  636.  
  637. Top and bottom halves
  638.  
  639. -- One of the main problems with interrupt handling is how to perform lengthy tasks within a handler.
  640. Often a substantial amount of work must be done in response to a device interrupt, but interrupt handlers need to finish up quickly and not keep interrupts blocked for long.
  641.  
  642. -- Linux (along with many other systems) resolves this problem by splitting the interrupt handler into two halves.
  643. The so-called top half is the routine that actually responds to the interrupt—the one you register with request_irq.
  644.  
  645. -- The bottom half is a routine that is scheduled by the top half to be executed later, at a safer time.
  646.  
  647. -- The big difference between the top-half handler and the bottom half is that all interrupts are enabled during execution of the bottom half—that's why it runs at a safer time.
  648.  
  649. -- In the typical scenario,the top half saves device data to a device-specific buffer,schedules its bottom half,and exits: this operation is very fast.
  650.  
  651. -- The bottom half then performs whatever other work is required, such as awakening processes, starting up another I/O operation, and so on.
  652. This setup permits the top half to service a new interrupt while the bottom half is still working.
  653.  
  654. -- when a network interface reports the arrival of a new packet, the handler just retrieves the data and pushes it up to the protocol layer;
  655. actual processing of the packet is performed in a bottom half.
  656.  
  657. Tasklets
  658.  
  659. -- tasklets are a special function that may be scheduled to run, in software interrupt context, at a system-determined safe time.
  660. -- No tasklet ever runs in parallel with itself, since they run only once, but tasklets can run in parallel with other tasklets on SMP systems.
  661. -- Tasklets are also guaranteed to run on the same CPU as the function that first schedules them.
  662. Therefore, an interrupt handler can be secure that a tasklet does not begin executing before the handler has completed.
  663. However, another interrupt can certainly be delivered while the tasklet is running, so locking between the tasklet and the interrupt handler may still be required.
  664.  
  665. Tasklets must be declared with the DECLARE_TASKLET macro:
  666. DECLARE_TASKLET(name, function, data);
  667.  
  668. name is the name to be given to the tasklet, function is the function that is called to execute the tasklet (it takes one unsigned long argument and returns void), and data is an unsigned long value to be passed to the tasklet function.
  669.  
  670. -- The function tasklet_schedule is used to schedule a tasklet for running.
  671.  
  672. Sample interrupt routine
  673.  
  674. irqreturn_t short_tl_interrupt(int irq, void *dev_id, struct pt_regs *regs)
  675. {
  676. do_gettimeofday((struct timeval *) tv_head); /* cast to stop 'volatile' warning */
  677. short_incr_tv(&tv_head);
  678. tasklet_schedule(&short_tasklet);
  679. short_wq_count++; /* record that an interrupt arrived */
  680. return IRQ_HANDLED;
  681. }
  682.  
  683. The actual tasklet routine, short_do_tasklet, will be executed shortly (so to speak) at the system's convenience. As mentioned earlier, this routine performs the bulk of the work of handling the interrupt; it looks like this:
  684.  
  685. void short_do_tasklet(unsigned long);
  686. DECLARE_TASKLET(short_tasklet, short_do_tasklet, 0);
  687.  
  688. void short_do_tasklet (unsigned long unused)
  689. {
  690. int savecount = short_wq_count, written;
  691. short_wq_count = 0; /* we have already been removed from the queue */
  692. /*
  693. * The bottom half reads the tv array, filled by the top half,
  694. * and prints it to the circular text buffer, which is then consumed
  695. * by reading processes
  696. */
  697.  
  698. /* First write the number of interrupts that occurred before this bh */
  699. written = sprintf((char *)short_head,"bh after %6i\n",savecount);
  700. short_incr_bp(&short_head, written);
  701.  
  702. /*
  703. * Then, write the time values. Write exactly 16 bytes at a time,
  704. * so it aligns with PAGE_SIZE
  705. */
  706.  
  707. do {
  708. written = sprintf((char *)short_head,"%08u.%06u\n",
  709. (int)(tv_tail->tv_sec % 100000000),
  710. (int)(tv_tail->tv_usec));
  711. short_incr_bp(&short_head, written);
  712. short_incr_tv(&tv_tail);
  713. } while (tv_tail != tv_head);
  714.  
  715. wake_up_interruptible(&short_queue); /* awake any reading process */
  716. }
  717.  
  718. Workqueue
  719.  
  720. -- workqueues invoke a function at some future time in the context of a special worker process.
  721. -- workqueue function runs in process context, it can sleep if need be. You cannot, however, copy data into user space from a workqueue.
  722. -- We do need a work_struct structure, which is declared and initialized with the following:
  723.  
  724. static struct work_struct short_wq;
  725.  
  726. /* this line is in short_init( ) */
  727. INIT_WORK(&short_wq, (void (*)(void *)) short_do_tasklet, NULL);
  728.  
  729. Interrupt handler for bottom handler using work-queue
  730.  
  731. irqreturn_t short_wq_interrupt(int irq, void *dev_id, struct pt_regs *regs)
  732. {
  733. /* Grab the current time information. */
  734. do_gettimeofday((struct timeval *) tv_head);
  735. short_incr_tv(&tv_head);
  736.  
  737. /* Queue the bh. Don't worry about multiple enqueueing */
  738. schedule_work(&short_wq);
  739.  
  740. short_wq_count++; /* record that an interrupt arrived */
  741. return IRQ_HANDLED;
  742. }
  743.  
  744. Shared interrupts
  745.  
  746. the Linux kernel supports interrupt sharing on all buses, even those (such as the ISA bus) where sharing has traditionally not been supported. Device drivers for the 2.6 kernel should be written to work with shared interrupts if the target hardware can support that mode of operation.
  747.  
  748. Installing a Shared Handler
  749.  
  750. Shared interrupts are installed through request_irq just like nonshared ones, but there are two differences:
  751.  
  752. The SA_SHIRQ bit must be specified in the flags argument when requesting the interrupt.
  753.  
  754. The dev_id argument must be unique. Any pointer into the module's address space will do, but dev_id definitely cannot be set to NULL.
  755.  
  756. request_irq succeeds if one of the following is true:
  757.  
  758. 1-The interrupt line is free.
  759.  
  760. 2-All handlers already registered for that line have also specified that the IRQ is to be shared.
  761.  
  762. Whenever two or more drivers are sharing an interrupt line and the hardware interrupts the processor on that line, the kernel invokes every handler registered for that interrupt, passing each its own dev_id. Therefore, a shared handler must be able to recognize its own interrupts and should quickly exit when its own device has not interrupted. Be sure to return IRQ_NONE whenever your handler is called and finds that the device is not interrupting.
  763.  
  764. No probing function is available for shared handlers. The standard probing mechanism works if the line being used is free, but if the line is already held by another driver with sharing capabilities, the probe fails, even if your driver would have worked perfectly.
  765.  
  766. Releasing the handler is performed in the normal way, using free_irq. Here the dev_id argument is used to select the correct handler to release from the list of shared handlers for the interrupt. That's why the dev_id pointer must be unique.
  767.  
  768. A driver using a shared handler needs to be careful about one more thing: it can't play with enable_irq or disable_irq. If it does, things might go haywire for other devices sharing the line; disabling another device's interrupts for even a short time may create latencies that are problematic for that device and it's user.
  769.  
  770. Running the handler
  771.  
  772. when the kernel receives an interrupt, all the registered handlers are invoked. A shared handler must be able to distinguish between interrupts that it needs to handle and interrupts generated by other devices.
  773.  
  774.  
  775. The /proc Interface and Shared Interrupts
  776.  
  777. Installing shared handlers in the system doesn't affect /proc/stat, which doesn't even know about handlers. However, /proc/interrupts changes slightly.
  778.  
  779. All the handlers installed for the same interrupt number appear on the same line of /proc/interrupts. The following output (from an x86_64 system) shows how shared interrupt handlers are displayed:
  780.  
  781. CPU0
  782. 0: 892335412 XT-PIC timer
  783. 1: 453971 XT-PIC i8042
  784. 2: 0 XT-PIC cascade
  785. 5: 0 XT-PIC libata, ehci_hcd
  786. 8: 0 XT-PIC rtc
  787. 9: 0 XT-PIC acpi
  788. 10: 11365067 XT-PIC ide2, uhci_hcd, uhci_hcd, SysKonnect SK-98xx, EMU10K1
  789. 11: 4391962 XT-PIC uhci_hcd, uhci_hcd
  790. 12: 224 XT-PIC i8042
  791. 14: 2787721 XT-PIC ide0
  792. 15: 203048 XT-PIC ide1
  793. NMI: 41234
  794. LOC: 892193503
  795. ERR: 102
  796. MIS: 0
  797.  
  798. This system has several shared interrupt lines. IRQ 5 is used for the serial ATA and IEEE 1394 controllers; IRQ 10 has several devices, including an IDE controller, two USB controllers, an Ethernet interface, and a sound card; and IRQ 11 also is used by two USB controllers.
Add Comment
Please, Sign In to add comment