[PATCH 09/11] staging: comedi: jr3_pci: re-work struct jr3_pci_subdev_private range

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



The `range` member of `struct jr3_pci_subdev_private` is an array of a
tag-less `struct` type whose layout is similar to `struct
comedi_lrange`.  Both `struct` types end with a member also called
`range`.  In the case of tag-less `struct` type, it is a single `struct
comedi_krange`.  In the case of `struct comedi_lrange`, it is a flexible
array of `struct comedi_krange`.

Elements of the `range` array member in `struct jr3_pci_subdev_private`
are pointed to by elements of the `range_table_list` array member, which
are of type `const struct comedi_lrange *`.  This requires some dodgy
type casting.

To avoid the dodgy type casting, change the element type of the `range`
member of `struct jr3_pci_subdev_private` to be a new type `union
jr3_pci_single_range`.  This contains a member `l` of type `struct
comedi_lrange`, and an array member `_reserved` that is large enough to
encompass the `struct comedi_lrange` plus a single `struct
comedi_krange`.  It is the same size as the previous type.  Accesses to
`spriv->range[i].length` and `spriv->range[i].range` are replaced with
`spriv->range[i].l.length` and `spriv->range[i].l.range[0]` respectively
(where `spriv` is a `struct jr3_pci_subdev_private *`, and `i` is an
array index).  Type-casted pointers to `spriv->range[i]` are replaced
with pointers to `spriv->range[i].l`, which do not require the type
casts.  Since we defined a new type, we can define local variables of
the corresponding pointer type to shorten some lines of code.  This is
made use of in `jr3_pci_alloc_spriv()`.

Signed-off-by: Ian Abbott <abbotti@xxxxxxxxx>
---
Note that this patch produces these two checkpatch warnings:

WARNING: struct comedi_lrange should normally be const
+	struct comedi_lrange l;

WARNING: struct comedi_lrange should normally be const
+	char _reserved[offsetof(struct comedi_lrange, range[1])];

For the first one, this driver determines ranges at run-time, so they
are non-const.  The second one is pretty irrelevant as it is only being
used as part of an offsetof() macro call..
---
 drivers/staging/comedi/drivers/jr3_pci.c | 70 ++++++++++++++++----------------
 1 file changed, 35 insertions(+), 35 deletions(-)

diff --git a/drivers/staging/comedi/drivers/jr3_pci.c b/drivers/staging/comedi/drivers/jr3_pci.c
index 749f5069c42f..59030f3b382b 100644
--- a/drivers/staging/comedi/drivers/jr3_pci.c
+++ b/drivers/staging/comedi/drivers/jr3_pci.c
@@ -99,6 +99,11 @@ struct jr3_pci_dev_private {
 	struct timer_list timer;
 };
 
