From b47d82cb176427c78627d8791cc1361be9c0e971 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Wed, 21 May 2008 00:30:31 +0000 Subject: cinergyT2: endianness annotations, endianness and race fixes From: Al Viro Endianness annotations and fixes + fixing the handling of ->uncorrected_block_count Signed-off-by: Al Viro Signed-off-by: Mauro Carvalho Chehab --- linux/drivers/media/dvb/cinergyT2/cinergyT2.c | 46 ++++++++++++++------------- 1 file changed, 24 insertions(+), 22 deletions(-) (limited to 'linux/drivers/media/dvb/cinergyT2') diff --git a/linux/drivers/media/dvb/cinergyT2/cinergyT2.c b/linux/drivers/media/dvb/cinergyT2/cinergyT2.c index 728197340..651df056e 100644 --- a/linux/drivers/media/dvb/cinergyT2/cinergyT2.c +++ b/linux/drivers/media/dvb/cinergyT2/cinergyT2.c @@ -95,22 +95,22 @@ enum cinergyt2_ep1_cmd { struct dvbt_set_parameters_msg { uint8_t cmd; - uint32_t freq; + __le32 freq; uint8_t bandwidth; - uint16_t tps; + __le16 tps; uint8_t flags; } __attribute__((packed)); struct dvbt_get_status_msg { - uint32_t freq; + __le32 freq; uint8_t bandwidth; - uint16_t tps; + __le16 tps; uint8_t flags; - uint16_t gain; + __le16 gain; uint8_t snr; - uint32_t viterbi_error_rate; - uint32_t rs_error_rate; - uint32_t uncorrected_block_count; + __le32 viterbi_error_rate; + __le32 rs_error_rate; + __le32 uncorrected_block_count; uint8_t lock_bits; uint8_t prev_lock_bits; } __attribute__((packed)); @@ -158,6 +158,7 @@ struct cinergyt2 { wait_queue_head_t poll_wq; int pending_fe_events; int disconnect_pending; + unsigned int uncorrected_block_count; atomic_t inuse; void *streambuf; @@ -173,7 +174,7 @@ struct cinergyt2 { struct delayed_work rc_query_work; #endif int rc_input_event; - u32 rc_last_code; + __le32 rc_last_code; unsigned long last_event_jiffies; #endif }; @@ -186,7 +187,7 @@ enum { struct cinergyt2_rc_event { char type; - uint32_t value; + __le32 value; } __attribute__((packed)); static const uint32_t rc_keys[] = { @@ -653,8 +654,11 @@ static int cinergyt2_ioctl (struct inode *inode, struct file *file, { uint32_t unc_count; - unc_count = stat->uncorrected_block_count; - stat->uncorrected_block_count = 0; + if (mutex_lock_interruptible(&cinergyt2->sem)) + return -ERESTARTSYS; + unc_count = cinergyt2->uncorrected_block_count; + cinergyt2->uncorrected_block_count = 0; + mutex_unlock(&cinergyt2->sem); /* UNC are already converted to host byte order... */ return put_user(unc_count,(__u32 __user *) arg); @@ -811,7 +815,7 @@ static void cinergyt2_query_rc (struct work_struct *work) input_sync(cinergyt2->rc_input_dev); cinergyt2->rc_input_event = KEY_MAX; } - cinergyt2->rc_last_code = ~0; + cinergyt2->rc_last_code = cpu_to_le32(~0); } goto out; } @@ -822,7 +826,7 @@ static void cinergyt2_query_rc (struct work_struct *work) n, le32_to_cpu(rc_events[n].value), rc_events[n].type); if (rc_events[n].type == CINERGYT2_RC_EVENT_TYPE_NEC && - rc_events[n].value == ~0) { + rc_events[n].value == cpu_to_le32(~0)) { /* keyrepeat bit -> just repeat last rc_input_event */ } else { cinergyt2->rc_input_event = KEY_MAX; @@ -837,7 +841,7 @@ static void cinergyt2_query_rc (struct work_struct *work) if (cinergyt2->rc_input_event != KEY_MAX) { if (rc_events[n].value == cinergyt2->rc_last_code && - cinergyt2->rc_last_code != ~0) { + cinergyt2->rc_last_code != cpu_to_le32(~0)) { /* emit a key-up so the double event is recognized */ dprintk(1, "rc_input_event=%d UP\n", cinergyt2->rc_input_event); input_report_key(cinergyt2->rc_input_dev, @@ -871,7 +875,7 @@ static int cinergyt2_register_rc(struct cinergyt2 *cinergyt2) usb_make_path(cinergyt2->udev, cinergyt2->phys, sizeof(cinergyt2->phys)); strlcat(cinergyt2->phys, "/input0", sizeof(cinergyt2->phys)); cinergyt2->rc_input_event = KEY_MAX; - cinergyt2->rc_last_code = ~0; + cinergyt2->rc_last_code = cpu_to_le32(~0); #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20) INIT_WORK(&cinergyt2->rc_query_work, cinergyt2_query_rc, cinergyt2); #else @@ -886,8 +890,8 @@ static int cinergyt2_register_rc(struct cinergyt2 *cinergyt2) input_dev->keycodesize = 0; input_dev->keycodemax = 0; input_dev->id.bustype = BUS_USB; - input_dev->id.vendor = cinergyt2->udev->descriptor.idVendor; - input_dev->id.product = cinergyt2->udev->descriptor.idProduct; + input_dev->id.vendor = le16_to_cpu(cinergyt2->udev->descriptor.idVendor); + input_dev->id.product = le16_to_cpu(cinergyt2->udev->descriptor.idProduct); input_dev->id.version = 1; #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22) input_dev->dev.parent = &cinergyt2->udev->dev; @@ -951,18 +955,16 @@ static void cinergyt2_query (struct work_struct *work) char cmd [] = { CINERGYT2_EP1_GET_TUNER_STATUS }; struct dvbt_get_status_msg *s = &cinergyt2->status; uint8_t lock_bits; - uint32_t unc; if (cinergyt2->disconnect_pending || mutex_lock_interruptible(&cinergyt2->sem)) return; - unc = s->uncorrected_block_count; lock_bits = s->lock_bits; cinergyt2_command(cinergyt2, cmd, sizeof(cmd), (char *) s, sizeof(*s)); - unc += le32_to_cpu(s->uncorrected_block_count); - s->uncorrected_block_count = unc; + cinergyt2->uncorrected_block_count += + le32_to_cpu(s->uncorrected_block_count); if (lock_bits != s->lock_bits) { wake_up_interruptible(&cinergyt2->poll_wq); -- cgit v1.2.3 From e92f78bc63e71d1572225b93b4ea0c31e6e6efc0 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Tue, 3 Jun 2008 14:50:32 -0300 Subject: backout changeset e30f9c367fabf6227e17c5191c62f886d55eb2d7 From: Mauro Carvalho Chehab Unfortunately, this patch were mixed with an experimental patch I'm working with. Signed-off-by: Mauro Carvalho Chehab --- linux/drivers/media/dvb/cinergyT2/cinergyT2.c | 46 +++++++++++++-------------- 1 file changed, 22 insertions(+), 24 deletions(-) (limited to 'linux/drivers/media/dvb/cinergyT2') diff --git a/linux/drivers/media/dvb/cinergyT2/cinergyT2.c b/linux/drivers/media/dvb/cinergyT2/cinergyT2.c index 651df056e..728197340 100644 --- a/linux/drivers/media/dvb/cinergyT2/cinergyT2.c +++ b/linux/drivers/media/dvb/cinergyT2/cinergyT2.c @@ -95,22 +95,22 @@ enum cinergyt2_ep1_cmd { struct dvbt_set_parameters_msg { uint8_t cmd; - __le32 freq; + uint32_t freq; uint8_t bandwidth; - __le16 tps; + uint16_t tps; uint8_t flags; } __attribute__((packed)); struct dvbt_get_status_msg { - __le32 freq; + uint32_t freq; uint8_t bandwidth; - __le16 tps; + uint16_t tps; uint8_t flags; - __le16 gain; + uint16_t gain; uint8_t snr; - __le32 viterbi_error_rate; - __le32 rs_error_rate; - __le32 uncorrected_block_count; + uint32_t viterbi_error_rate; + uint32_t rs_error_rate; + uint32_t uncorrected_block_count; uint8_t lock_bits; uint8_t prev_lock_bits; } __attribute__((packed)); @@ -158,7 +158,6 @@ struct cinergyt2 { wait_queue_head_t poll_wq; int pending_fe_events; int disconnect_pending; - unsigned int uncorrected_block_count; atomic_t inuse; void *streambuf; @@ -174,7 +173,7 @@ struct cinergyt2 { struct delayed_work rc_query_work; #endif int rc_input_event; - __le32 rc_last_code; + u32 rc_last_code; unsigned long last_event_jiffies; #endif }; @@ -187,7 +186,7 @@ enum { struct cinergyt2_rc_event { char type; - __le32 value; + uint32_t value; } __attribute__((packed)); static const uint32_t rc_keys[] = { @@ -654,11 +653,8 @@ static int cinergyt2_ioctl (struct inode *inode, struct file *file, { uint32_t unc_count; - if (mutex_lock_interruptible(&cinergyt2->sem)) - return -ERESTARTSYS; - unc_count = cinergyt2->uncorrected_block_count; - cinergyt2->uncorrected_block_count = 0; - mutex_unlock(&cinergyt2->sem); + unc_count = stat->uncorrected_block_count; + stat->uncorrected_block_count = 0; /* UNC are already converted to host byte order... */ return put_user(unc_count,(__u32 __user *) arg); @@ -815,7 +811,7 @@ static void cinergyt2_query_rc (struct work_struct *work) input_sync(cinergyt2->rc_input_dev); cinergyt2->rc_input_event = KEY_MAX; } - cinergyt2->rc_last_code = cpu_to_le32(~0); + cinergyt2->rc_last_code = ~0; } goto out; } @@ -826,7 +822,7 @@ static void cinergyt2_query_rc (struct work_struct *work) n, le32_to_cpu(rc_events[n].value), rc_events[n].type); if (rc_events[n].type == CINERGYT2_RC_EVENT_TYPE_NEC && - rc_events[n].value == cpu_to_le32(~0)) { + rc_events[n].value == ~0) { /* keyrepeat bit -> just repeat last rc_input_event */ } else { cinergyt2->rc_input_event = KEY_MAX; @@ -841,7 +837,7 @@ static void cinergyt2_query_rc (struct work_struct *work) if (cinergyt2->rc_input_event != KEY_MAX) { if (rc_events[n].value == cinergyt2->rc_last_code && - cinergyt2->rc_last_code != cpu_to_le32(~0)) { + cinergyt2->rc_last_code != ~0) { /* emit a key-up so the double event is recognized */ dprintk(1, "rc_input_event=%d UP\n", cinergyt2->rc_input_event); input_report_key(cinergyt2->rc_input_dev, @@ -875,7 +871,7 @@ static int cinergyt2_register_rc(struct cinergyt2 *cinergyt2) usb_make_path(cinergyt2->udev, cinergyt2->phys, sizeof(cinergyt2->phys)); strlcat(cinergyt2->phys, "/input0", sizeof(cinergyt2->phys)); cinergyt2->rc_input_event = KEY_MAX; - cinergyt2->rc_last_code = cpu_to_le32(~0); + cinergyt2->rc_last_code = ~0; #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20) INIT_WORK(&cinergyt2->rc_query_work, cinergyt2_query_rc, cinergyt2); #else @@ -890,8 +886,8 @@ static int cinergyt2_register_rc(struct cinergyt2 *cinergyt2) input_dev->keycodesize = 0; input_dev->keycodemax = 0; input_dev->id.bustype = BUS_USB; - input_dev->id.vendor = le16_to_cpu(cinergyt2->udev->descriptor.idVendor); - input_dev->id.product = le16_to_cpu(cinergyt2->udev->descriptor.idProduct); + input_dev->id.vendor = cinergyt2->udev->descriptor.idVendor; + input_dev->id.product = cinergyt2->udev->descriptor.idProduct; input_dev->id.version = 1; #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22) input_dev->dev.parent = &cinergyt2->udev->dev; @@ -955,16 +951,18 @@ static void cinergyt2_query (struct work_struct *work) char cmd [] = { CINERGYT2_EP1_GET_TUNER_STATUS }; struct dvbt_get_status_msg *s = &cinergyt2->status; uint8_t lock_bits; + uint32_t unc; if (cinergyt2->disconnect_pending || mutex_lock_interruptible(&cinergyt2->sem)) return; + unc = s->uncorrected_block_count; lock_bits = s->lock_bits; cinergyt2_command(cinergyt2, cmd, sizeof(cmd), (char *) s, sizeof(*s)); - cinergyt2->uncorrected_block_count += - le32_to_cpu(s->uncorrected_block_count); + unc += le32_to_cpu(s->uncorrected_block_count); + s->uncorrected_block_count = unc; if (lock_bits != s->lock_bits) { wake_up_interruptible(&cinergyt2->poll_wq); -- cgit v1.2.3 From 480df628e9153e3669da57b2a41eacc00666066c Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Tue, 3 Jun 2008 17:37:03 -0300 Subject: cinergyT2: endianness annotations, endianness and race fixes From: Al Viro Endianness annotations and fixes + fixing the handling of ->uncorrected_block_count Signed-off-by: Al Viro Signed-off-by: Mauro Carvalho Chehab PS.: I've reapplied this patch since changeset e30f9c367fab got mangled. --- linux/drivers/media/dvb/cinergyT2/cinergyT2.c | 46 ++++++++++++++------------- 1 file changed, 24 insertions(+), 22 deletions(-) (limited to 'linux/drivers/media/dvb/cinergyT2') diff --git a/linux/drivers/media/dvb/cinergyT2/cinergyT2.c b/linux/drivers/media/dvb/cinergyT2/cinergyT2.c index 728197340..651df056e 100644 --- a/linux/drivers/media/dvb/cinergyT2/cinergyT2.c +++ b/linux/drivers/media/dvb/cinergyT2/cinergyT2.c @@ -95,22 +95,22 @@ enum cinergyt2_ep1_cmd { struct dvbt_set_parameters_msg { uint8_t cmd; - uint32_t freq; + __le32 freq; uint8_t bandwidth; - uint16_t tps; + __le16 tps; uint8_t flags; } __attribute__((packed)); struct dvbt_get_status_msg { - uint32_t freq; + __le32 freq; uint8_t bandwidth; - uint16_t tps; + __le16 tps; uint8_t flags; - uint16_t gain; + __le16 gain; uint8_t snr; - uint32_t viterbi_error_rate; - uint32_t rs_error_rate; - uint32_t uncorrected_block_count; + __le32 viterbi_error_rate; + __le32 rs_error_rate; + __le32 uncorrected_block_count; uint8_t lock_bits; uint8_t prev_lock_bits; } __attribute__((packed)); @@ -158,6 +158,7 @@ struct cinergyt2 { wait_queue_head_t poll_wq; int pending_fe_events; int disconnect_pending; + unsigned int uncorrected_block_count; atomic_t inuse; void *streambuf; @@ -173,7 +174,7 @@ struct cinergyt2 { struct delayed_work rc_query_work; #endif int rc_input_event; - u32 rc_last_code; + __le32 rc_last_code; unsigned long last_event_jiffies; #endif }; @@ -186,7 +187,7 @@ enum { struct cinergyt2_rc_event { char type; - uint32_t value; + __le32 value; } __attribute__((packed)); static const uint32_t rc_keys[] = { @@ -653,8 +654,11 @@ static int cinergyt2_ioctl (struct inode *inode, struct file *file, { uint32_t unc_count; - unc_count = stat->uncorrected_block_count; - stat->uncorrected_block_count = 0; + if (mutex_lock_interruptible(&cinergyt2->sem)) + return -ERESTARTSYS; + unc_count = cinergyt2->uncorrected_block_count; + cinergyt2->uncorrected_block_count = 0; + mutex_unlock(&cinergyt2->sem); /* UNC are already converted to host byte order... */ return put_user(unc_count,(__u32 __user *) arg); @@ -811,7 +815,7 @@ static void cinergyt2_query_rc (struct work_struct *work) input_sync(cinergyt2->rc_input_dev); cinergyt2->rc_input_event = KEY_MAX; } - cinergyt2->rc_last_code = ~0; + cinergyt2->rc_last_code = cpu_to_le32(~0); } goto out; } @@ -822,7 +826,7 @@ static void cinergyt2_query_rc (struct work_struct *work) n, le32_to_cpu(rc_events[n].value), rc_events[n].type); if (rc_events[n].type == CINERGYT2_RC_EVENT_TYPE_NEC && - rc_events[n].value == ~0) { + rc_events[n].value == cpu_to_le32(~0)) { /* keyrepeat bit -> just repeat last rc_input_event */ } else { cinergyt2->rc_input_event = KEY_MAX; @@ -837,7 +841,7 @@ static void cinergyt2_query_rc (struct work_struct *work) if (cinergyt2->rc_input_event != KEY_MAX) { if (rc_events[n].value == cinergyt2->rc_last_code && - cinergyt2->rc_last_code != ~0) { + cinergyt2->rc_last_code != cpu_to_le32(~0)) { /* emit a key-up so the double event is recognized */ dprintk(1, "rc_input_event=%d UP\n", cinergyt2->rc_input_event); input_report_key(cinergyt2->rc_input_dev, @@ -871,7 +875,7 @@ static int cinergyt2_register_rc(struct cinergyt2 *cinergyt2) usb_make_path(cinergyt2->udev, cinergyt2->phys, sizeof(cinergyt2->phys)); strlcat(cinergyt2->phys, "/input0", sizeof(cinergyt2->phys)); cinergyt2->rc_input_event = KEY_MAX; - cinergyt2->rc_last_code = ~0; + cinergyt2->rc_last_code = cpu_to_le32(~0); #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20) INIT_WORK(&cinergyt2->rc_query_work, cinergyt2_query_rc, cinergyt2); #else @@ -886,8 +890,8 @@ static int cinergyt2_register_rc(struct cinergyt2 *cinergyt2) input_dev->keycodesize = 0; input_dev->keycodemax = 0; input_dev->id.bustype = BUS_USB; - input_dev->id.vendor = cinergyt2->udev->descriptor.idVendor; - input_dev->id.product = cinergyt2->udev->descriptor.idProduct; + input_dev->id.vendor = le16_to_cpu(cinergyt2->udev->descriptor.idVendor); + input_dev->id.product = le16_to_cpu(cinergyt2->udev->descriptor.idProduct); input_dev->id.version = 1; #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22) input_dev->dev.parent = &cinergyt2->udev->dev; @@ -951,18 +955,16 @@ static void cinergyt2_query (struct work_struct *work) char cmd [] = { CINERGYT2_EP1_GET_TUNER_STATUS }; struct dvbt_get_status_msg *s = &cinergyt2->status; uint8_t lock_bits; - uint32_t unc; if (cinergyt2->disconnect_pending || mutex_lock_interruptible(&cinergyt2->sem)) return; - unc = s->uncorrected_block_count; lock_bits = s->lock_bits; cinergyt2_command(cinergyt2, cmd, sizeof(cmd), (char *) s, sizeof(*s)); - unc += le32_to_cpu(s->uncorrected_block_count); - s->uncorrected_block_count = unc; + cinergyt2->uncorrected_block_count += + le32_to_cpu(s->uncorrected_block_count); if (lock_bits != s->lock_bits) { wake_up_interruptible(&cinergyt2->poll_wq); -- cgit v1.2.3