Linux Device Drivers 2nd Edition (779877), страница 57
Текст из файла (страница 57)
The problems can arisebecause the processor is overclocked with respect to the ISA bus, and can showup when the device board is too slow. The solution is to insert a small delay aftereach I/O instruction if another such instruction follows. If your device misses somedata, or if you fear it might miss some, you can use pausing functions in place ofthe normal ones. The pausing functions are exactly like those listed previously, buttheir names end in _p; they are called inb_ p, outb_ p, and so on. The functions aredefined for most supported architectures, although they often expand to the samecode as nonpausing I/O, because there is no need for the extra pause if the architecture runs with a nonobsolete peripheral bus.Platform DependenciesI/O instructions are, by their nature, highly processor dependent.
Because theywork with the details of how the processor handles moving data in and out, it isvery hard to hide the differences between systems. As a consequence, much of thesource code related to port I/O is platform dependent.You can see one of the incompatibilities, data typing, by looking back at the list offunctions, where the arguments are typed differently based on the architectural23222 June 2001 16:39http://openlib.org.uaUsing I/O Portsdifferences between platforms. For example, a port is unsigned short on thex86 (where the processor supports a 64-KB I/O space), but unsigned long onother platforms, whose ports are just special locations in the same address spaceas memory.Other platform dependencies arise from basic structural differences in the processors and thus are unavoidable.
We won’t go into detail about the differences,because we assume that you won’t be writing a device driver for a particular system without understanding the underlying hardware. Instead, the following is anoverview of the capabilities of the architectures that are supported by version 2.4of the kernel:IA-32 (x86)The architecture supports all the functions described in this chapter.
Portnumbers are of type unsigned short.IA-64 (Itanium)All functions are supported; ports are unsigned long (and memorymapped). String functions are implemented in C.AlphaAll the functions are supported, and ports are memory-mapped. The implementation of port I/O is different in different Alpha platforms, according to thechipset they use.
String functions are implemented in C and defined inarch/alpha/lib/io.c. Ports are unsigned long.ARMPorts are memory-mapped, and all functions are supported; string functionsare implemented in C. Ports are of type unsigned int.M68kPorts are memory-mapped, and only byte functions are supported. No stringfunctions are supported, and the port type is unsigned char *.MIPSMIPS64The MIPS port supports all the functions.
String operations are implementedwith tight assembly loops, because the processor lacks machine-level stringI/O. Ports are memory-mapped; they are unsigned int in 32-bit processorsand unsigned long in 64-bit ones.PowerPCAll the functions are supported; ports have type unsigned char *.23322 June 2001 16:39http://openlib.org.uaChapter 8: Hardware ManagementS390Similar to the M68k, the header for this platform supports only byte-wide portI/O with no string operations. Ports are char pointers and are memorymapped.Super-HPorts are unsigned int (memory-mapped), and all the functions are supported.SPARCSPARC64Once again, I/O space is memory-mapped. Versions of the port functions aredefined to work with unsigned long ports.The curious reader can extract more information from the io.h files, which sometimes define a few architecture-specific functions in addition to those we describein this chapter.
Be warned that some of these files are rather difficult reading,however.It’s interesting to note that no processor outside the x86 family features a differentaddress space for ports, even though several of the supported families are shippedwith ISA and/or PCI slots (and both buses implement different I/O and memoryaddress spaces).Moreover, some processors (most notably the early Alphas) lack instructions thatmove one or two bytes at a time.* Therefore, their peripheral chipsets simulate8-bit and 16-bit I/O accesses by mapping them to special address ranges in thememory address space. Thus, an inb and an inw instruction that act on the sameport are implemented by two 32-bit memory reads that operate on differentaddresses. Fortunately, all of this is hidden from the device driver writer by theinternals of the macros described in this section, but we feel it’s an interesting feature to note.
If you want to probe further, look for examples in include/asmalpha/cor e_lca.h.How I/O operations are performed on each platform is well described in the programmer’s manual for each platform; those manuals are usually available fordownload as PDF files on the Web.* Single-byte I/O is not as important as one may imagine, because it is a rare operation. Inorder to read/write a single byte to any address space, you need to implement a datapath connecting the low bits of the register-set data bus to any byte position in the external data bus. These data paths require additional logic gates that get in the way of everydata transfer. Dropping byte-wide loads and stores can benefit overall system performance.23422 June 2001 16:39http://openlib.org.uaUsing Digital I/O PortsUsing Digital I/O PortsThe sample code we use to show port I/O from within a device driver acts ongeneral-purpose digital I/O ports; such ports are found in most computer systems.A digital I/O port, in its most common incarnation, is a byte-wide I/O location,either memory-mapped or port-mapped.
When you write a value to an outputlocation, the electrical signal seen on output pins is changed according to the individual bits being written. When you read a value from the input location, the current logic level seen on input pins is returned as individual bit values.The actual implementation and software interface of such I/O ports varies fromsystem to system. Most of the time I/O pins are controlled by two I/O locations:one that allows selecting what pins are used as input and what pins are used asoutput, and one in which you can actually read or write logic levels. Sometimes,however, things are even simpler and the bits are hardwired as either input or output (but, in this case, you don’t call them ‘‘general-purpose I/O’’ anymore); theparallel port found on all personal computers is one such not-so-general-purposeI/O port.
Either way, the I/O pins are usable by the sample code we introduceshortly.An Overview of the Parallel PortBecause we expect most readers to be using an x86 platform in the form called‘‘personal computer,’’ we feel it is worth explaining how the PC parallel port isdesigned. The parallel port is the peripheral interface of choice for running digitalI/O sample code on a personal computer. Although most readers probably haveparallel port specifications available, we summarize them here for your convenience.The parallel interface, in its minimal configuration (we will overlook the ECP andEPP modes) is made up of three 8-bit ports. The PC standard starts the I/O portsfor the first parallel interface at 0x378, and for the second at 0x278.
The first portis a bidirectional data register; it connects directly to pins 2 through 9 on the physical connector. The second port is a read-only status register; when the parallelport is being used for a printer, this register reports several aspects of printer status, such as being online, out of paper, or busy. The third port is an output-onlycontrol register, which, among other things, controls whether interrupts areenabled.The signal levels used in parallel communications are standard transistor-transistorlogic (TTL) levels: 0 and 5 volts, with the logic threshold at about 1.2 volts; youcan count on the ports at least meeting the standard TTL LS current ratings,although most modern parallel ports do better in both current and voltage ratings.23522 June 2001 16:39http://openlib.org.uaChapter 8: Hardware ManagementThe parallel connector is not isolated from the computer’s internalcircuitry, which is useful if you want to connect logic gates directlyto the port.
But you have to be careful to do the wiring correctly; theparallel port circuitry is easily damaged when you play with yourown custom circuitry unless you add optoisolators to your circuit.You can choose to use plug-in parallel ports if you fear you’ll damage your motherboard.The bit specifications are outlined in Figure 8-1. You can access 12 output bits and5 input bits, some of which are logically inverted over the course of their signalpath. The only bit with no associated signal pin is bit 4 (0x10) of port 2, whichenables interrupts from the parallel port.
We’ll make use of this bit as part of ourimplementation of an interrupt handler in Chapter 9.7 6 5 4 3 2 1 0Control port: base_addr + 217 16 14 1irq enable7 6 5 4 3 2 1 0Status port: base_addr + 111 10 12 13 157 6 5 4 3 2 1 0Data port: base_addr + 098765432114KEYInput lineOutput line3 2Bit #17 16Pin #noninvertedinverted1325Figur e 8-1. The pinout of the parallel port23622 June 2001 16:39http://openlib.org.uaUsing Digital I/O PortsA Sample DriverThe driver we will introduce is called short (Simple Hardware Operations and RawTests). All it does is read and write a few eight-bit ports, starting from the one youselect at load time. By default it uses the port range assigned to the parallel interface of the PC.