+union jr3_pci_single_range {
+	struct comedi_lrange l;
+	char _reserved[offsetof(struct comedi_lrange, range[1])];
+};
+
 enum jr3_pci_poll_state {
 	state_jr3_poll,
 	state_jr3_init_wait_for_offset,
@@ -114,10 +119,7 @@ struct jr3_pci_subdev_private {
 	enum jr3_pci_poll_state state;
 	int serial_no;
 	int model_no;
-	struct {
-		int length;
-		struct comedi_krange range;
-	} range[9];
+	union jr3_pci_single_range range[9];
 	const struct comedi_lrange *range_table_list[8 * 7 + 2];
 	unsigned int maxdata_list[8 * 7 + 2];
 	u16 errors;
@@ -532,27 +534,28 @@ jr3_pci_poll_subdevice(struct comedi_subdevice *s)
 			result = poll_delay_min_max(20, 100);
 		} else {
 			struct force_array __iomem *fs = &channel->full_scale;
+			union jr3_pci_single_range *r = spriv->range;
 
 			/* Use ranges in kN or we will overflow around 2000N! */
-			spriv->range[0].range.min = -get_s16(&fs->fx) * 1000;
-			spriv->range[0].range.max = get_s16(&fs->fx) * 1000;
-			spriv->range[1].range.min = -get_s16(&fs->fy) * 1000;
-			spriv->range[1].range.max = get_s16(&fs->fy) * 1000;
-			spriv->range[2].range.min = -get_s16(&fs->fz) * 1000;
-			spriv->range[2].range.max = get_s16(&fs->fz) * 1000;
-			spriv->range[3].range.min = -get_s16(&fs->mx) * 100;
-			spriv->range[3].range.max = get_s16(&fs->mx) * 100;
-			spriv->range[4].range.min = -get_s16(&fs->my) * 100;
-			spriv->range[4].range.max = get_s16(&fs->my) * 100;
-			spriv->range[5].range.min = -get_s16(&fs->mz) * 100;
+			r[0].l.range[0].min = -get_s16(&fs->fx) * 1000;
+			r[0].l.range[0].max = get_s16(&fs->fx) * 1000;
+			r[1].l.range[0].min = -get_s16(&fs->fy) * 1000;
+			r[1].l.range[0].max = get_s16(&fs->fy) * 1000;
+			r[2].l.range[0].min = -get_s16(&fs->fz) * 1000;
+			r[2].l.range[0].max = get_s16(&fs->fz) * 1000;
+			r[3].l.range[0].min = -get_s16(&fs->mx) * 100;
+			r[3].l.range[0].max = get_s16(&fs->mx) * 100;
+			r[4].l.range[0].min = -get_s16(&fs->my) * 100;
+			r[4].l.range[0].max = get_s16(&fs->my) * 100;
+			r[5].l.range[0].min = -get_s16(&fs->mz) * 100;
 			/* the next five are questionable */
-			spriv->range[5].range.max = get_s16(&fs->mz) * 100;
-			spriv->range[6].range.min = -get_s16(&fs->v1) * 100;
-			spriv->range[6].range.max = get_s16(&fs->v1) * 100;
-			spriv->range[7].range.min = -get_s16(&fs->v2) * 100;
-			spriv->range[7].range.max = get_s16(&fs->v2) * 100;
-			spriv->range[8].range.min = 0;
-			spriv->range[8].range.max = 65535;
+			r[5].l.range[0].max = get_s16(&fs->mz) * 100;
+			r[6].l.range[0].min = -get_s16(&fs->v1) * 100;
+			r[6].l.range[0].max = get_s16(&fs->v1) * 100;
+			r[7].l.range[0].min = -get_s16(&fs->v2) * 100;
+			r[7].l.range[0].max = get_s16(&fs->v2) * 100;
+			r[8].l.range[0].min = 0;
+			r[8].l.range[0].max = 65535;
 
 			use_offset(channel, 0);
 			spriv->state = state_jr3_init_use_offset_complete;
@@ -643,24 +646,21 @@ jr3_pci_alloc_spriv(struct comedi_device *dev, struct comedi_subdevice *s)
 	spriv->channel = &devpriv->iobase->channel[s->index].data;
 
 	for (j = 0; j < 8; j++) {
-		spriv->range[j].length = 1;
-		spriv->range[j].range.min = -1000000;
-		spriv->range[j].range.max = 1000000;
+		spriv->range[j].l.length = 1;
+		spriv->range[j].l.range[0].min = -1000000;
+		spriv->range[j].l.range[0].max = 1000000;
 
 		for (k = 0; k < 7; k++) {
-			spriv->range_table_list[j + k * 8] =
-				(const struct comedi_lrange *)&spriv->range[j];
+			spriv->range_table_list[j + k * 8] = &spriv->range[j].l;
 			spriv->maxdata_list[j + k * 8] = 0x7fff;
 		}
 	}
-	spriv->range[8].length = 1;
-	spriv->range[8].range.min = 0;
-	spriv->range[8].range.max = 65536;
-
-	spriv->range_table_list[56] =
-		(const struct comedi_lrange *)&spriv->range[8];
-	spriv->range_table_list[57] =
-		(const struct comedi_lrange *)&spriv->range[8];
+	spriv->range[8].l.length = 1;
+	spriv->range[8].l.range[0].min = 0;
+	spriv->range[8].l.range[0].max = 65536;
+
+	spriv->range_table_list[56] = &spriv->range[8].l;
+	spriv->range_table_list[57] = &spriv->range[8].l;
 	spriv->maxdata_list[56] = 0xffff;
 	spriv->maxdata_list[57] = 0xffff;
 
-- 
2.11.0

_______________________________________________
devel mailing list
devel@xxxxxxxxxxxxxxxxxxxxxx
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel



[Index of Archives]     [Linux Driver Backports]     [DMA Engine]     [Linux GPIO]     [Linux SPI]     [Video for Linux]     [Linux USB Devel]     [Linux Coverity]     [Linux Audio Users]     [Linux Kernel]     [Linux SCSI]     [Yosemite Backpacking]
  Powered by Linux