aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorStefan Richter <stefanr@s5r6.in-berlin.de>2010-06-20 16:52:55 -0400
committerStefan Richter <stefanr@s5r6.in-berlin.de>2010-06-20 17:11:56 -0400
commit604f45167824e18ad5766e51ecf1d4d65f15118d (patch)
tree40deeca88e1788e98d54d82f429a45ce276c4135
parent0244f57302f7e8bebd2f1ab58767eac2e9f678a6 (diff)
firewire: cdev: freeze FW_CDEV_VERSION due to libraw1394 bug
libraw1394 v2.0.0...v2.0.5 takes FW_CDEV_VERSION from an externally installed header file and uses it to declare its own implementation level in FW_CDEV_IOC_GET_INFO. This is wrong; it should set the real version for which it was actually written. If we add features to the kernel ABI that require the kernel to check a client's implementation level, we can not trust the client version if it was set from FW_CDEV_VERSION. Hence freeze FW_CDEV_VERSION at the current value (no damage has been done yet), clearly document FW_CDEV_VERSION as a dummy version and what clients are expected to do with fw_cdev_get_info.version, and use a new defined constant (which is not placed into the exported header file) as kernel implementation level. Note, in order to check in client program source code which features are present in an externally installed linux/firewire-cdev.h, use preprocessor directives like #ifdef FW_CDEV_IOC_ALLOCATE_ISO_RESOURCE or #ifdef FW_CDEV_EVENT_ISO_RESOURCE_ALLOCATED instead of a check of FW_CDEV_VERSION. Signed-off-by: Stefan Richter <stefanr@s5r6.in-berlin.de>
-rw-r--r--drivers/firewire/core-cdev.c7
-rw-r--r--include/linux/firewire-cdev.h22
2 files changed, 22 insertions, 7 deletions
diff --git a/drivers/firewire/core-cdev.c b/drivers/firewire/core-cdev.c
index 8f8c8eeaf046..0cf86bcbeea2 100644
--- a/drivers/firewire/core-cdev.c
+++ b/drivers/firewire/core-cdev.c
@@ -46,6 +46,11 @@
46 46
47#include "core.h" 47#include "core.h"
48 48
49/*
50 * ABI version history is documented in linux/firewire-cdev.h.
51 */
52#define FW_CDEV_KERNEL_VERSION 3
53
49struct client { 54struct client {
50 u32 version; 55 u32 version;
51 struct fw_device *device; 56 struct fw_device *device;
@@ -395,7 +400,7 @@ static int ioctl_get_info(struct client *client, union ioctl_arg *arg)
395 unsigned long ret = 0; 400 unsigned long ret = 0;
396 401
397 client->version = a->version; 402 client->version = a->version;
398 a->version = FW_CDEV_VERSION; 403 a->version = FW_CDEV_KERNEL_VERSION;
399 a->card = client->device->card->index; 404 a->card = client->device->card->index;
400 405
401 down_read(&fw_device_rwsem); 406 down_read(&fw_device_rwsem);
diff --git a/include/linux/firewire-cdev.h b/include/linux/firewire-cdev.h
index 6ffb24a1f2f2..0d0cc07358af 100644
--- a/include/linux/firewire-cdev.h
+++ b/include/linux/firewire-cdev.h
@@ -219,7 +219,7 @@ union fw_cdev_event {
219 struct fw_cdev_event_response response; 219 struct fw_cdev_event_response response;
220 struct fw_cdev_event_request request; 220 struct fw_cdev_event_request request;
221 struct fw_cdev_event_iso_interrupt iso_interrupt; 221 struct fw_cdev_event_iso_interrupt iso_interrupt;
222 struct fw_cdev_event_iso_resource iso_resource; 222 struct fw_cdev_event_iso_resource iso_resource; /* added in 2.6.30 */
223}; 223};
224 224
225/* available since kernel version 2.6.22 */ 225/* available since kernel version 2.6.22 */
@@ -252,22 +252,32 @@ union fw_cdev_event {
252#define FW_CDEV_IOC_GET_CYCLE_TIMER2 _IOWR('#', 0x14, struct fw_cdev_get_cycle_timer2) 252#define FW_CDEV_IOC_GET_CYCLE_TIMER2 _IOWR('#', 0x14, struct fw_cdev_get_cycle_timer2)
253 253
254/* 254/*
255 * FW_CDEV_VERSION History 255 * ABI version history
256 * 1 (2.6.22) - initial version 256 * 1 (2.6.22) - initial version
257 * (2.6.24) - added %FW_CDEV_IOC_GET_CYCLE_TIMER
257 * 2 (2.6.30) - changed &fw_cdev_event_iso_interrupt.header if 258 * 2 (2.6.30) - changed &fw_cdev_event_iso_interrupt.header if
258 * &fw_cdev_create_iso_context.header_size is 8 or more 259 * &fw_cdev_create_iso_context.header_size is 8 or more
260 * - added %FW_CDEV_IOC_*_ISO_RESOURCE*,
261 * %FW_CDEV_IOC_GET_SPEED, %FW_CDEV_IOC_SEND_BROADCAST_REQUEST,
262 * %FW_CDEV_IOC_SEND_STREAM_PACKET
259 * (2.6.32) - added time stamp to xmit &fw_cdev_event_iso_interrupt 263 * (2.6.32) - added time stamp to xmit &fw_cdev_event_iso_interrupt
260 * (2.6.33) - IR has always packet-per-buffer semantics now, not one of 264 * (2.6.33) - IR has always packet-per-buffer semantics now, not one of
261 * dual-buffer or packet-per-buffer depending on hardware 265 * dual-buffer or packet-per-buffer depending on hardware
262 * 3 (2.6.34) - made &fw_cdev_get_cycle_timer reliable 266 * 3 (2.6.34) - made &fw_cdev_get_cycle_timer reliable
267 * - added %FW_CDEV_IOC_GET_CYCLE_TIMER2
263 */ 268 */
264#define FW_CDEV_VERSION 3 269#define FW_CDEV_VERSION 3 /* Meaningless; don't use this macro. */
265 270
266/** 271/**
267 * struct fw_cdev_get_info - General purpose information ioctl 272 * struct fw_cdev_get_info - General purpose information ioctl
268 * @version: The version field is just a running serial number. 273 * @version: The version field is just a running serial number. Both an
269 * We never break backwards compatibility, but may add more 274 * input parameter (ABI version implemented by the client) and
270 * structs and ioctls in later revisions. 275 * output parameter (ABI version implemented by the kernel).
276 * A client must not fill in an %FW_CDEV_VERSION defined from an
277 * included kernel header file but the actual version for which
278 * the client was implemented. This is necessary for forward
279 * compatibility. We never break backwards compatibility, but
280 * may add more structs, events, and ioctls in later revisions.
271 * @rom_length: If @rom is non-zero, at most rom_length bytes of configuration 281 * @rom_length: If @rom is non-zero, at most rom_length bytes of configuration
272 * ROM will be copied into that user space address. In either 282 * ROM will be copied into that user space address. In either
273 * case, @rom_length is updated with the actual length of the 283 * case, @rom_length is updated with the actual length of the