sbus_drivers.txt
上传用户:lgb322
上传日期:2013-02-24
资源大小:30529k
文件大小:9k
源码类别:

嵌入式Linux

开发平台:

Unix_Linux

  1. Writing SBUS Drivers
  2.     David S. Miller (davem@redhat.com)
  3. The SBUS driver interfaces of the Linux kernel have been
  4. revamped completely for 2.4.x for several reasons.  Foremost were
  5. performance and complexity concerns.  This document details these
  6. new interfaces and how they are used to write an SBUS device driver.
  7. SBUS drivers need to include <asm/sbus.h> to get access
  8. to functions and structures described here.
  9. Probing and Detection
  10. Each SBUS device inside the machine is described by a
  11. structure called "struct sbus_dev".  Likewise, each SBUS bus
  12. found in the system is described by a "struct sbus_bus".  For
  13. each SBUS bus, the devices underneath are hung in a tree-like
  14. fashion off of the bus structure.
  15. The SBUS device structure contains enough information
  16. for you to implement your device probing algorithm and obtain
  17. the bits necessary to run your device.  The most commonly
  18. used members of this structure, and their typical usage,
  19. will be detailed below.
  20. Here is how probing is performed by an SBUS driver
  21. under Linux:
  22. static void init_one_mydevice(struct sbus_dev *sdev)
  23. {
  24. ...
  25. }
  26. static int mydevice_match(struct sbus_dev *sdev)
  27. {
  28. if (some_criteria(sdev))
  29. return 1;
  30. return 0;
  31. }
  32. static void mydevice_probe(void)
  33. {
  34. struct sbus_bus *sbus;
  35. struct sbus_dev *sdev;
  36. for_each_sbus(sbus) {
  37. for_each_sbusdev(sdev, sbus) {
  38. if (mydevice_match(sdev))
  39. init_one_mydevice(sdev);
  40. }
  41. }
  42. }
  43. All this does is walk through all SBUS devices in the
  44. system, checks each to see if it is of the type which
  45. your driver is written for, and if so it calls the init
  46. routine to attach the device and prepare to drive it.
  47. "init_one_mydevice" might do things like allocate software
  48. state structures, map in I/O registers, place the hardware
  49. into an initialized state, etc.
  50. Mapping and Accessing I/O Registers
  51. Each SBUS device structure contains an array of descriptors
  52. which describe each register set. We abuse struct resource for that.
  53. They each correspond to the "reg" properties provided by the OBP firmware.
  54. Before you can access your device's registers you must map
  55. them.  And later if you wish to shutdown your driver (for module
  56. unload or similar) you must unmap them.  You must treat them as
  57. a resource, which you allocate (map) before using and free up
  58. (unmap) when you are done with it.
  59. The mapping information is stored in an opaque value
  60. typed as an "unsigned long".  This is the type of the return value
  61. of the mapping interface, and the arguments to the unmapping
  62. interface.  Let's say you want to map the first set of registers.
  63. Perhaps part of your driver software state structure looks like:
  64. struct mydevice {
  65. unsigned long control_regs;
  66.    ...
  67. struct sbus_dev *sdev;
  68.    ...
  69. };
  70. At initialization time you then use the sbus_ioremap
  71. interface to map in your registers, like so:
  72. static void init_one_mydevice(struct sbus_dev *sdev)
  73. {
  74. struct mydevice *mp;
  75. ...
  76. mp->control_regs = sbus_ioremap(&sdev->resource[0], 0,
  77. CONTROL_REGS_SIZE, "mydevice regs");
  78. if (!mp->control_regs) {
  79. /* Failure, cleanup and return. */
  80. }
  81. }
  82. Second argument to sbus_ioremap is an offset for
  83. cranky devices with broken OBP PROM. The sbus_ioremap uses only
  84. a start address and flags from the resource structure.
  85. Therefore it is possible to use the same resource to map
  86. several sets of registers or even to fabricate a resource
  87. structure if driver gets physical address from some private place.
  88. This practice is discouraged though. Use whatever OBP PROM
  89. provided to you.
  90. And here is how you might unmap these registers later at
  91. driver shutdown or module unload time, using the sbus_iounmap
  92. interface:
  93. static void mydevice_unmap_regs(struct mydevice *mp)
  94. {
  95. sbus_iounmap(mp->control_regs, CONTROL_REGS_SIZE);
  96. }
  97. Finally, to actually access your registers there are 6
  98. interface routines at your disposal.  Accesses are byte (8 bit),
  99. word (16 bit), or longword (32 bit) sized.  Here they are:
  100. u8 sbus_readb(unsigned long reg) /* read byte */
  101. u16 sbus_readw(unsigned long reg) /* read word */
  102. u32 sbus_readl(unsigned long reg) /* read longword */
  103. void sbus_writeb(u8 value, unsigned long reg) /* write byte */
  104. void sbus_writew(u16 value, unsigned long reg) /* write word */
  105. void sbus_writel(u32 value, unsigned long reg) /* write longword */
  106. So, let's say your device has a control register of some sort
  107. at offset zero.  The following might implement resetting your device:
  108. #define CONTROL 0x00UL
  109. #define CONTROL_RESET 0x00000001 /* Reset hardware */
  110. static void mydevice_reset(struct mydevice *mp)
  111. {
  112. sbus_writel(CONTROL_RESET, mp->regs + CONTROL);
  113. }
  114. Or perhaps there is a data port register at an offset of
  115. 16 bytes which allows you to read bytes from a fifo in the device:
  116. #define DATA 0x10UL
  117. static u8 mydevice_get_byte(struct mydevice *mp)
  118. {
  119. return sbus_readb(mp->regs + DATA);
  120. }
  121. It's pretty straightforward, and clueful readers may have
  122. noticed that these interfaces mimick the PCI interfaces of the
  123. Linux kernel.  This was not by accident.
  124. WARNING:
  125. DO NOT try to treat these opaque register mapping
  126. values as a memory mapped pointer to some structure
  127. which you can dereference.
  128. It may be memory mapped, it may not be.  In fact it
  129. could be a physical address, or it could be the time
  130. of day xor'd with 0xdeadbeef.  :-)
  131. Whatever it is, it's an implementation detail.  The
  132. interface was done this way to shield the driver
  133. author from such complexities.
  134. Doing DVMA
  135. SBUS devices can perform DMA transactions in a way similar
  136. to PCI but dissimilar to ISA, e.g. DMA masters supply address.
  137. In contrast to PCI, however, that address (a bus address) is
  138. translated by IOMMU before a memory access is performed and therefore
  139. it is virtual. Sun calls this procedure DVMA.
  140. Linux supports two styles of using SBUS DVMA: "consistent memory"
  141. and "streaming DVMA". CPU view of consistent memory chunk is, well,
  142. consistent with a view of a device. Think of it as an uncached memory.
  143. Typically this way of doing DVMA is not very fast and drivers use it
  144. mostly for control blocks or queues. On some CPUs we cannot flush or
  145. invalidate individual pages or cache lines and doing explicit flushing
  146. over ever little byte in every control block would be wasteful.
  147. Streaming DVMA is a preferred way to transfer large amounts of data.
  148. This process works in the following way:
  149. 1. a CPU stops accessing a certain part of memory,
  150.    flushes its caches covering that memory;
  151. 2. a device does DVMA accesses, then posts an interrupt;
  152. 3. CPU invalidates its caches and starts to access the memory.
  153. A single streaming DVMA operation can touch several discontiguous
  154. regions of a virtual bus address space. This is called a scatter-gather
  155. DVMA.
  156. [TBD: Why do not we neither Solaris attempt to map disjoint pages
  157. into a single virtual chunk with the help of IOMMU, so that non SG
  158. DVMA masters would do SG? It'd be very helpful for RAID.]
  159. In order to perform a consistent DVMA a driver does something
  160. like the following:
  161. char *mem; /* Address in the CPU space */
  162. u32 busa; /* Address in the SBus space */
  163. mem = (char *) sbus_alloc_consistant(sdev, MYMEMSIZE, &busa);
  164. Then mem is used when CPU accesses this memory and u32
  165. is fed to the device so that it can do DVMA. This is typically
  166. done with an sbus_writel() into some device register.
  167. Do not forget to free the DVMA resources once you are done:
  168. sbus_free_consistant(sdev, MYMEMSIZE, mem, busa);
  169. Streaming DVMA is more interesting. First you allocate some
  170. memory suitable for it or pin down some user pages. Then it all works
  171. like this:
  172. char *mem = argumen1;
  173. unsigned int size = argument2;
  174. u32 busa; /* Address in the SBus space */
  175. *mem = 1; /* CPU can access */
  176. busa = sbus_map_single(sdev, mem, size);
  177. if (busa == 0) .......
  178. /* Tell the device to use busa here */
  179. /* CPU cannot access the memory without sbus_dma_sync_single() */
  180. sbus_unmap_single(sdev, busa, size);
  181. if (*mem == 0) .... /* CPU can access again */
  182. It is possible to retain mappings and ask the device to
  183. access data again and again without calling sbus_unmap_single.
  184. However, CPU caches must be invalidated with sbus_dma_sync_single
  185. before such access.
  186. [TBD but what about writeback caches here... do we have any?]
  187. There is an equivalent set of functions doing the same thing
  188. only with several memory segments at once for devices capable of
  189. scatter-gather transfers. Use the Source, Luke.
  190. Examples
  191. drivers/net/sunhme.c
  192. This is a complicated driver which illustrates many concepts
  193. discussed above and plus it handles both PCI and SBUS boards.
  194. drivers/scsi/esp.c
  195. Check it out for scatter-gather DVMA.
  196. drivers/sbus/char/bpp.c
  197. A non-DVMA device.
  198. drivers/net/sunlance.c
  199. Lance driver abuses consistent mappings for data transfer.
  200. It is a nifty trick which we do not particularly recommend...
  201. Just check it out and know that it's legal.
  202. Bad examples, do NOT use
  203. drivers/video/cgsix.c
  204. This one uses result of sbus_ioremap as if it is an address.
  205. This does NOT work on sparc64 and therefore is broken. We will
  206. convert it at a later date.