xref: /OK3568_Linux_fs/kernel/Documentation/driver-api/vme.rst (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593SmuzhiyunVME Device Drivers
2*4882a593Smuzhiyun==================
3*4882a593Smuzhiyun
4*4882a593SmuzhiyunDriver registration
5*4882a593Smuzhiyun-------------------
6*4882a593Smuzhiyun
7*4882a593SmuzhiyunAs with other subsystems within the Linux kernel, VME device drivers register
8*4882a593Smuzhiyunwith the VME subsystem, typically called from the devices init routine.  This is
9*4882a593Smuzhiyunachieved via a call to :c:func:`vme_register_driver`.
10*4882a593Smuzhiyun
11*4882a593SmuzhiyunA pointer to a structure of type :c:type:`struct vme_driver <vme_driver>` must
12*4882a593Smuzhiyunbe provided to the registration function. Along with the maximum number of
13*4882a593Smuzhiyundevices your driver is able to support.
14*4882a593Smuzhiyun
15*4882a593SmuzhiyunAt the minimum, the '.name', '.match' and '.probe' elements of
16*4882a593Smuzhiyun:c:type:`struct vme_driver <vme_driver>` should be correctly set. The '.name'
17*4882a593Smuzhiyunelement is a pointer to a string holding the device driver's name.
18*4882a593Smuzhiyun
19*4882a593SmuzhiyunThe '.match' function allows control over which VME devices should be registered
20*4882a593Smuzhiyunwith the driver. The match function should return 1 if a device should be
21*4882a593Smuzhiyunprobed and 0 otherwise. This example match function (from vme_user.c) limits
22*4882a593Smuzhiyunthe number of devices probed to one:
23*4882a593Smuzhiyun
24*4882a593Smuzhiyun.. code-block:: c
25*4882a593Smuzhiyun
26*4882a593Smuzhiyun	#define USER_BUS_MAX	1
27*4882a593Smuzhiyun	...
28*4882a593Smuzhiyun	static int vme_user_match(struct vme_dev *vdev)
29*4882a593Smuzhiyun	{
30*4882a593Smuzhiyun		if (vdev->id.num >= USER_BUS_MAX)
31*4882a593Smuzhiyun			return 0;
32*4882a593Smuzhiyun		return 1;
33*4882a593Smuzhiyun	}
34*4882a593Smuzhiyun
35*4882a593SmuzhiyunThe '.probe' element should contain a pointer to the probe routine. The
36*4882a593Smuzhiyunprobe routine is passed a :c:type:`struct vme_dev <vme_dev>` pointer as an
37*4882a593Smuzhiyunargument.
38*4882a593Smuzhiyun
39*4882a593SmuzhiyunHere, the 'num' field refers to the sequential device ID for this specific
40*4882a593Smuzhiyundriver. The bridge number (or bus number) can be accessed using
41*4882a593Smuzhiyundev->bridge->num.
42*4882a593Smuzhiyun
43*4882a593SmuzhiyunA function is also provided to unregister the driver from the VME core called
44*4882a593Smuzhiyun:c:func:`vme_unregister_driver` and should usually be called from the device
45*4882a593Smuzhiyundriver's exit routine.
46*4882a593Smuzhiyun
47*4882a593Smuzhiyun
48*4882a593SmuzhiyunResource management
49*4882a593Smuzhiyun-------------------
50*4882a593Smuzhiyun
51*4882a593SmuzhiyunOnce a driver has registered with the VME core the provided match routine will
52*4882a593Smuzhiyunbe called the number of times specified during the registration. If a match
53*4882a593Smuzhiyunsucceeds, a non-zero value should be returned. A zero return value indicates
54*4882a593Smuzhiyunfailure. For all successful matches, the probe routine of the corresponding
55*4882a593Smuzhiyundriver is called. The probe routine is passed a pointer to the devices
56*4882a593Smuzhiyundevice structure. This pointer should be saved, it will be required for
57*4882a593Smuzhiyunrequesting VME resources.
58*4882a593Smuzhiyun
59*4882a593SmuzhiyunThe driver can request ownership of one or more master windows
60*4882a593Smuzhiyun(:c:func:`vme_master_request`), slave windows (:c:func:`vme_slave_request`)
61*4882a593Smuzhiyunand/or dma channels (:c:func:`vme_dma_request`). Rather than allowing the device
62*4882a593Smuzhiyundriver to request a specific window or DMA channel (which may be used by a
63*4882a593Smuzhiyundifferent driver) the API allows a resource to be assigned based on the required
64*4882a593Smuzhiyunattributes of the driver in question. For slave windows these attributes are
65*4882a593Smuzhiyunsplit into the VME address spaces that need to be accessed in 'aspace' and VME
66*4882a593Smuzhiyunbus cycle types required in 'cycle'. Master windows add a further set of
67*4882a593Smuzhiyunattributes in 'width' specifying the required data transfer widths. These
68*4882a593Smuzhiyunattributes are defined as bitmasks and as such any combination of the
69*4882a593Smuzhiyunattributes can be requested for a single window, the core will assign a window
70*4882a593Smuzhiyunthat meets the requirements, returning a pointer of type vme_resource that
71*4882a593Smuzhiyunshould be used to identify the allocated resource when it is used. For DMA
72*4882a593Smuzhiyuncontrollers, the request function requires the potential direction of any
73*4882a593Smuzhiyuntransfers to be provided in the route attributes. This is typically VME-to-MEM
74*4882a593Smuzhiyunand/or MEM-to-VME, though some hardware can support VME-to-VME and MEM-to-MEM
75*4882a593Smuzhiyuntransfers as well as test pattern generation. If an unallocated window fitting
76*4882a593Smuzhiyunthe requirements can not be found a NULL pointer will be returned.
77*4882a593Smuzhiyun
78*4882a593SmuzhiyunFunctions are also provided to free window allocations once they are no longer
79*4882a593Smuzhiyunrequired. These functions (:c:func:`vme_master_free`, :c:func:`vme_slave_free`
80*4882a593Smuzhiyunand :c:func:`vme_dma_free`) should be passed the pointer to the resource
81*4882a593Smuzhiyunprovided during resource allocation.
82*4882a593Smuzhiyun
83*4882a593Smuzhiyun
84*4882a593SmuzhiyunMaster windows
85*4882a593Smuzhiyun--------------
86*4882a593Smuzhiyun
87*4882a593SmuzhiyunMaster windows provide access from the local processor[s] out onto the VME bus.
88*4882a593SmuzhiyunThe number of windows available and the available access modes is dependent on
89*4882a593Smuzhiyunthe underlying chipset. A window must be configured before it can be used.
90*4882a593Smuzhiyun
91*4882a593Smuzhiyun
92*4882a593SmuzhiyunMaster window configuration
93*4882a593Smuzhiyun~~~~~~~~~~~~~~~~~~~~~~~~~~~
94*4882a593Smuzhiyun
95*4882a593SmuzhiyunOnce a master window has been assigned :c:func:`vme_master_set` can be used to
96*4882a593Smuzhiyunconfigure it and :c:func:`vme_master_get` to retrieve the current settings. The
97*4882a593Smuzhiyunaddress spaces, transfer widths and cycle types are the same as described
98*4882a593Smuzhiyununder resource management, however some of the options are mutually exclusive.
99*4882a593SmuzhiyunFor example, only one address space may be specified.
100*4882a593Smuzhiyun
101*4882a593Smuzhiyun
102*4882a593SmuzhiyunMaster window access
103*4882a593Smuzhiyun~~~~~~~~~~~~~~~~~~~~
104*4882a593Smuzhiyun
105*4882a593SmuzhiyunThe function :c:func:`vme_master_read` can be used to read from and
106*4882a593Smuzhiyun:c:func:`vme_master_write` used to write to configured master windows.
107*4882a593Smuzhiyun
108*4882a593SmuzhiyunIn addition to simple reads and writes, :c:func:`vme_master_rmw` is provided to
109*4882a593Smuzhiyundo a read-modify-write transaction. Parts of a VME window can also be mapped
110*4882a593Smuzhiyuninto user space memory using :c:func:`vme_master_mmap`.
111*4882a593Smuzhiyun
112*4882a593Smuzhiyun
113*4882a593SmuzhiyunSlave windows
114*4882a593Smuzhiyun-------------
115*4882a593Smuzhiyun
116*4882a593SmuzhiyunSlave windows provide devices on the VME bus access into mapped portions of the
117*4882a593Smuzhiyunlocal memory. The number of windows available and the access modes that can be
118*4882a593Smuzhiyunused is dependent on the underlying chipset. A window must be configured before
119*4882a593Smuzhiyunit can be used.
120*4882a593Smuzhiyun
121*4882a593Smuzhiyun
122*4882a593SmuzhiyunSlave window configuration
123*4882a593Smuzhiyun~~~~~~~~~~~~~~~~~~~~~~~~~~
124*4882a593Smuzhiyun
125*4882a593SmuzhiyunOnce a slave window has been assigned :c:func:`vme_slave_set` can be used to
126*4882a593Smuzhiyunconfigure it and :c:func:`vme_slave_get` to retrieve the current settings.
127*4882a593Smuzhiyun
128*4882a593SmuzhiyunThe address spaces, transfer widths and cycle types are the same as described
129*4882a593Smuzhiyununder resource management, however some of the options are mutually exclusive.
130*4882a593SmuzhiyunFor example, only one address space may be specified.
131*4882a593Smuzhiyun
132*4882a593Smuzhiyun
133*4882a593SmuzhiyunSlave window buffer allocation
134*4882a593Smuzhiyun~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
135*4882a593Smuzhiyun
136*4882a593SmuzhiyunFunctions are provided to allow the user to allocate
137*4882a593Smuzhiyun(:c:func:`vme_alloc_consistent`) and free (:c:func:`vme_free_consistent`)
138*4882a593Smuzhiyuncontiguous buffers which will be accessible by the VME bridge. These functions
139*4882a593Smuzhiyundo not have to be used, other methods can be used to allocate a buffer, though
140*4882a593Smuzhiyuncare must be taken to ensure that they are contiguous and accessible by the VME
141*4882a593Smuzhiyunbridge.
142*4882a593Smuzhiyun
143*4882a593Smuzhiyun
144*4882a593SmuzhiyunSlave window access
145*4882a593Smuzhiyun~~~~~~~~~~~~~~~~~~~
146*4882a593Smuzhiyun
147*4882a593SmuzhiyunSlave windows map local memory onto the VME bus, the standard methods for
148*4882a593Smuzhiyunaccessing memory should be used.
149*4882a593Smuzhiyun
150*4882a593Smuzhiyun
151*4882a593SmuzhiyunDMA channels
152*4882a593Smuzhiyun------------
153*4882a593Smuzhiyun
154*4882a593SmuzhiyunThe VME DMA transfer provides the ability to run link-list DMA transfers. The
155*4882a593SmuzhiyunAPI introduces the concept of DMA lists. Each DMA list is a link-list which can
156*4882a593Smuzhiyunbe passed to a DMA controller. Multiple lists can be created, extended,
157*4882a593Smuzhiyunexecuted, reused and destroyed.
158*4882a593Smuzhiyun
159*4882a593Smuzhiyun
160*4882a593SmuzhiyunList Management
161*4882a593Smuzhiyun~~~~~~~~~~~~~~~
162*4882a593Smuzhiyun
163*4882a593SmuzhiyunThe function :c:func:`vme_new_dma_list` is provided to create and
164*4882a593Smuzhiyun:c:func:`vme_dma_list_free` to destroy DMA lists. Execution of a list will not
165*4882a593Smuzhiyunautomatically destroy the list, thus enabling a list to be reused for repetitive
166*4882a593Smuzhiyuntasks.
167*4882a593Smuzhiyun
168*4882a593Smuzhiyun
169*4882a593SmuzhiyunList Population
170*4882a593Smuzhiyun~~~~~~~~~~~~~~~
171*4882a593Smuzhiyun
172*4882a593SmuzhiyunAn item can be added to a list using :c:func:`vme_dma_list_add` (the source and
173*4882a593Smuzhiyundestination attributes need to be created before calling this function, this is
174*4882a593Smuzhiyuncovered under "Transfer Attributes").
175*4882a593Smuzhiyun
176*4882a593Smuzhiyun.. note::
177*4882a593Smuzhiyun
178*4882a593Smuzhiyun	The detailed attributes of the transfers source and destination
179*4882a593Smuzhiyun	are not checked until an entry is added to a DMA list, the request
180*4882a593Smuzhiyun	for a DMA channel purely checks the directions in which the
181*4882a593Smuzhiyun	controller is expected to transfer data. As a result it is
182*4882a593Smuzhiyun	possible for this call to return an error, for example if the
183*4882a593Smuzhiyun	source or destination is in an unsupported VME address space.
184*4882a593Smuzhiyun
185*4882a593SmuzhiyunTransfer Attributes
186*4882a593Smuzhiyun~~~~~~~~~~~~~~~~~~~
187*4882a593Smuzhiyun
188*4882a593SmuzhiyunThe attributes for the source and destination are handled separately from adding
189*4882a593Smuzhiyunan item to a list. This is due to the diverse attributes required for each type
190*4882a593Smuzhiyunof source and destination. There are functions to create attributes for PCI, VME
191*4882a593Smuzhiyunand pattern sources and destinations (where appropriate):
192*4882a593Smuzhiyun
193*4882a593Smuzhiyun - PCI source or destination: :c:func:`vme_dma_pci_attribute`
194*4882a593Smuzhiyun - VME source or destination: :c:func:`vme_dma_vme_attribute`
195*4882a593Smuzhiyun - Pattern source: :c:func:`vme_dma_pattern_attribute`
196*4882a593Smuzhiyun
197*4882a593SmuzhiyunThe function :c:func:`vme_dma_free_attribute` should be used to free an
198*4882a593Smuzhiyunattribute.
199*4882a593Smuzhiyun
200*4882a593Smuzhiyun
201*4882a593SmuzhiyunList Execution
202*4882a593Smuzhiyun~~~~~~~~~~~~~~
203*4882a593Smuzhiyun
204*4882a593SmuzhiyunThe function :c:func:`vme_dma_list_exec` queues a list for execution and will
205*4882a593Smuzhiyunreturn once the list has been executed.
206*4882a593Smuzhiyun
207*4882a593Smuzhiyun
208*4882a593SmuzhiyunInterrupts
209*4882a593Smuzhiyun----------
210*4882a593Smuzhiyun
211*4882a593SmuzhiyunThe VME API provides functions to attach and detach callbacks to specific VME
212*4882a593Smuzhiyunlevel and status ID combinations and for the generation of VME interrupts with
213*4882a593Smuzhiyunspecific VME level and status IDs.
214*4882a593Smuzhiyun
215*4882a593Smuzhiyun
216*4882a593SmuzhiyunAttaching Interrupt Handlers
217*4882a593Smuzhiyun~~~~~~~~~~~~~~~~~~~~~~~~~~~~
218*4882a593Smuzhiyun
219*4882a593SmuzhiyunThe function :c:func:`vme_irq_request` can be used to attach and
220*4882a593Smuzhiyun:c:func:`vme_irq_free` to free a specific VME level and status ID combination.
221*4882a593SmuzhiyunAny given combination can only be assigned a single callback function. A void
222*4882a593Smuzhiyunpointer parameter is provided, the value of which is passed to the callback
223*4882a593Smuzhiyunfunction, the use of this pointer is user undefined. The callback parameters are
224*4882a593Smuzhiyunas follows. Care must be taken in writing a callback function, callback
225*4882a593Smuzhiyunfunctions run in interrupt context:
226*4882a593Smuzhiyun
227*4882a593Smuzhiyun.. code-block:: c
228*4882a593Smuzhiyun
229*4882a593Smuzhiyun	void callback(int level, int statid, void *priv);
230*4882a593Smuzhiyun
231*4882a593Smuzhiyun
232*4882a593SmuzhiyunInterrupt Generation
233*4882a593Smuzhiyun~~~~~~~~~~~~~~~~~~~~
234*4882a593Smuzhiyun
235*4882a593SmuzhiyunThe function :c:func:`vme_irq_generate` can be used to generate a VME interrupt
236*4882a593Smuzhiyunat a given VME level and VME status ID.
237*4882a593Smuzhiyun
238*4882a593Smuzhiyun
239*4882a593SmuzhiyunLocation monitors
240*4882a593Smuzhiyun-----------------
241*4882a593Smuzhiyun
242*4882a593SmuzhiyunThe VME API provides the following functionality to configure the location
243*4882a593Smuzhiyunmonitor.
244*4882a593Smuzhiyun
245*4882a593Smuzhiyun
246*4882a593SmuzhiyunLocation Monitor Management
247*4882a593Smuzhiyun~~~~~~~~~~~~~~~~~~~~~~~~~~~
248*4882a593Smuzhiyun
249*4882a593SmuzhiyunThe function :c:func:`vme_lm_request` is provided to request the use of a block
250*4882a593Smuzhiyunof location monitors and :c:func:`vme_lm_free` to free them after they are no
251*4882a593Smuzhiyunlonger required. Each block may provide a number of location monitors,
252*4882a593Smuzhiyunmonitoring adjacent locations. The function :c:func:`vme_lm_count` can be used
253*4882a593Smuzhiyunto determine how many locations are provided.
254*4882a593Smuzhiyun
255*4882a593Smuzhiyun
256*4882a593SmuzhiyunLocation Monitor Configuration
257*4882a593Smuzhiyun~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
258*4882a593Smuzhiyun
259*4882a593SmuzhiyunOnce a bank of location monitors has been allocated, the function
260*4882a593Smuzhiyun:c:func:`vme_lm_set` is provided to configure the location and mode of the
261*4882a593Smuzhiyunlocation monitor. The function :c:func:`vme_lm_get` can be used to retrieve
262*4882a593Smuzhiyunexisting settings.
263*4882a593Smuzhiyun
264*4882a593Smuzhiyun
265*4882a593SmuzhiyunLocation Monitor Use
266*4882a593Smuzhiyun~~~~~~~~~~~~~~~~~~~~
267*4882a593Smuzhiyun
268*4882a593SmuzhiyunThe function :c:func:`vme_lm_attach` enables a callback to be attached and
269*4882a593Smuzhiyun:c:func:`vme_lm_detach` allows on to be detached from each location monitor
270*4882a593Smuzhiyunlocation. Each location monitor can monitor a number of adjacent locations. The
271*4882a593Smuzhiyuncallback function is declared as follows.
272*4882a593Smuzhiyun
273*4882a593Smuzhiyun.. code-block:: c
274*4882a593Smuzhiyun
275*4882a593Smuzhiyun	void callback(void *data);
276*4882a593Smuzhiyun
277*4882a593Smuzhiyun
278*4882a593SmuzhiyunSlot Detection
279*4882a593Smuzhiyun--------------
280*4882a593Smuzhiyun
281*4882a593SmuzhiyunThe function :c:func:`vme_slot_num` returns the slot ID of the provided bridge.
282*4882a593Smuzhiyun
283*4882a593Smuzhiyun
284*4882a593SmuzhiyunBus Detection
285*4882a593Smuzhiyun-------------
286*4882a593Smuzhiyun
287*4882a593SmuzhiyunThe function :c:func:`vme_bus_num` returns the bus ID of the provided bridge.
288*4882a593Smuzhiyun
289*4882a593Smuzhiyun
290*4882a593SmuzhiyunVME API
291*4882a593Smuzhiyun-------
292*4882a593Smuzhiyun
293*4882a593Smuzhiyun.. kernel-doc:: include/linux/vme.h
294*4882a593Smuzhiyun   :internal:
295*4882a593Smuzhiyun
296*4882a593Smuzhiyun.. kernel-doc:: drivers/vme/vme.c
297*4882a593Smuzhiyun   :export:
298