2 * vme_misc.c - PCI-VME bridge miscellaneous interfaces
4 * Copyright (c) 2009 Sebastien Dugue
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the
8 * Free Software Foundation; either version 2 of the License, or (at your
9 * option) any later version.
14 * This file provides some PCI-VME bridge miscellaneous interfaces:
16 * - Access to VME control (requestor, arbitrer) - Not implemented yet
17 * - VME Bus error checking
20 #include "vme_bridge.h"
22 int vme_bus_error_check(int clear
)
24 return tsi148_bus_error_chk(vme_bridge
->regs
, clear
);
26 EXPORT_SYMBOL_GPL(vme_bus_error_check
);
29 __vme_bus_error_check_clear(struct vme_bus_error
*err
)
31 struct vme_bus_error_desc
*desc
= &vme_bridge
->verr
.desc
;
32 struct vme_bus_error
*vme_err
= &desc
->error
;
34 if (desc
->valid
&& vme_err
->am
== err
->am
&&
35 vme_err
->address
== err
->address
) {
45 * vme_register_berr_handler() - register a VME Bus Error handler
46 * @error: Bus Error descriptor: Initial Address + Address Modifier
47 * @size: Size of the address range of interest. The Initial Address
48 * is the address provided in @error.
49 * @func: Handler function for the bus errors in the range above.
51 * NOTE: the handler function will be called in interrupt context.
52 * Return the address of the registered handler on success, ERR_PTR otherwise.
54 struct vme_berr_handler
*
55 vme_register_berr_handler(struct vme_bus_error
*error
, size_t size
,
56 vme_berr_handler_t func
)
58 spinlock_t
*lock
= &vme_bridge
->verr
.lock
;
59 struct vme_berr_handler
*handler
;
63 printk(KERN_WARNING PFX
"%s: size cannot be 0.\n", __func__
);
64 return ERR_PTR(-EINVAL
);
67 handler
= kzalloc(sizeof(struct vme_berr_handler
), GFP_KERNEL
);
68 if (handler
== NULL
) {
69 printk(KERN_ERR PFX
"Unable to allocate Bus Error Handler\n");
70 return ERR_PTR(-ENOMEM
);
73 spin_lock_irqsave(lock
, flags
);
75 memcpy(&handler
->error
, error
, sizeof(struct vme_bus_error
));
78 list_add_tail(&handler
->h_list
, &vme_bridge
->verr
.h_list
);
80 spin_unlock_irqrestore(lock
, flags
);
84 EXPORT_SYMBOL_GPL(vme_register_berr_handler
);
86 static void __vme_unregister_berr_handler(struct vme_berr_handler
*handler
)
88 struct list_head
*h_pos
, *temp
;
89 struct vme_berr_handler
*entry
;
91 list_for_each_safe(h_pos
, temp
, &vme_bridge
->verr
.h_list
) {
92 entry
= list_entry(h_pos
, struct vme_berr_handler
, h_list
);
94 if (entry
== handler
) {
100 printk(KERN_WARNING PFX
"%s: handler not found\n", __func__
);
104 * vme_unregister_berr_handler - Unregister a VME Bus Error Handler
105 * @handler: Address of the registered handler to be removed.
107 void vme_unregister_berr_handler(struct vme_berr_handler
*handler
)
109 spinlock_t
*lock
= &vme_bridge
->verr
.lock
;
112 spin_lock_irqsave(lock
, flags
);
113 __vme_unregister_berr_handler(handler
);
114 spin_unlock_irqrestore(lock
, flags
);
116 EXPORT_SYMBOL_GPL(vme_unregister_berr_handler
);
119 * vme_bus_error_check_clear - check and clear VME bus errors
120 * @bus_error: bus error to be checked
122 * Note: the bus error is only cleared if it matches the given bus
125 int vme_bus_error_check_clear(struct vme_bus_error
*err
)
131 lock
= &vme_bridge
->verr
.lock
;
133 spin_lock_irqsave(lock
, flags
);
134 ret
= __vme_bus_error_check_clear(err
);
135 spin_unlock_irqrestore(lock
, flags
);
139 EXPORT_SYMBOL_GPL(vme_bus_error_check_clear
);
141 ssize_t
vme_misc_read(struct file
*file
, char *buf
, size_t count
,
147 ssize_t
vme_misc_write(struct file
*file
, const char *buf
, size_t count
,
153 long vme_misc_ioctl(struct file
*file
, unsigned int cmd
, unsigned long arg
)