PageRenderTime 24ms CodeModel.GetById 15ms app.highlight 3ms RepoModel.GetById 1ms app.codeStats 0ms

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