adjtimex broken in 3.12.37 - 3.12.39

2015-04-03 Thread Christian Riesch
Hello Jiri,

Commit f09c62a1c27dcc43a06e5ebb27ae67306146277b ("time: adjtimex:
Validate the ADJ_FREQUENCY values", appeared first in 3.12.37,
upstream is 5e5aeb4367b450a28f447f6d5ab57d8f2ab16a5f) breaks the
adjtimex call on 32 bit systems. This was fixed upstream by commit
29183a70b0b828500816bd794b3fe192fce89f73 ("ntp: Fixup adjtimex freq
validation on 32-bit systems").

If you haven't already done this, please consider applying the fix to
the 3.12 series. Thank you!

Christian
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


adjtimex broken in 3.12.37 - 3.12.39

2015-04-03 Thread Christian Riesch
Hello Jiri,

Commit f09c62a1c27dcc43a06e5ebb27ae67306146277b (time: adjtimex:
Validate the ADJ_FREQUENCY values, appeared first in 3.12.37,
upstream is 5e5aeb4367b450a28f447f6d5ab57d8f2ab16a5f) breaks the
adjtimex call on 32 bit systems. This was fixed upstream by commit
29183a70b0b828500816bd794b3fe192fce89f73 (ntp: Fixup adjtimex freq
validation on 32-bit systems).

If you haven't already done this, please consider applying the fix to
the 3.12 series. Thank you!

Christian
--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH] pps: Add support for read operations and return a useful value in poll

2015-04-01 Thread Christian Riesch
[sent again with Rodolfo in the list of recipients, something went
wrong, sorry!]

Hi Rodolfo,

Thanks for your reply!

On Wed, Apr 1, 2015 at 10:11 AM, Rodolfo Giometti  wrote:
> On Tue, Mar 31, 2015 at 11:31:22PM +0200, Christian Riesch wrote:
>> The PPS_FETCH ioctl in drivers/pps/pps.c blocks until a new PPS event
>> occurs, then returns the time stamp data. While this is fine for
>> lots of applications, sometimes it would be nice if the poll system
>> call and a subsequent read could be used to obtain the pps data.
>
> Nak. The read syscall can't be forced to return fix amount of
> data.

I just copied/modified the behavior of ptp_read() in drivers/ptp/ptp_chardev.c:

if (cnt % sizeof(struct ptp_extts_event) != 0)
return -EINVAL;

There the amount of data is forced to be a multiple of sizeof(struct
ptp_extts_event). But if you prefer an ioctl, I can change that of
course.

> Use a dedicated ioctl instead.

Is it ok to pair POLLIN | POLLRDNORM in the poll function with an
ioctl? Or should returning POLLIN | POLLRDNORM mean that a read() will
not block? Should I use POLLPRI instead or something else?

Regards, Christian
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH] pps: Add support for read operations and return a useful value in poll

2015-04-01 Thread Christian Riesch
Hi Rodolfo,

Thanks for your reply!

On Wed, Apr 1, 2015 at 10:11 AM, Rodolfo Giometti  wrote:
> On Tue, Mar 31, 2015 at 11:31:22PM +0200, Christian Riesch wrote:
>> The PPS_FETCH ioctl in drivers/pps/pps.c blocks until a new PPS event
>> occurs, then returns the time stamp data. While this is fine for
>> lots of applications, sometimes it would be nice if the poll system
>> call and a subsequent read could be used to obtain the pps data.
>
> Nak. The read syscall can't be forced to return fix amount of
> data.

I just copied/modified the behavior of ptp_read() in drivers/ptp/ptp_chardev.c:

if (cnt % sizeof(struct ptp_extts_event) != 0)
return -EINVAL;

There the amount of data is forced to be a multiple of sizeof(struct
ptp_extts_event). But if you prefer an ioctl, I can change that of
course.

>
> Use a dedicated ioctl instead.

Is it ok to pair POLLIN | POLLRDNORM in the poll function with an
ioctl? Or should returning POLLIN | POLLRDNORM mean that a read() will
not block? Should I use POLLPRI instead or something else?

Regards, Christian
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH] pps: Add support for read operations and return a useful value in poll

2015-04-01 Thread Christian Riesch
[sent again with Rodolfo in the list of recipients, something went
wrong, sorry!]

Hi Rodolfo,

Thanks for your reply!

On Wed, Apr 1, 2015 at 10:11 AM, Rodolfo Giometti giome...@enneenne.com wrote:
 On Tue, Mar 31, 2015 at 11:31:22PM +0200, Christian Riesch wrote:
 The PPS_FETCH ioctl in drivers/pps/pps.c blocks until a new PPS event
 occurs, then returns the time stamp data. While this is fine for
 lots of applications, sometimes it would be nice if the poll system
 call and a subsequent read could be used to obtain the pps data.

 Nak. The read syscall can't be forced to return fix amount of
 data.

I just copied/modified the behavior of ptp_read() in drivers/ptp/ptp_chardev.c:

if (cnt % sizeof(struct ptp_extts_event) != 0)
return -EINVAL;

There the amount of data is forced to be a multiple of sizeof(struct
ptp_extts_event). But if you prefer an ioctl, I can change that of
course.

 Use a dedicated ioctl instead.

Is it ok to pair POLLIN | POLLRDNORM in the poll function with an
ioctl? Or should returning POLLIN | POLLRDNORM mean that a read() will
not block? Should I use POLLPRI instead or something else?

Regards, Christian
--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH] pps: Add support for read operations and return a useful value in poll

2015-04-01 Thread Christian Riesch
Hi Rodolfo,

Thanks for your reply!

On Wed, Apr 1, 2015 at 10:11 AM, Rodolfo Giometti giome...@enneenne.com wrote:
 On Tue, Mar 31, 2015 at 11:31:22PM +0200, Christian Riesch wrote:
 The PPS_FETCH ioctl in drivers/pps/pps.c blocks until a new PPS event
 occurs, then returns the time stamp data. While this is fine for
 lots of applications, sometimes it would be nice if the poll system
 call and a subsequent read could be used to obtain the pps data.

 Nak. The read syscall can't be forced to return fix amount of
 data.

I just copied/modified the behavior of ptp_read() in drivers/ptp/ptp_chardev.c:

if (cnt % sizeof(struct ptp_extts_event) != 0)
return -EINVAL;

There the amount of data is forced to be a multiple of sizeof(struct
ptp_extts_event). But if you prefer an ioctl, I can change that of
course.


 Use a dedicated ioctl instead.

Is it ok to pair POLLIN | POLLRDNORM in the poll function with an
ioctl? Or should returning POLLIN | POLLRDNORM mean that a read() will
not block? Should I use POLLPRI instead or something else?

Regards, Christian
--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH] pps: Add support for read operations and return a useful value in poll

2015-03-31 Thread Christian Riesch
The PPS_FETCH ioctl in drivers/pps/pps.c blocks until a new PPS event
occurs, then returns the time stamp data. While this is fine for
lots of applications, sometimes it would be nice if the poll system
call and a subsequent read could be used to obtain the pps data.

This patch adds support for read operations. Furthermore pps_cdev_poll
is modified to return POLLIN | POLLRDNORM only when new PPS data is
available.

Signed-off-by: Christian Riesch 
---
 drivers/pps/pps.c  |   32 +++-
 include/linux/pps_kernel.h |1 +
 2 files changed, 32 insertions(+), 1 deletion(-)

diff --git a/drivers/pps/pps.c b/drivers/pps/pps.c
index 2f07cd6..f90dd2e 100644
--- a/drivers/pps/pps.c
+++ b/drivers/pps/pps.c
@@ -55,7 +55,7 @@ static unsigned int pps_cdev_poll(struct file *file, 
poll_table *wait)
 
poll_wait(file, >queue, wait);
 
-   return POLLIN | POLLRDNORM;
+   return (pps->last_ev != pps->read_ev) ? POLLIN | POLLRDNORM : 0;
 }
 
 static int pps_cdev_fasync(int fd, struct file *file, int on)
@@ -191,6 +191,7 @@ static long pps_cdev_ioctl(struct file *file,
fdata.info.assert_tu = pps->assert_tu;
fdata.info.clear_tu = pps->clear_tu;
fdata.info.current_mode = pps->current_mode;
+   pps->read_ev = pps->last_ev;
 
spin_unlock_irq(>lock);
 
@@ -251,6 +252,34 @@ static int pps_cdev_open(struct inode *inode, struct file 
*file)
return 0;
 }
 
+ssize_t pps_cdev_read(struct file *file, char __user *buf, size_t count,
+ loff_t *ppos)
+{
+   struct pps_device *pps = file->private_data;
+   struct pps_fdata fdata;
+
+   if (count != sizeof(struct pps_fdata))
+   return -EINVAL;
+
+   if (wait_event_interruptible(pps->queue, pps->read_ev != pps->last_ev))
+   return -ERESTARTSYS;
+
+   /* Return the fetched timestamp */
+   spin_lock_irq(>lock);
+   fdata.info.assert_sequence = pps->assert_sequence;
+   fdata.info.clear_sequence = pps->clear_sequence;
+   fdata.info.assert_tu = pps->assert_tu;
+   fdata.info.clear_tu = pps->clear_tu;
+   fdata.info.current_mode = pps->current_mode;
+   pps->read_ev = pps->last_ev;
+   spin_unlock_irq(>lock);
+
+   if (copy_to_user(buf, , sizeof(struct pps_fdata)))
+   return -EFAULT;
+
+   return sizeof(struct pps_fdata);
+}
+
 static int pps_cdev_release(struct inode *inode, struct file *file)
 {
struct pps_device *pps = container_of(inode->i_cdev,
@@ -266,6 +295,7 @@ static int pps_cdev_release(struct inode *inode, struct 
file *file)
 static const struct file_operations pps_cdev_fops = {
.owner  = THIS_MODULE,
.llseek = no_llseek,
+   .read   = pps_cdev_read,
.poll   = pps_cdev_poll,
.fasync = pps_cdev_fasync,
.unlocked_ioctl = pps_cdev_ioctl,
diff --git a/include/linux/pps_kernel.h b/include/linux/pps_kernel.h
index 1d2cd21..42f405b 100644
--- a/include/linux/pps_kernel.h
+++ b/include/linux/pps_kernel.h
@@ -66,6 +66,7 @@ struct pps_device {
int current_mode;   /* PPS mode at event time */
 
unsigned int last_ev;   /* last PPS event id */
+   unsigned int read_ev;   /* last PPS event read by user 
*/
wait_queue_head_t queue;/* PPS event queue */
 
unsigned int id;/* PPS source unique ID */
-- 
1.7.9.5

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH] pps: Add support for read operations and return a useful value in poll

2015-03-31 Thread Christian Riesch
The PPS_FETCH ioctl in drivers/pps/pps.c blocks until a new PPS event
occurs, then returns the time stamp data. While this is fine for
lots of applications, sometimes it would be nice if the poll system
call and a subsequent read could be used to obtain the pps data.

This patch adds support for read operations. Furthermore pps_cdev_poll
is modified to return POLLIN | POLLRDNORM only when new PPS data is
available.

Signed-off-by: Christian Riesch christian.rie...@omicron.at
---
 drivers/pps/pps.c  |   32 +++-
 include/linux/pps_kernel.h |1 +
 2 files changed, 32 insertions(+), 1 deletion(-)

diff --git a/drivers/pps/pps.c b/drivers/pps/pps.c
index 2f07cd6..f90dd2e 100644
--- a/drivers/pps/pps.c
+++ b/drivers/pps/pps.c
@@ -55,7 +55,7 @@ static unsigned int pps_cdev_poll(struct file *file, 
poll_table *wait)
 
poll_wait(file, pps-queue, wait);
 
-   return POLLIN | POLLRDNORM;
+   return (pps-last_ev != pps-read_ev) ? POLLIN | POLLRDNORM : 0;
 }
 
 static int pps_cdev_fasync(int fd, struct file *file, int on)
@@ -191,6 +191,7 @@ static long pps_cdev_ioctl(struct file *file,
fdata.info.assert_tu = pps-assert_tu;
fdata.info.clear_tu = pps-clear_tu;
fdata.info.current_mode = pps-current_mode;
+   pps-read_ev = pps-last_ev;
 
spin_unlock_irq(pps-lock);
 
@@ -251,6 +252,34 @@ static int pps_cdev_open(struct inode *inode, struct file 
*file)
return 0;
 }
 
+ssize_t pps_cdev_read(struct file *file, char __user *buf, size_t count,
+ loff_t *ppos)
+{
+   struct pps_device *pps = file-private_data;
+   struct pps_fdata fdata;
+
+   if (count != sizeof(struct pps_fdata))
+   return -EINVAL;
+
+   if (wait_event_interruptible(pps-queue, pps-read_ev != pps-last_ev))
+   return -ERESTARTSYS;
+
+   /* Return the fetched timestamp */
+   spin_lock_irq(pps-lock);
+   fdata.info.assert_sequence = pps-assert_sequence;
+   fdata.info.clear_sequence = pps-clear_sequence;
+   fdata.info.assert_tu = pps-assert_tu;
+   fdata.info.clear_tu = pps-clear_tu;
+   fdata.info.current_mode = pps-current_mode;
+   pps-read_ev = pps-last_ev;
+   spin_unlock_irq(pps-lock);
+
+   if (copy_to_user(buf, fdata, sizeof(struct pps_fdata)))
+   return -EFAULT;
+
+   return sizeof(struct pps_fdata);
+}
+
 static int pps_cdev_release(struct inode *inode, struct file *file)
 {
struct pps_device *pps = container_of(inode-i_cdev,
@@ -266,6 +295,7 @@ static int pps_cdev_release(struct inode *inode, struct 
file *file)
 static const struct file_operations pps_cdev_fops = {
.owner  = THIS_MODULE,
.llseek = no_llseek,
+   .read   = pps_cdev_read,
.poll   = pps_cdev_poll,
.fasync = pps_cdev_fasync,
.unlocked_ioctl = pps_cdev_ioctl,
diff --git a/include/linux/pps_kernel.h b/include/linux/pps_kernel.h
index 1d2cd21..42f405b 100644
--- a/include/linux/pps_kernel.h
+++ b/include/linux/pps_kernel.h
@@ -66,6 +66,7 @@ struct pps_device {
int current_mode;   /* PPS mode at event time */
 
unsigned int last_ev;   /* last PPS event id */
+   unsigned int read_ev;   /* last PPS event read by user 
*/
wait_queue_head_t queue;/* PPS event queue */
 
unsigned int id;/* PPS source unique ID */
-- 
1.7.9.5

--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH] n_tty: Fix unordered accesses to lockless read buffer

2015-01-01 Thread Christian Riesch
On Thu, Jan 1, 2015 at 12:00 PM, Christian Riesch >> @@ -164,15
+160,17 @@ static inline int tty_put_user(struct tty_struct *tty,
unsigned char x,
>>  static int receive_room(struct tty_struct *tty)
>>  {
>> struct n_tty_data *ldata = tty->disc_data;
>> +   size_t head = ACCESS_ONCE(ldata->commit_head);
>> +   size_t tail = ACCESS_ONCE(ldata->read_tail);
>> int left;
>>
>> if (I_PARMRK(tty)) {
>> -   /* Multiply read_cnt by 3, since each byte might take up to
>> +   /* Multiply count by 3, since each byte might take up to
>>  * three times as many spaces when PARMRK is set (depending 
>> on
>>  * its flags, e.g. parity error). */
>> -   left = N_TTY_BUF_SIZE - read_cnt(ldata) * 3 - 1;
>> +   left = N_TTY_BUF_SIZE - (head - tail) * 3 - 1;
>> } else
>> -   left = N_TTY_BUF_SIZE - read_cnt(ldata) - 1;
>> +   left = N_TTY_BUF_SIZE - (head - tail) - 1;
>
> Actually, less room may be available, if read_head != commit_head.
> Could this cause problems? I guess yes, at least in
> n_tty_receive_buf_common, where this could lead to a buffer overflow,
> right?

Sorry, should not be a problem, at least not for
n_tty_receive_buf_common, since this is producer path, right? But how
about the other calls of receive_room()?

Christian
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH] n_tty: Fix unordered accesses to lockless read buffer

2015-01-01 Thread Christian Riesch
Peter,

Thank you for this patch! Unfortunately I had not much time for this
since my last patch submission, so I am happy that someone continued
this work.

I have a few comments/questions, please see below.

On Tue, Dec 30, 2014 at 1:05 PM, Peter Hurley  wrote:
> Add commit_head buffer index, which the producer-side publishes
> after input processing. This ensures the consumer-side observes
> correctly-ordered writes in raw mode

I understand that the commit_head reduces the number of memory
barriers and makes some things easier. But what is so special about
raw mode that requires the introduction of commit_head?

> (ie., the buffer data is
> written before the buffer index is advanced).
>
> Further, remove read_cnt() and expand inline, using ACCESS_ONCE()

"ACCESS_ONCE() and memory barriers"?

> on the relevant buffer index; read_tail from the producer-side
> and canon_head/commit_head from the consumer-side, or both in shared
> paths such as receive_room().
>
> Based on work by Christian Riesch 
>
> NB: Exclusive access is still guaranteed with termios_rwsem write
> lock, eg. by n_tty_set_termios() and in n_tty_ioctl(); in this
> circumstance, commit_head is equivalent to read_head.
>
> Cc: Christian Riesch 
> Cc:  # v3.14.x (will need backport to v3.12.x)
> Signed-off-by: Peter Hurley 
> ---
>  drivers/tty/n_tty.c | 80 
> ++---
>  1 file changed, 40 insertions(+), 40 deletions(-)
>
> diff --git a/drivers/tty/n_tty.c b/drivers/tty/n_tty.c
> index d2b4967..a618b10 100644
> --- a/drivers/tty/n_tty.c
> +++ b/drivers/tty/n_tty.c
> @@ -90,6 +90,7 @@
>  struct n_tty_data {
> /* producer-published */
> size_t read_head;
> +   size_t commit_head; /* == read_head when not receiving */
> size_t canon_head;
> size_t echo_head;
> size_t echo_commit;
> @@ -127,11 +128,6 @@ struct n_tty_data {
> struct mutex output_lock;
>  };
>
> -static inline size_t read_cnt(struct n_tty_data *ldata)
> -{
> -   return ldata->read_head - ldata->read_tail;
> -}
> -
>  static inline unsigned char read_buf(struct n_tty_data *ldata, size_t i)
>  {
> return ldata->read_buf[i & (N_TTY_BUF_SIZE - 1)];
> @@ -164,15 +160,17 @@ static inline int tty_put_user(struct tty_struct *tty, 
> unsigned char x,
>  static int receive_room(struct tty_struct *tty)
>  {
> struct n_tty_data *ldata = tty->disc_data;
> +   size_t head = ACCESS_ONCE(ldata->commit_head);
> +   size_t tail = ACCESS_ONCE(ldata->read_tail);
> int left;
>
> if (I_PARMRK(tty)) {
> -   /* Multiply read_cnt by 3, since each byte might take up to
> +   /* Multiply count by 3, since each byte might take up to
>  * three times as many spaces when PARMRK is set (depending on
>  * its flags, e.g. parity error). */
> -   left = N_TTY_BUF_SIZE - read_cnt(ldata) * 3 - 1;
> +   left = N_TTY_BUF_SIZE - (head - tail) * 3 - 1;
> } else
> -   left = N_TTY_BUF_SIZE - read_cnt(ldata) - 1;
> +   left = N_TTY_BUF_SIZE - (head - tail) - 1;

Actually, less room may be available, if read_head != commit_head.
Could this cause problems? I guess yes, at least in
n_tty_receive_buf_common, where this could lead to a buffer overflow,
right?

Best regards,
Christian
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH] n_tty: Fix unordered accesses to lockless read buffer

2015-01-01 Thread Christian Riesch
Peter,

Thank you for this patch! Unfortunately I had not much time for this
since my last patch submission, so I am happy that someone continued
this work.

I have a few comments/questions, please see below.

On Tue, Dec 30, 2014 at 1:05 PM, Peter Hurley pe...@hurleysoftware.com wrote:
 Add commit_head buffer index, which the producer-side publishes
 after input processing. This ensures the consumer-side observes
 correctly-ordered writes in raw mode

I understand that the commit_head reduces the number of memory
barriers and makes some things easier. But what is so special about
raw mode that requires the introduction of commit_head?

 (ie., the buffer data is
 written before the buffer index is advanced).

 Further, remove read_cnt() and expand inline, using ACCESS_ONCE()

ACCESS_ONCE() and memory barriers?

 on the relevant buffer index; read_tail from the producer-side
 and canon_head/commit_head from the consumer-side, or both in shared
 paths such as receive_room().

 Based on work by Christian Riesch christian.rie...@omicron.at

 NB: Exclusive access is still guaranteed with termios_rwsem write
 lock, eg. by n_tty_set_termios() and in n_tty_ioctl(); in this
 circumstance, commit_head is equivalent to read_head.

 Cc: Christian Riesch christian.rie...@omicron.at
 Cc: sta...@vger.kernel.org # v3.14.x (will need backport to v3.12.x)
 Signed-off-by: Peter Hurley pe...@hurleysoftware.com
 ---
  drivers/tty/n_tty.c | 80 
 ++---
  1 file changed, 40 insertions(+), 40 deletions(-)

 diff --git a/drivers/tty/n_tty.c b/drivers/tty/n_tty.c
 index d2b4967..a618b10 100644
 --- a/drivers/tty/n_tty.c
 +++ b/drivers/tty/n_tty.c
 @@ -90,6 +90,7 @@
  struct n_tty_data {
 /* producer-published */
 size_t read_head;
 +   size_t commit_head; /* == read_head when not receiving */
 size_t canon_head;
 size_t echo_head;
 size_t echo_commit;
 @@ -127,11 +128,6 @@ struct n_tty_data {
 struct mutex output_lock;
  };

 -static inline size_t read_cnt(struct n_tty_data *ldata)
 -{
 -   return ldata-read_head - ldata-read_tail;
 -}
 -
  static inline unsigned char read_buf(struct n_tty_data *ldata, size_t i)
  {
 return ldata-read_buf[i  (N_TTY_BUF_SIZE - 1)];
 @@ -164,15 +160,17 @@ static inline int tty_put_user(struct tty_struct *tty, 
 unsigned char x,
  static int receive_room(struct tty_struct *tty)
  {
 struct n_tty_data *ldata = tty-disc_data;
 +   size_t head = ACCESS_ONCE(ldata-commit_head);
 +   size_t tail = ACCESS_ONCE(ldata-read_tail);
 int left;

 if (I_PARMRK(tty)) {
 -   /* Multiply read_cnt by 3, since each byte might take up to
 +   /* Multiply count by 3, since each byte might take up to
  * three times as many spaces when PARMRK is set (depending on
  * its flags, e.g. parity error). */
 -   left = N_TTY_BUF_SIZE - read_cnt(ldata) * 3 - 1;
 +   left = N_TTY_BUF_SIZE - (head - tail) * 3 - 1;
 } else
 -   left = N_TTY_BUF_SIZE - read_cnt(ldata) - 1;
 +   left = N_TTY_BUF_SIZE - (head - tail) - 1;

Actually, less room may be available, if read_head != commit_head.
Could this cause problems? I guess yes, at least in
n_tty_receive_buf_common, where this could lead to a buffer overflow,
right?

Best regards,
Christian
--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH] n_tty: Fix unordered accesses to lockless read buffer

2015-01-01 Thread Christian Riesch
On Thu, Jan 1, 2015 at 12:00 PM, Christian Riesch  @@ -164,15
+160,17 @@ static inline int tty_put_user(struct tty_struct *tty,
unsigned char x,
  static int receive_room(struct tty_struct *tty)
  {
 struct n_tty_data *ldata = tty-disc_data;
 +   size_t head = ACCESS_ONCE(ldata-commit_head);
 +   size_t tail = ACCESS_ONCE(ldata-read_tail);
 int left;

 if (I_PARMRK(tty)) {
 -   /* Multiply read_cnt by 3, since each byte might take up to
 +   /* Multiply count by 3, since each byte might take up to
  * three times as many spaces when PARMRK is set (depending 
 on
  * its flags, e.g. parity error). */
 -   left = N_TTY_BUF_SIZE - read_cnt(ldata) * 3 - 1;
 +   left = N_TTY_BUF_SIZE - (head - tail) * 3 - 1;
 } else
 -   left = N_TTY_BUF_SIZE - read_cnt(ldata) - 1;
 +   left = N_TTY_BUF_SIZE - (head - tail) - 1;

 Actually, less room may be available, if read_head != commit_head.
 Could this cause problems? I guess yes, at least in
 n_tty_receive_buf_common, where this could lead to a buffer overflow,
 right?

Sorry, should not be a problem, at least not for
n_tty_receive_buf_common, since this is producer path, right? But how
about the other calls of receive_room()?

Christian
--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [RFC PATCH] n_tty: Add memory barriers where required for lock-less circular buffer

2014-11-17 Thread Christian Riesch
On Mon, Nov 17, 2014 at 1:27 PM, Christian Riesch
 wrote:
> Signed-off-by: Christian Riesch 
> Cc: Peter Hurley 
[...]

> [2] https://lkml.org/lkml/2014/11/11/77

Uupps, [2] should point to https://lkml.org/lkml/2014/11/13/1 instead.
v3 instead of v2. Sorry.

>
>  drivers/tty/n_tty.c |   93 
> +++
>  1 file changed, 64 insertions(+), 29 deletions(-)
>
> diff --git a/drivers/tty/n_tty.c b/drivers/tty/n_tty.c
> index 47ca0f3..656d868 100644
> --- a/drivers/tty/n_tty.c
> +++ b/drivers/tty/n_tty.c

[...]

> @@ -165,14 +180,18 @@ static int receive_room(struct tty_struct *tty)
>  {
> struct n_tty_data *ldata = tty->disc_data;
> int left;
> +   size_t head, tail;
> +
> +   head = ldata->read_head;
> +   tail = ACCESS_ONCE(ldata->read_tail);

I just noticed that this is probably wrong, since receive_room is
called from both the consumer and producer paths.

>
> if (I_PARMRK(tty)) {
> -   /* Multiply read_cnt by 3, since each byte might take up to
> -* three times as many spaces when PARMRK is set (depending on
> -* its flags, e.g. parity error). */
> -   left = N_TTY_BUF_SIZE - read_cnt(ldata) * 3 - 1;

BTW does this make sense? When the data is in the buffer, it is
already expanded by the PARMRK feature. Only new data could be
expanded by a factor of 3 when PARMRK is set.
Shouldn't that be (N_TTY_BUF_SIZE - read_cnt(ldata) - 1)/3 ?

Regards, Christian
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[RFC PATCH] n_tty: Add memory barriers where required for lock-less circular buffer

2014-11-17 Thread Christian Riesch
Signed-off-by: Christian Riesch 
Cc: Peter Hurley 
---

Hi all,

This patch adds memory barriers to the lock-less circular buffer in the n_tty
driver to fix the race condition described in [1] and [2] for SMP machines.

The patch is based on the instructions in Documentation/circular-buffers.txt.

Currently, this is only compile-tested. Peter, could you please have a look
at this and the documentation mentioned above, and tell me what you
think about this?

Prerequisites:
- The patch in [2]

Thanks!
Christian

[1] https://lkml.org/lkml/2014/11/6/216
[2] https://lkml.org/lkml/2014/11/11/77

 drivers/tty/n_tty.c |   93 +++
 1 file changed, 64 insertions(+), 29 deletions(-)

diff --git a/drivers/tty/n_tty.c b/drivers/tty/n_tty.c
index 47ca0f3..656d868 100644
--- a/drivers/tty/n_tty.c
+++ b/drivers/tty/n_tty.c
@@ -127,9 +127,24 @@ struct n_tty_data {
struct mutex output_lock;
 };
 
-static inline size_t read_cnt(struct n_tty_data *ldata)
+static inline size_t data_available(size_t head, size_t tail)
 {
-   return ldata->read_head - ldata->read_tail;
+   return head - tail;
+}
+
+static inline size_t room_available(size_t head, size_t tail)
+{
+   return N_TTY_BUF_SIZE - data_available(head, tail);
+}
+
+static inline size_t contiguous_data_available(size_t head, size_t tail)
+{
+   return min(head - tail, N_TTY_BUF_SIZE - (tail & (N_TTY_BUF_SIZE - 1)));
+}
+
+static inline size_t contiguous_room_available(size_t head, size_t tail)
+{
+   return N_TTY_BUF_SIZE - max(head - tail, head & (N_TTY_BUF_SIZE - 1));
 }
 
 static inline unsigned char read_buf(struct n_tty_data *ldata, size_t i)
@@ -165,14 +180,18 @@ static int receive_room(struct tty_struct *tty)
 {
struct n_tty_data *ldata = tty->disc_data;
int left;
+   size_t head, tail;
+
+   head = ldata->read_head;
+   tail = ACCESS_ONCE(ldata->read_tail);
 
if (I_PARMRK(tty)) {
-   /* Multiply read_cnt by 3, since each byte might take up to
-* three times as many spaces when PARMRK is set (depending on
-* its flags, e.g. parity error). */
-   left = N_TTY_BUF_SIZE - read_cnt(ldata) * 3 - 1;
+   /* Multiply available data by 3, since each byte might take up
+* to three times as many spaces when PARMRK is set (depending
+* on its flags, e.g. parity error). */
+   left = N_TTY_BUF_SIZE - data_available(head, tail) * 3 - 1;
} else
-   left = N_TTY_BUF_SIZE - read_cnt(ldata) - 1;
+   left = N_TTY_BUF_SIZE - data_available(head, tail) - 1;
 
/*
 * If we are doing input canonicalization, and there are no
@@ -181,7 +200,7 @@ static int receive_room(struct tty_struct *tty)
 * characters will be beeped.
 */
if (left <= 0)
-   left = ldata->icanon && ldata->canon_head == ldata->read_tail;
+   left = ldata->icanon && ldata->canon_head == tail;
 
return left;
 }
@@ -222,11 +241,15 @@ static ssize_t chars_in_buffer(struct tty_struct *tty)
 {
struct n_tty_data *ldata = tty->disc_data;
ssize_t n = 0;
+   size_t head, tail;
+
+   head = ACCESS_ONCE(ldata->read_head);
+   tail = ldata->read_tail;
 
if (!ldata->icanon)
-   n = read_cnt(ldata);
+   n = data_available(head, tail);
else
-   n = ldata->canon_head - ldata->read_tail;
+   n = ldata->canon_head - tail;
return n;
 }
 
@@ -322,7 +345,7 @@ static void n_tty_check_unthrottle(struct tty_struct *tty)
 static inline void put_tty_queue(unsigned char c, struct n_tty_data *ldata)
 {
*read_buf_addr(ldata, ldata->read_head) = c;
-   ldata->read_head++;
+   smp_store_release(>read_head, ldata->read_head + 1);
 }
 
 /**
@@ -1534,21 +1557,23 @@ n_tty_receive_buf_real_raw(struct tty_struct *tty, 
const unsigned char *cp,
   char *fp, int count)
 {
struct n_tty_data *ldata = tty->disc_data;
-   size_t n, head;
+   size_t n, head, tail;
+
+   head = ldata->read_head;
+   tail = ACCESS_ONCE(ldata->read_tail);
 
-   head = ldata->read_head & (N_TTY_BUF_SIZE - 1);
-   n = N_TTY_BUF_SIZE - max(read_cnt(ldata), head);
+   n = contiguous_room_available(head, tail);
n = min_t(size_t, count, n);
memcpy(read_buf_addr(ldata, head), cp, n);
-   ldata->read_head += n;
+   smp_store_release(>read_head, ldata->read_head + n);
cp += n;
count -= n;
 
-   head = ldata->read_head & (N_TTY_BUF_SIZE - 1);
-   n = N_TTY_BUF_SIZE - max(read_cnt(ldata), head);
+   head = ldata->read_head;
+   n = contiguous_room_available(head, tail);
n = min_t(size_t, count, n);
memcpy(

[RFC PATCH] n_tty: Add memory barriers where required for lock-less circular buffer

2014-11-17 Thread Christian Riesch
Signed-off-by: Christian Riesch christian.rie...@omicron.at
Cc: Peter Hurley pe...@hurleysoftware.com
---

Hi all,

This patch adds memory barriers to the lock-less circular buffer in the n_tty
driver to fix the race condition described in [1] and [2] for SMP machines.

The patch is based on the instructions in Documentation/circular-buffers.txt.

Currently, this is only compile-tested. Peter, could you please have a look
at this and the documentation mentioned above, and tell me what you
think about this?

Prerequisites:
- The patch in [2]

Thanks!
Christian

[1] https://lkml.org/lkml/2014/11/6/216
[2] https://lkml.org/lkml/2014/11/11/77

 drivers/tty/n_tty.c |   93 +++
 1 file changed, 64 insertions(+), 29 deletions(-)

diff --git a/drivers/tty/n_tty.c b/drivers/tty/n_tty.c
index 47ca0f3..656d868 100644
--- a/drivers/tty/n_tty.c
+++ b/drivers/tty/n_tty.c
@@ -127,9 +127,24 @@ struct n_tty_data {
struct mutex output_lock;
 };
 
-static inline size_t read_cnt(struct n_tty_data *ldata)
+static inline size_t data_available(size_t head, size_t tail)
 {
-   return ldata-read_head - ldata-read_tail;
+   return head - tail;
+}
+
+static inline size_t room_available(size_t head, size_t tail)
+{
+   return N_TTY_BUF_SIZE - data_available(head, tail);
+}
+
+static inline size_t contiguous_data_available(size_t head, size_t tail)
+{
+   return min(head - tail, N_TTY_BUF_SIZE - (tail  (N_TTY_BUF_SIZE - 1)));
+}
+
+static inline size_t contiguous_room_available(size_t head, size_t tail)
+{
+   return N_TTY_BUF_SIZE - max(head - tail, head  (N_TTY_BUF_SIZE - 1));
 }
 
 static inline unsigned char read_buf(struct n_tty_data *ldata, size_t i)
@@ -165,14 +180,18 @@ static int receive_room(struct tty_struct *tty)
 {
struct n_tty_data *ldata = tty-disc_data;
int left;
+   size_t head, tail;
+
+   head = ldata-read_head;
+   tail = ACCESS_ONCE(ldata-read_tail);
 
if (I_PARMRK(tty)) {
-   /* Multiply read_cnt by 3, since each byte might take up to
-* three times as many spaces when PARMRK is set (depending on
-* its flags, e.g. parity error). */
-   left = N_TTY_BUF_SIZE - read_cnt(ldata) * 3 - 1;
+   /* Multiply available data by 3, since each byte might take up
+* to three times as many spaces when PARMRK is set (depending
+* on its flags, e.g. parity error). */
+   left = N_TTY_BUF_SIZE - data_available(head, tail) * 3 - 1;
} else
-   left = N_TTY_BUF_SIZE - read_cnt(ldata) - 1;
+   left = N_TTY_BUF_SIZE - data_available(head, tail) - 1;
 
/*
 * If we are doing input canonicalization, and there are no
@@ -181,7 +200,7 @@ static int receive_room(struct tty_struct *tty)
 * characters will be beeped.
 */
if (left = 0)
-   left = ldata-icanon  ldata-canon_head == ldata-read_tail;
+   left = ldata-icanon  ldata-canon_head == tail;
 
return left;
 }
@@ -222,11 +241,15 @@ static ssize_t chars_in_buffer(struct tty_struct *tty)
 {
struct n_tty_data *ldata = tty-disc_data;
ssize_t n = 0;
+   size_t head, tail;
+
+   head = ACCESS_ONCE(ldata-read_head);
+   tail = ldata-read_tail;
 
if (!ldata-icanon)
-   n = read_cnt(ldata);
+   n = data_available(head, tail);
else
-   n = ldata-canon_head - ldata-read_tail;
+   n = ldata-canon_head - tail;
return n;
 }
 
@@ -322,7 +345,7 @@ static void n_tty_check_unthrottle(struct tty_struct *tty)
 static inline void put_tty_queue(unsigned char c, struct n_tty_data *ldata)
 {
*read_buf_addr(ldata, ldata-read_head) = c;
-   ldata-read_head++;
+   smp_store_release(ldata-read_head, ldata-read_head + 1);
 }
 
 /**
@@ -1534,21 +1557,23 @@ n_tty_receive_buf_real_raw(struct tty_struct *tty, 
const unsigned char *cp,
   char *fp, int count)
 {
struct n_tty_data *ldata = tty-disc_data;
-   size_t n, head;
+   size_t n, head, tail;
+
+   head = ldata-read_head;
+   tail = ACCESS_ONCE(ldata-read_tail);
 
-   head = ldata-read_head  (N_TTY_BUF_SIZE - 1);
-   n = N_TTY_BUF_SIZE - max(read_cnt(ldata), head);
+   n = contiguous_room_available(head, tail);
n = min_t(size_t, count, n);
memcpy(read_buf_addr(ldata, head), cp, n);
-   ldata-read_head += n;
+   smp_store_release(ldata-read_head, ldata-read_head + n);
cp += n;
count -= n;
 
-   head = ldata-read_head  (N_TTY_BUF_SIZE - 1);
-   n = N_TTY_BUF_SIZE - max(read_cnt(ldata), head);
+   head = ldata-read_head;
+   n = contiguous_room_available(head, tail);
n = min_t(size_t, count, n);
memcpy(read_buf_addr(ldata, head), cp, n);
-   ldata-read_head += n;
+   smp_store_release(ldata

Re: [RFC PATCH] n_tty: Add memory barriers where required for lock-less circular buffer

2014-11-17 Thread Christian Riesch
On Mon, Nov 17, 2014 at 1:27 PM, Christian Riesch
christian.rie...@omicron.at wrote:
 Signed-off-by: Christian Riesch christian.rie...@omicron.at
 Cc: Peter Hurley pe...@hurleysoftware.com
[...]

 [2] https://lkml.org/lkml/2014/11/11/77

Uupps, [2] should point to https://lkml.org/lkml/2014/11/13/1 instead.
v3 instead of v2. Sorry.


  drivers/tty/n_tty.c |   93 
 +++
  1 file changed, 64 insertions(+), 29 deletions(-)

 diff --git a/drivers/tty/n_tty.c b/drivers/tty/n_tty.c
 index 47ca0f3..656d868 100644
 --- a/drivers/tty/n_tty.c
 +++ b/drivers/tty/n_tty.c

[...]

 @@ -165,14 +180,18 @@ static int receive_room(struct tty_struct *tty)
  {
 struct n_tty_data *ldata = tty-disc_data;
 int left;
 +   size_t head, tail;
 +
 +   head = ldata-read_head;
 +   tail = ACCESS_ONCE(ldata-read_tail);

I just noticed that this is probably wrong, since receive_room is
called from both the consumer and producer paths.


 if (I_PARMRK(tty)) {
 -   /* Multiply read_cnt by 3, since each byte might take up to
 -* three times as many spaces when PARMRK is set (depending on
 -* its flags, e.g. parity error). */
 -   left = N_TTY_BUF_SIZE - read_cnt(ldata) * 3 - 1;

BTW does this make sense? When the data is in the buffer, it is
already expanded by the PARMRK feature. Only new data could be
expanded by a factor of 3 when PARMRK is set.
Shouldn't that be (N_TTY_BUF_SIZE - read_cnt(ldata) - 1)/3 ?

Regards, Christian
--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH v3] n_tty: Fix read_buf race condition, increment read_head after pushing data

2014-11-12 Thread Christian Riesch
Commit 19e2ad6a09f0c06dbca19c98e5f4584269d913dd ("n_tty: Remove overflow
tests from receive_buf() path") moved the increment of read_head into
the arguments list of read_buf_addr(). Function calls represent a
sequence point in C. Therefore read_head is incremented before the
character c is placed in the buffer. Since the circular read buffer is
a lock-less design since commit 6d76bd2618535c581f1673047b8341fd291abc67
("n_tty: Make N_TTY ldisc receive path lockless"), this creates a race
condition that leads to communication errors.

This patch modifies the code to increment read_head _after_ the data
is placed in the buffer and thus fixes the race for non-SMP machines.
To fix the problem for SMP machines, memory barriers must be added in
a separate patch.

Signed-off-by: Christian Riesch 
Cc: 
---

Changes for v3:
- Removed unnecessary comment.

Changes for v2:
- Rewrote commit message. Since I did not know better, I blamed the compiler
  in v1, but actually the code was wrong. See the discussion in [1].
- Removed memory barriers. For non-SMP machines they are not required,
  for SMP machines more brainwork and discussions are needed.

 drivers/tty/n_tty.c |3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/tty/n_tty.c b/drivers/tty/n_tty.c
index 2e900a9..47ca0f3 100644
--- a/drivers/tty/n_tty.c
+++ b/drivers/tty/n_tty.c
@@ -321,7 +321,8 @@ static void n_tty_check_unthrottle(struct tty_struct *tty)
 
 static inline void put_tty_queue(unsigned char c, struct n_tty_data *ldata)
 {
-   *read_buf_addr(ldata, ldata->read_head++) = c;
+   *read_buf_addr(ldata, ldata->read_head) = c;
+   ldata->read_head++;
 }
 
 /**
-- 
1.7.9.5

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH v2] n_tty: Fix read_buf race condition, increment read_head after pushing data

2014-11-12 Thread Christian Riesch
On Wed, Nov 12, 2014 at 12:53 PM, Måns Rullgård  wrote:
> Christian Riesch  writes:
>
>> On Tue, Nov 11, 2014 at 2:04 PM, Måns Rullgård  wrote:
>>> Christian Riesch  writes:
>> [...]>> diff --git a/drivers/tty/n_tty.c b/drivers/tty/n_tty.c
>>>> index 2e900a9..b09f326 100644
>>>> --- a/drivers/tty/n_tty.c
>>>> +++ b/drivers/tty/n_tty.c
>>>> @@ -321,7 +321,9 @@ static void n_tty_check_unthrottle(struct tty_struct 
>>>> *tty)
>>>>
>>>>  static inline void put_tty_queue(unsigned char c, struct n_tty_data 
>>>> *ldata)
>>>>  {
>>>> - *read_buf_addr(ldata, ldata->read_head++) = c;
>>>> + *read_buf_addr(ldata, ldata->read_head) = c;
>>>> + /* increment read_head _after_ placing the character in the buffer */
>>>> + ldata->read_head++;
>>>>  }
>>>
>>> Is that comment really necessary?
>>
>> No, I am pretty sure that removing the comment would not break the code ;-)
>>
>> I just thought it would be good to have some kind of reminder here.
>> Otherwise someone may think: Hey, it would be a good idea to do the
>> increment right in the first line. And submit a patch for it.
>
> The intent all along was to increment after the write.  Nobody needs
> reminding of that.  The problem was a misunderstanding of when the
> post-increment takes effect.  As much as we'd like for everybody to have
> a thorough knowledge of C, a random tty driver doesn't seem the place to
> educate them.

Ok. I will send a new patch without the comment.
Thanks, Christian
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH v2] n_tty: Fix read_buf race condition, increment read_head after pushing data

2014-11-12 Thread Christian Riesch
On Wed, Nov 12, 2014 at 12:53 PM, Måns Rullgård m...@mansr.com wrote:
 Christian Riesch christian.rie...@omicron.at writes:

 On Tue, Nov 11, 2014 at 2:04 PM, Måns Rullgård m...@mansr.com wrote:
 Christian Riesch christian.rie...@omicron.at writes:
 [...] diff --git a/drivers/tty/n_tty.c b/drivers/tty/n_tty.c
 index 2e900a9..b09f326 100644
 --- a/drivers/tty/n_tty.c
 +++ b/drivers/tty/n_tty.c
 @@ -321,7 +321,9 @@ static void n_tty_check_unthrottle(struct tty_struct 
 *tty)

  static inline void put_tty_queue(unsigned char c, struct n_tty_data 
 *ldata)
  {
 - *read_buf_addr(ldata, ldata-read_head++) = c;
 + *read_buf_addr(ldata, ldata-read_head) = c;
 + /* increment read_head _after_ placing the character in the buffer */
 + ldata-read_head++;
  }

 Is that comment really necessary?

 No, I am pretty sure that removing the comment would not break the code ;-)

 I just thought it would be good to have some kind of reminder here.
 Otherwise someone may think: Hey, it would be a good idea to do the
 increment right in the first line. And submit a patch for it.

 The intent all along was to increment after the write.  Nobody needs
 reminding of that.  The problem was a misunderstanding of when the
 post-increment takes effect.  As much as we'd like for everybody to have
 a thorough knowledge of C, a random tty driver doesn't seem the place to
 educate them.

Ok. I will send a new patch without the comment.
Thanks, Christian
--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH v3] n_tty: Fix read_buf race condition, increment read_head after pushing data

2014-11-12 Thread Christian Riesch
Commit 19e2ad6a09f0c06dbca19c98e5f4584269d913dd (n_tty: Remove overflow
tests from receive_buf() path) moved the increment of read_head into
the arguments list of read_buf_addr(). Function calls represent a
sequence point in C. Therefore read_head is incremented before the
character c is placed in the buffer. Since the circular read buffer is
a lock-less design since commit 6d76bd2618535c581f1673047b8341fd291abc67
(n_tty: Make N_TTY ldisc receive path lockless), this creates a race
condition that leads to communication errors.

This patch modifies the code to increment read_head _after_ the data
is placed in the buffer and thus fixes the race for non-SMP machines.
To fix the problem for SMP machines, memory barriers must be added in
a separate patch.

Signed-off-by: Christian Riesch christian.rie...@omicron.at
Cc: sta...@vger.kernel.org
---

Changes for v3:
- Removed unnecessary comment.

Changes for v2:
- Rewrote commit message. Since I did not know better, I blamed the compiler
  in v1, but actually the code was wrong. See the discussion in [1].
- Removed memory barriers. For non-SMP machines they are not required,
  for SMP machines more brainwork and discussions are needed.

 drivers/tty/n_tty.c |3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/tty/n_tty.c b/drivers/tty/n_tty.c
index 2e900a9..47ca0f3 100644
--- a/drivers/tty/n_tty.c
+++ b/drivers/tty/n_tty.c
@@ -321,7 +321,8 @@ static void n_tty_check_unthrottle(struct tty_struct *tty)
 
 static inline void put_tty_queue(unsigned char c, struct n_tty_data *ldata)
 {
-   *read_buf_addr(ldata, ldata-read_head++) = c;
+   *read_buf_addr(ldata, ldata-read_head) = c;
+   ldata-read_head++;
 }
 
 /**
-- 
1.7.9.5

--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH v2] n_tty: Fix read_buf race condition, increment read_head after pushing data

2014-11-11 Thread Christian Riesch
On Tue, Nov 11, 2014 at 2:04 PM, Måns Rullgård  wrote:
> Christian Riesch  writes:
[...]>> diff --git a/drivers/tty/n_tty.c b/drivers/tty/n_tty.c
>> index 2e900a9..b09f326 100644
>> --- a/drivers/tty/n_tty.c
>> +++ b/drivers/tty/n_tty.c
>> @@ -321,7 +321,9 @@ static void n_tty_check_unthrottle(struct tty_struct 
>> *tty)
>>
>>  static inline void put_tty_queue(unsigned char c, struct n_tty_data *ldata)
>>  {
>> - *read_buf_addr(ldata, ldata->read_head++) = c;
>> + *read_buf_addr(ldata, ldata->read_head) = c;
>> + /* increment read_head _after_ placing the character in the buffer */
>> + ldata->read_head++;
>>  }
>
> Is that comment really necessary?

No, I am pretty sure that removing the comment would not break the code ;-)

I just thought it would be good to have some kind of reminder here.
Otherwise someone may think: Hey, it would be a good idea to do the
increment right in the first line. And submit a patch for it.
But I am also ok with removing the comment. So if you like me to post
a v3 without the comment, I'll be happy to do that.

Christian
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH v2] n_tty: Fix read_buf race condition, increment read_head after pushing data

2014-11-11 Thread Christian Riesch
On Tue, Nov 11, 2014 at 2:04 PM, Måns Rullgård m...@mansr.com wrote:
 Christian Riesch christian.rie...@omicron.at writes:
[...] diff --git a/drivers/tty/n_tty.c b/drivers/tty/n_tty.c
 index 2e900a9..b09f326 100644
 --- a/drivers/tty/n_tty.c
 +++ b/drivers/tty/n_tty.c
 @@ -321,7 +321,9 @@ static void n_tty_check_unthrottle(struct tty_struct 
 *tty)

  static inline void put_tty_queue(unsigned char c, struct n_tty_data *ldata)
  {
 - *read_buf_addr(ldata, ldata-read_head++) = c;
 + *read_buf_addr(ldata, ldata-read_head) = c;
 + /* increment read_head _after_ placing the character in the buffer */
 + ldata-read_head++;
  }

 Is that comment really necessary?

No, I am pretty sure that removing the comment would not break the code ;-)

I just thought it would be good to have some kind of reminder here.
Otherwise someone may think: Hey, it would be a good idea to do the
increment right in the first line. And submit a patch for it.
But I am also ok with removing the comment. So if you like me to post
a v3 without the comment, I'll be happy to do that.

Christian
--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH v2] n_tty: Fix read_buf race condition, increment read_head after pushing data

2014-11-10 Thread Christian Riesch
Commit 19e2ad6a09f0c06dbca19c98e5f4584269d913dd ("n_tty: Remove overflow
tests from receive_buf() path") moved the increment of read_head into
the arguments list of read_buf_addr(). Function calls represent a
sequence point in C. Therefore read_head is incremented before the
character c is placed in the buffer. Since the circular read buffer is
a lock-less design since commit 6d76bd2618535c581f1673047b8341fd291abc67
("n_tty: Make N_TTY ldisc receive path lockless"), this creates a race
condition that leads to communication errors.

This patch modifies the code to increment read_head _after_ the data
is placed in the buffer and thus fixes the race for non-SMP machines.
To fix the problem for SMP machines, memory barriers must be added in
a separate patch.

Signed-off-by: Christian Riesch 
Cc: 
---

This is version 2 of the patch in [1].

Changes for v2:
- Rewrote commit message. Since I did not know better, I blamed the compiler
  in v1, but actually the code was wrong. See the discussion in [1].
- Removed memory barriers. For non-SMP machines they are not required,
  for SMP machines more brainwork and discussions are needed.

Best regards,
Christian

[1] https://lkml.org/lkml/2014/11/6/216


 drivers/tty/n_tty.c |4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/drivers/tty/n_tty.c b/drivers/tty/n_tty.c
index 2e900a9..b09f326 100644
--- a/drivers/tty/n_tty.c
+++ b/drivers/tty/n_tty.c
@@ -321,7 +321,9 @@ static void n_tty_check_unthrottle(struct tty_struct *tty)
 
 static inline void put_tty_queue(unsigned char c, struct n_tty_data *ldata)
 {
-   *read_buf_addr(ldata, ldata->read_head++) = c;
+   *read_buf_addr(ldata, ldata->read_head) = c;
+   /* increment read_head _after_ placing the character in the buffer */
+   ldata->read_head++;
 }
 
 /**
-- 
1.7.9.5

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH] n_tty: Add memory barrier to fix race condition in receive path

2014-11-10 Thread Christian Riesch
Hi Måns,

On Mon, Nov 10, 2014 at 10:25 AM, Måns Rullgård  wrote:
> Christian Riesch  writes:
>
>> On Thu, Nov 6, 2014 at 9:56 PM, Greg Kroah-Hartman
>>  wrote:
>>> On Thu, Nov 06, 2014 at 08:49:01PM +, Måns Rullgård wrote:
>>>> Greg Kroah-Hartman  writes:
>>>>
>>>> > On Thu, Nov 06, 2014 at 12:39:59PM +0100, Christian Riesch wrote:
>>>> >> The current implementation of put_tty_queue() causes a race condition
>>>> >> when re-arranged by the compiler.
>>>> >>
>>>> >> On my build with gcc 4.8.3, cross-compiling for ARM, the line
>>>> >>
>>>> >>*read_buf_addr(ldata, ldata->read_head++) = c;
>>>> >>
>>>> >> was re-arranged by the compiler to something like
>>>> >>
>>>> >>x = ldata->read_head
>>>> >>ldata->read_head++
>>>> >>*read_buf_addr(ldata, x) = c;
>>>> >>
>>>> >> which causes a race condition. Invalid data is read if data is read
>>>> >> before it is actually written to the read buffer.
>>>> >
>>>> > Really?  A compiler can rearange things like that and expect things to
>>>> > actually work?  How is that valid?
>>>>
>>>> This is actually required by the C spec.  There is a sequence point
>>>> before a function call, after the arguments have been evaluated.  Thus
>>>> all side-effects, such as the post-increment, must be complete before
>>>> the function is called, just like in the example.
>>>>
>>>> There is no "re-arranging" here.  The code is simply wrong.
>>>
>>> Ah, ok, time to dig out the C spec...
>>>
>>> Anyway, because of this, no need for the wmb() calls, just rearrange the
>>> logic and all should be good, right?  Christian, can you test that
>>> instead?
>>
>> I ran a test with the patch that I posted in my first email for the
>> last 4 days. No communication errors occurred so the patch actually
>> fixes my problem. I will run another test as suggested by Greg, just
>> with rearranging the logic.
>
> What hardware are you running on?  If it's a single-processor system,
> it won't break without barriers even if they are required for SMP.

Yes, single processor. Texas Instruments AM1808 SoC.

Thanks,
Christian
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH] n_tty: Add memory barrier to fix race condition in receive path

2014-11-10 Thread Christian Riesch
Hi Måns,

On Mon, Nov 10, 2014 at 10:25 AM, Måns Rullgård m...@mansr.com wrote:
 Christian Riesch christian.rie...@omicron.at writes:

 On Thu, Nov 6, 2014 at 9:56 PM, Greg Kroah-Hartman
 gre...@linuxfoundation.org wrote:
 On Thu, Nov 06, 2014 at 08:49:01PM +, Måns Rullgård wrote:
 Greg Kroah-Hartman gre...@linuxfoundation.org writes:

  On Thu, Nov 06, 2014 at 12:39:59PM +0100, Christian Riesch wrote:
  The current implementation of put_tty_queue() causes a race condition
  when re-arranged by the compiler.
 
  On my build with gcc 4.8.3, cross-compiling for ARM, the line
 
 *read_buf_addr(ldata, ldata-read_head++) = c;
 
  was re-arranged by the compiler to something like
 
 x = ldata-read_head
 ldata-read_head++
 *read_buf_addr(ldata, x) = c;
 
  which causes a race condition. Invalid data is read if data is read
  before it is actually written to the read buffer.
 
  Really?  A compiler can rearange things like that and expect things to
  actually work?  How is that valid?

 This is actually required by the C spec.  There is a sequence point
 before a function call, after the arguments have been evaluated.  Thus
 all side-effects, such as the post-increment, must be complete before
 the function is called, just like in the example.

 There is no re-arranging here.  The code is simply wrong.

 Ah, ok, time to dig out the C spec...

 Anyway, because of this, no need for the wmb() calls, just rearrange the
 logic and all should be good, right?  Christian, can you test that
 instead?

 I ran a test with the patch that I posted in my first email for the
 last 4 days. No communication errors occurred so the patch actually
 fixes my problem. I will run another test as suggested by Greg, just
 with rearranging the logic.

 What hardware are you running on?  If it's a single-processor system,
 it won't break without barriers even if they are required for SMP.

Yes, single processor. Texas Instruments AM1808 SoC.

Thanks,
Christian
--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH v2] n_tty: Fix read_buf race condition, increment read_head after pushing data

2014-11-10 Thread Christian Riesch
Commit 19e2ad6a09f0c06dbca19c98e5f4584269d913dd (n_tty: Remove overflow
tests from receive_buf() path) moved the increment of read_head into
the arguments list of read_buf_addr(). Function calls represent a
sequence point in C. Therefore read_head is incremented before the
character c is placed in the buffer. Since the circular read buffer is
a lock-less design since commit 6d76bd2618535c581f1673047b8341fd291abc67
(n_tty: Make N_TTY ldisc receive path lockless), this creates a race
condition that leads to communication errors.

This patch modifies the code to increment read_head _after_ the data
is placed in the buffer and thus fixes the race for non-SMP machines.
To fix the problem for SMP machines, memory barriers must be added in
a separate patch.

Signed-off-by: Christian Riesch christian.rie...@omicron.at
Cc: sta...@vger.kernel.org
---

This is version 2 of the patch in [1].

Changes for v2:
- Rewrote commit message. Since I did not know better, I blamed the compiler
  in v1, but actually the code was wrong. See the discussion in [1].
- Removed memory barriers. For non-SMP machines they are not required,
  for SMP machines more brainwork and discussions are needed.

Best regards,
Christian

[1] https://lkml.org/lkml/2014/11/6/216


 drivers/tty/n_tty.c |4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/drivers/tty/n_tty.c b/drivers/tty/n_tty.c
index 2e900a9..b09f326 100644
--- a/drivers/tty/n_tty.c
+++ b/drivers/tty/n_tty.c
@@ -321,7 +321,9 @@ static void n_tty_check_unthrottle(struct tty_struct *tty)
 
 static inline void put_tty_queue(unsigned char c, struct n_tty_data *ldata)
 {
-   *read_buf_addr(ldata, ldata-read_head++) = c;
+   *read_buf_addr(ldata, ldata-read_head) = c;
+   /* increment read_head _after_ placing the character in the buffer */
+   ldata-read_head++;
 }
 
 /**
-- 
1.7.9.5

--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH] n_tty: Add memory barrier to fix race condition in receive path

2014-11-09 Thread Christian Riesch
On Thu, Nov 6, 2014 at 9:56 PM, Greg Kroah-Hartman
 wrote:
> On Thu, Nov 06, 2014 at 08:49:01PM +, Måns Rullgård wrote:
>> Greg Kroah-Hartman  writes:
>>
>> > On Thu, Nov 06, 2014 at 12:39:59PM +0100, Christian Riesch wrote:
>> >> The current implementation of put_tty_queue() causes a race condition
>> >> when re-arranged by the compiler.
>> >>
>> >> On my build with gcc 4.8.3, cross-compiling for ARM, the line
>> >>
>> >>*read_buf_addr(ldata, ldata->read_head++) = c;
>> >>
>> >> was re-arranged by the compiler to something like
>> >>
>> >>x = ldata->read_head
>> >>ldata->read_head++
>> >>*read_buf_addr(ldata, x) = c;
>> >>
>> >> which causes a race condition. Invalid data is read if data is read
>> >> before it is actually written to the read buffer.
>> >
>> > Really?  A compiler can rearange things like that and expect things to
>> > actually work?  How is that valid?
>>
>> This is actually required by the C spec.  There is a sequence point
>> before a function call, after the arguments have been evaluated.  Thus
>> all side-effects, such as the post-increment, must be complete before
>> the function is called, just like in the example.
>>
>> There is no "re-arranging" here.  The code is simply wrong.
>
> Ah, ok, time to dig out the C spec...
>
> Anyway, because of this, no need for the wmb() calls, just rearrange the
> logic and all should be good, right?  Christian, can you test that
> instead?

I ran a test with the patch that I posted in my first email for the
last 4 days. No communication errors occurred so the patch actually
fixes my problem. I will run another test as suggested by Greg, just
with rearranging the logic.
Best regards, Christian
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH] n_tty: Add memory barrier to fix race condition in receive path

2014-11-09 Thread Christian Riesch
On Thu, Nov 6, 2014 at 9:56 PM, Greg Kroah-Hartman
gre...@linuxfoundation.org wrote:
 On Thu, Nov 06, 2014 at 08:49:01PM +, Måns Rullgård wrote:
 Greg Kroah-Hartman gre...@linuxfoundation.org writes:

  On Thu, Nov 06, 2014 at 12:39:59PM +0100, Christian Riesch wrote:
  The current implementation of put_tty_queue() causes a race condition
  when re-arranged by the compiler.
 
  On my build with gcc 4.8.3, cross-compiling for ARM, the line
 
 *read_buf_addr(ldata, ldata-read_head++) = c;
 
  was re-arranged by the compiler to something like
 
 x = ldata-read_head
 ldata-read_head++
 *read_buf_addr(ldata, x) = c;
 
  which causes a race condition. Invalid data is read if data is read
  before it is actually written to the read buffer.
 
  Really?  A compiler can rearange things like that and expect things to
  actually work?  How is that valid?

 This is actually required by the C spec.  There is a sequence point
 before a function call, after the arguments have been evaluated.  Thus
 all side-effects, such as the post-increment, must be complete before
 the function is called, just like in the example.

 There is no re-arranging here.  The code is simply wrong.

 Ah, ok, time to dig out the C spec...

 Anyway, because of this, no need for the wmb() calls, just rearrange the
 logic and all should be good, right?  Christian, can you test that
 instead?

I ran a test with the patch that I posted in my first email for the
last 4 days. No communication errors occurred so the patch actually
fixes my problem. I will run another test as suggested by Greg, just
with rearranging the logic.
Best regards, Christian
--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH] n_tty: Add memory barrier to fix race condition in receive path

2014-11-06 Thread Christian Riesch
[sent again due to stupid HTML mail problems, sorry]

On Thu, Nov 6, 2014 at 11:54 PM, Måns Rullgård  wrote:
> Greg Kroah-Hartman  writes:
>
>> On Thu, Nov 06, 2014 at 10:12:54PM +, Måns Rullgård wrote:
>>> Greg Kroah-Hartman  writes:
>>>
>>> > On Thu, Nov 06, 2014 at 09:38:59PM +, Måns Rullgård wrote:
>>> >> Greg Kroah-Hartman  writes:
>>> >>
>>> >> > On Thu, Nov 06, 2014 at 09:01:36PM +, Måns Rullgård wrote:
>>> >> >> Greg Kroah-Hartman  writes:
>>> >> >>
>>> >> >> > On Thu, Nov 06, 2014 at 08:49:01PM +, Måns Rullgård wrote:
>>> >> >> >> Greg Kroah-Hartman  writes:
>>> >> >> >>
>>> >> >> >> > On Thu, Nov 06, 2014 at 12:39:59PM +0100, Christian Riesch wrote:
>>> >> >> >> >> The current implementation of put_tty_queue() causes a race 
>>> >> >> >> >> condition
>>> >> >> >> >> when re-arranged by the compiler.
>>> >> >> >> >>
>>> >> >> >> >> On my build with gcc 4.8.3, cross-compiling for ARM, the line
>>> >> >> >> >>
>>> >> >> >> >>  *read_buf_addr(ldata, ldata->read_head++) = c;
>>> >> >> >> >>
>>> >> >> >> >> was re-arranged by the compiler to something like
>>> >> >> >> >>
>>> >> >> >> >>  x = ldata->read_head
>>> >> >> >> >>  ldata->read_head++
>>> >> >> >> >>  *read_buf_addr(ldata, x) = c;
>>> >> >> >> >>
>>> >> >> >> >> which causes a race condition. Invalid data is read if data is 
>>> >> >> >> >> read
>>> >> >> >> >> before it is actually written to the read buffer.
>>> >> >> >> >
>>> >> >> >> > Really?  A compiler can rearange things like that and expect 
>>> >> >> >> > things to
>>> >> >> >> > actually work?  How is that valid?
>>> >> >> >>
>>> >> >> >> This is actually required by the C spec.  There is a sequence point
>>> >> >> >> before a function call, after the arguments have been evaluated.  
>>> >> >> >> Thus
>>> >> >> >> all side-effects, such as the post-increment, must be complete 
>>> >> >> >> before
>>> >> >> >> the function is called, just like in the example.
>>> >> >> >>
>>> >> >> >> There is no "re-arranging" here.  The code is simply wrong.
>>> >> >> >
>>> >> >> > Ah, ok, time to dig out the C spec...
>>> >> >> >
>>> >> >> > Anyway, because of this, no need for the wmb() calls, just 
>>> >> >> > rearrange the
>>> >> >> > logic and all should be good, right?  Christian, can you test that
>>> >> >> > instead?
>>> >> >>
>>> >> >> Weakly ordered SMP systems probably need some kind of barrier.  I 
>>> >> >> didn't
>>> >> >> look at it carefully.
>>> >> >
>>> >> > It shouldn't need a barier, as it is a sequence point with the function
>>> >> > call.  Well, it's an inline function, but that "shouldn't" matter here,
>>> >> > right?
>>> >>
>>> >> Sequence points say nothing about the order in which stores become
>>> >> visible to other CPUs.  That's why there are barrier instructions.
>>> >
>>> > Yes, but "order" matters.
>>> >
>>> > If I write code that does:
>>> >
>>> > 100x = ldata->read_head;
>>> > 101>read_head[x & SOME_VALUE] = y;
>>> > 102ldata->read_head++;
>>> >
>>> > the compiler can not reorder lines 102 and 101 just because it feels
>>> > like it, right?  Or is it time to go spend some reading of the C spec
>>> > again...
>>>
>>> The compiler can't.  The hardware can.  All the hardware promises is
>>> that at some unspecified time in the future, both memory locations will
>>> have the correct values.  Another CPU might see 'read_head' updated
>>> before it sees the corresponding data value.  A wmb() between the writes
>>> forces the CPU to complete preceding stores before it begins subsequent
>>> ones.
>>
>> Yes, sorry, I'm not talking about other CPUs and what they see, I'm
>> talking about the local one.  I'm not assuming that this is SMP "safe"
>> at all.  If it is supposed to be, then yes, we do have problems, but
>> there should be a lock _somewhere_ protecting this.
>
> Within the confines of a single CPU + memory, barriers are never needed.
> The moment another CPU or master-capable peripheral enters the mix,
> proper ordering must be enforced somehow.
>
> If the buffer is already protected by a lock of some kind, this will
> provide the necessary barriers, so nothing further is necessary.  If
> it's a lock-less design, there will need to be barriers somewhere.

It was changed to lock-less with 3.12 in commit
6d76bd2618535c581f1673047b8341fd291abc67 ("n_tty: Make N_TTY ldisc
receive
path lockless"). So I will try to read the memory barrier docs again.

Of course my little ARM system is no SMP system, but I guess this
should also be fixed for the SMP case, right?

Thanks,
Christian
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH] n_tty: Add memory barrier to fix race condition in receive path

2014-11-06 Thread Christian Riesch
On Thu, Nov 6, 2014 at 9:56 PM, Greg Kroah-Hartman
 wrote:
> On Thu, Nov 06, 2014 at 08:49:01PM +, Måns Rullgård wrote:
>> Greg Kroah-Hartman  writes:
>>
>> > On Thu, Nov 06, 2014 at 12:39:59PM +0100, Christian Riesch wrote:
>> >> The current implementation of put_tty_queue() causes a race condition
>> >> when re-arranged by the compiler.
>> >>
>> >> On my build with gcc 4.8.3, cross-compiling for ARM, the line
>> >>
>> >>*read_buf_addr(ldata, ldata->read_head++) = c;
>> >>
>> >> was re-arranged by the compiler to something like
>> >>
>> >>x = ldata->read_head
>> >>ldata->read_head++
>> >>*read_buf_addr(ldata, x) = c;
>> >>
>> >> which causes a race condition. Invalid data is read if data is read
>> >> before it is actually written to the read buffer.
>> >
>> > Really?  A compiler can rearange things like that and expect things to
>> > actually work?  How is that valid?
>>
>> This is actually required by the C spec.  There is a sequence point
>> before a function call, after the arguments have been evaluated.  Thus
>> all side-effects, such as the post-increment, must be complete before
>> the function is called, just like in the example.
>>
>> There is no "re-arranging" here.  The code is simply wrong.

Oh, I didn't know that, thanks a lot for this!

> Anyway, because of this, no need for the wmb() calls, just rearrange the
> logic and all should be good, right?

I came up with the wmb() stuff after getting scared from reading
Documentation/memory-barriers.txt (which I didn't understand) and
Documentation/circular-buffers.txt (which I understood partly). But it
is actually a circular buffer and circular-buffers.txt says I need
memory barriers for circular buffers. Though I do not know how
function calls fit into this picture.

> Christian, can you test that
> instead?

Sure, but it will probably not happen before Monday. Thanks a lot for your help!

Christian
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH] n_tty: Add memory barrier to fix race condition in receive path

2014-11-06 Thread Christian Riesch
The current implementation of put_tty_queue() causes a race condition
when re-arranged by the compiler.

On my build with gcc 4.8.3, cross-compiling for ARM, the line

*read_buf_addr(ldata, ldata->read_head++) = c;

was re-arranged by the compiler to something like

x = ldata->read_head
ldata->read_head++
*read_buf_addr(ldata, x) = c;

which causes a race condition. Invalid data is read if data is read
before it is actually written to the read buffer.

This race condition was introduced with commit
6d76bd2618535c581f1673047b8341fd291abc67 ("n_tty: Make N_TTY ldisc receive
path lockless").

This patch adds memory barriers to resolve this race condition.

Signed-off-by: Christian Riesch 
Cc: Peter Hurley 
Cc: 
---

Hi all,

I noticed that since an upgrade to kernel 3.12 my ARM device communicating
via serial port with a GPS receiver module reports frequent communication
errors.

After several attempts to resolve these problems I created a small
test setup. This setup utilizes a small microcontroller that just sends
data via serial port to the ARM processor using 9600o1.

The code on the microcontroller looks like this:

char c = 48;
while (1) {
if c > 126 then c = 48
send character c
c++
}

On the ARM/Linux side I ran the serial port in non-canonical mode,
received the data and checked if the data is what we expect it to be:

struct termios tio;
memset(, 0, sizeof(tio));
tio.c_cflag = CREAD | CLOCAL | B9600 | CS8 | PARENB | PARODD;
tio.c_iflag = INPCK;
tio.c_cc[VTIME] = 0;
tio.c_cc[VMIN] = 0;
tcsetattr(fd, TCSANOW, );

...
c = 48;
while (1) {
...
poll(pfds, 1, 1000);
if (pfds[0].revents & POLLIN) {
ret = read(fd, buf, 200);
for (i = 0; i < ret; i++) {
c++;
if (c > 126)
c = 48;
if (c != buf[i]) {
printf("expected %d - received %d, ret = %d, i = %d\n",
c, buf[i], ret, i);
c = buf[i];
}
}
}
}

I ran this test for about 5 days, the result was:

expected 51 - received 63, ret = 11, i = 10
expected 64 - received 52, ret = 13, i = 0
expected 64 - received 76, ret = 11, i = 10
expected 77 - received 65, ret = 5, i = 0
expected 105 - received 117, ret = 18, i = 17
expected 118 - received 106, ret = 6, i = 0
expected 120 - received 53, ret = 16, i = 15
expected 54 - received 121, ret = 8, i = 0
expected 105 - received 117, ret = 3, i = 2
expected 118 - received 106, ret = 5, i = 0
expected 79 - received 91, ret = 20, i = 19
expected 92 - received 80, ret = 4, i = 0
expected 72 - received 84, ret = 15, i = 14
expected 85 - received 73, ret = 9, i = 0
expected 54 - received 66, ret = 13, i = 12
expected 67 - received 55, ret = 3, i = 0
expected 86 - received 98, ret = 25, i = 24
expected 99 - received 87, ret = 15, i = 0
expected 86 - received 98, ret = 14, i = 13
expected 99 - received 87, ret = 42, i = 0
expected 93 - received 105, ret = 34, i = 33
expected 106 - received 94, ret = 6, i = 0
expected 92 - received 104, ret = 16, i = 15
expected 105 - received 93, ret = 8, i = 0
expected 53 - received 65, ret = 8, i = 7
expected 66 - received 54, ret = 8, i = 0

The first line shows that we expected buf[i] to be 51, actually we
received 63. We therefore set c = 63, consequently we expect 64 as the
next character. But we receive 52, so everything is back to normal. So
no bytes are missing, no additional bytes are received, there is just
a single byte with a wrong content.

We see that always the last byte in buf is affected, i.e. buf[ret - 1].

Furthermore we see that the wrong byte is always off by 12, i.e. instead
of 51 we received 63 (63 - 51 = 12), instead of 64 we received 76
(76 - 64 = 12) etc.

The race that I described above in the commit message exactly results in
such a behavior.

In the example below read_head was already incremented but the new content
has not yet been written to ldata->read_buf.

48 49 50 51 64 65 66 67
^^
read_head

The receive buffer is 4096 bytes, and we are sending a character
sequence that repeats every 126 - 47 = 79 bytes. Therefore the offset between
the old data and the new data is 4096 mod 79 = 67.

Instead of the new value 52, we still read the old value 52 - 67 (with
wrapping around from 48 to 127) = 64 = 52 + 12.

I have now applied my proposed fix below, I will run a test for the new
few days and report if this finally solved my problem.

However, since I am not familiar with memory barriers, I would like to
ask you for comments if this is the correct way to solve this problem.

Thank you!

Regards, Christian


 drivers/tty/n_tty.c |   20 +++-
 1 file changed, 19 insertions(+), 1 deletion(-)

diff --git a/drivers/tty/n_tty.c b/drivers/tty/n_tty.c
index 89c4cee..831137e 1

Re: [PATCH] n_tty: Add memory barrier to fix race condition in receive path

2014-11-06 Thread Christian Riesch
On Thu, Nov 6, 2014 at 9:56 PM, Greg Kroah-Hartman
gre...@linuxfoundation.org wrote:
 On Thu, Nov 06, 2014 at 08:49:01PM +, Måns Rullgård wrote:
 Greg Kroah-Hartman gre...@linuxfoundation.org writes:

  On Thu, Nov 06, 2014 at 12:39:59PM +0100, Christian Riesch wrote:
  The current implementation of put_tty_queue() causes a race condition
  when re-arranged by the compiler.
 
  On my build with gcc 4.8.3, cross-compiling for ARM, the line
 
 *read_buf_addr(ldata, ldata-read_head++) = c;
 
  was re-arranged by the compiler to something like
 
 x = ldata-read_head
 ldata-read_head++
 *read_buf_addr(ldata, x) = c;
 
  which causes a race condition. Invalid data is read if data is read
  before it is actually written to the read buffer.
 
  Really?  A compiler can rearange things like that and expect things to
  actually work?  How is that valid?

 This is actually required by the C spec.  There is a sequence point
 before a function call, after the arguments have been evaluated.  Thus
 all side-effects, such as the post-increment, must be complete before
 the function is called, just like in the example.

 There is no re-arranging here.  The code is simply wrong.

Oh, I didn't know that, thanks a lot for this!

 Anyway, because of this, no need for the wmb() calls, just rearrange the
 logic and all should be good, right?

I came up with the wmb() stuff after getting scared from reading
Documentation/memory-barriers.txt (which I didn't understand) and
Documentation/circular-buffers.txt (which I understood partly). But it
is actually a circular buffer and circular-buffers.txt says I need
memory barriers for circular buffers. Though I do not know how
function calls fit into this picture.

 Christian, can you test that
 instead?

Sure, but it will probably not happen before Monday. Thanks a lot for your help!

Christian
--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH] n_tty: Add memory barrier to fix race condition in receive path

2014-11-06 Thread Christian Riesch
[sent again due to stupid HTML mail problems, sorry]

On Thu, Nov 6, 2014 at 11:54 PM, Måns Rullgård m...@mansr.com wrote:
 Greg Kroah-Hartman gre...@linuxfoundation.org writes:

 On Thu, Nov 06, 2014 at 10:12:54PM +, Måns Rullgård wrote:
 Greg Kroah-Hartman gre...@linuxfoundation.org writes:

  On Thu, Nov 06, 2014 at 09:38:59PM +, Måns Rullgård wrote:
  Greg Kroah-Hartman gre...@linuxfoundation.org writes:
 
   On Thu, Nov 06, 2014 at 09:01:36PM +, Måns Rullgård wrote:
   Greg Kroah-Hartman gre...@linuxfoundation.org writes:
  
On Thu, Nov 06, 2014 at 08:49:01PM +, Måns Rullgård wrote:
Greg Kroah-Hartman gre...@linuxfoundation.org writes:
   
 On Thu, Nov 06, 2014 at 12:39:59PM +0100, Christian Riesch wrote:
 The current implementation of put_tty_queue() causes a race 
 condition
 when re-arranged by the compiler.

 On my build with gcc 4.8.3, cross-compiling for ARM, the line

  *read_buf_addr(ldata, ldata-read_head++) = c;

 was re-arranged by the compiler to something like

  x = ldata-read_head
  ldata-read_head++
  *read_buf_addr(ldata, x) = c;

 which causes a race condition. Invalid data is read if data is 
 read
 before it is actually written to the read buffer.

 Really?  A compiler can rearange things like that and expect 
 things to
 actually work?  How is that valid?
   
This is actually required by the C spec.  There is a sequence point
before a function call, after the arguments have been evaluated.  
Thus
all side-effects, such as the post-increment, must be complete 
before
the function is called, just like in the example.
   
There is no re-arranging here.  The code is simply wrong.
   
Ah, ok, time to dig out the C spec...
   
Anyway, because of this, no need for the wmb() calls, just 
rearrange the
logic and all should be good, right?  Christian, can you test that
instead?
  
   Weakly ordered SMP systems probably need some kind of barrier.  I 
   didn't
   look at it carefully.
  
   It shouldn't need a barier, as it is a sequence point with the function
   call.  Well, it's an inline function, but that shouldn't matter here,
   right?
 
  Sequence points say nothing about the order in which stores become
  visible to other CPUs.  That's why there are barrier instructions.
 
  Yes, but order matters.
 
  If I write code that does:
 
  100x = ldata-read_head;
  101ldata-read_head[x  SOME_VALUE] = y;
  102ldata-read_head++;
 
  the compiler can not reorder lines 102 and 101 just because it feels
  like it, right?  Or is it time to go spend some reading of the C spec
  again...

 The compiler can't.  The hardware can.  All the hardware promises is
 that at some unspecified time in the future, both memory locations will
 have the correct values.  Another CPU might see 'read_head' updated
 before it sees the corresponding data value.  A wmb() between the writes
 forces the CPU to complete preceding stores before it begins subsequent
 ones.

 Yes, sorry, I'm not talking about other CPUs and what they see, I'm
 talking about the local one.  I'm not assuming that this is SMP safe
 at all.  If it is supposed to be, then yes, we do have problems, but
 there should be a lock _somewhere_ protecting this.

 Within the confines of a single CPU + memory, barriers are never needed.
 The moment another CPU or master-capable peripheral enters the mix,
 proper ordering must be enforced somehow.

 If the buffer is already protected by a lock of some kind, this will
 provide the necessary barriers, so nothing further is necessary.  If
 it's a lock-less design, there will need to be barriers somewhere.

It was changed to lock-less with 3.12 in commit
6d76bd2618535c581f1673047b8341fd291abc67 (n_tty: Make N_TTY ldisc
receive
path lockless). So I will try to read the memory barrier docs again.

Of course my little ARM system is no SMP system, but I guess this
should also be fixed for the SMP case, right?

Thanks,
Christian
--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH] n_tty: Add memory barrier to fix race condition in receive path

2014-11-06 Thread Christian Riesch
The current implementation of put_tty_queue() causes a race condition
when re-arranged by the compiler.

On my build with gcc 4.8.3, cross-compiling for ARM, the line

*read_buf_addr(ldata, ldata-read_head++) = c;

was re-arranged by the compiler to something like

x = ldata-read_head
ldata-read_head++
*read_buf_addr(ldata, x) = c;

which causes a race condition. Invalid data is read if data is read
before it is actually written to the read buffer.

This race condition was introduced with commit
6d76bd2618535c581f1673047b8341fd291abc67 (n_tty: Make N_TTY ldisc receive
path lockless).

This patch adds memory barriers to resolve this race condition.

Signed-off-by: Christian Riesch christian.rie...@omicron.at
Cc: Peter Hurley pe...@hurleysoftware.com
Cc: sta...@vger.kernel.org
---

Hi all,

I noticed that since an upgrade to kernel 3.12 my ARM device communicating
via serial port with a GPS receiver module reports frequent communication
errors.

After several attempts to resolve these problems I created a small
test setup. This setup utilizes a small microcontroller that just sends
data via serial port to the ARM processor using 9600o1.

The code on the microcontroller looks like this:

char c = 48;
while (1) {
if c  126 then c = 48
send character c
c++
}

On the ARM/Linux side I ran the serial port in non-canonical mode,
received the data and checked if the data is what we expect it to be:

struct termios tio;
memset(tio, 0, sizeof(tio));
tio.c_cflag = CREAD | CLOCAL | B9600 | CS8 | PARENB | PARODD;
tio.c_iflag = INPCK;
tio.c_cc[VTIME] = 0;
tio.c_cc[VMIN] = 0;
tcsetattr(fd, TCSANOW, tio);

...
c = 48;
while (1) {
...
poll(pfds, 1, 1000);
if (pfds[0].revents  POLLIN) {
ret = read(fd, buf, 200);
for (i = 0; i  ret; i++) {
c++;
if (c  126)
c = 48;
if (c != buf[i]) {
printf(expected %d - received %d, ret = %d, i = %d\n,
c, buf[i], ret, i);
c = buf[i];
}
}
}
}

I ran this test for about 5 days, the result was:

expected 51 - received 63, ret = 11, i = 10
expected 64 - received 52, ret = 13, i = 0
expected 64 - received 76, ret = 11, i = 10
expected 77 - received 65, ret = 5, i = 0
expected 105 - received 117, ret = 18, i = 17
expected 118 - received 106, ret = 6, i = 0
expected 120 - received 53, ret = 16, i = 15
expected 54 - received 121, ret = 8, i = 0
expected 105 - received 117, ret = 3, i = 2
expected 118 - received 106, ret = 5, i = 0
expected 79 - received 91, ret = 20, i = 19
expected 92 - received 80, ret = 4, i = 0
expected 72 - received 84, ret = 15, i = 14
expected 85 - received 73, ret = 9, i = 0
expected 54 - received 66, ret = 13, i = 12
expected 67 - received 55, ret = 3, i = 0
expected 86 - received 98, ret = 25, i = 24
expected 99 - received 87, ret = 15, i = 0
expected 86 - received 98, ret = 14, i = 13
expected 99 - received 87, ret = 42, i = 0
expected 93 - received 105, ret = 34, i = 33
expected 106 - received 94, ret = 6, i = 0
expected 92 - received 104, ret = 16, i = 15
expected 105 - received 93, ret = 8, i = 0
expected 53 - received 65, ret = 8, i = 7
expected 66 - received 54, ret = 8, i = 0

The first line shows that we expected buf[i] to be 51, actually we
received 63. We therefore set c = 63, consequently we expect 64 as the
next character. But we receive 52, so everything is back to normal. So
no bytes are missing, no additional bytes are received, there is just
a single byte with a wrong content.

We see that always the last byte in buf is affected, i.e. buf[ret - 1].

Furthermore we see that the wrong byte is always off by 12, i.e. instead
of 51 we received 63 (63 - 51 = 12), instead of 64 we received 76
(76 - 64 = 12) etc.

The race that I described above in the commit message exactly results in
such a behavior.

In the example below read_head was already incremented but the new content
has not yet been written to ldata-read_buf.

48 49 50 51 64 65 66 67
^^
read_head

The receive buffer is 4096 bytes, and we are sending a character
sequence that repeats every 126 - 47 = 79 bytes. Therefore the offset between
the old data and the new data is 4096 mod 79 = 67.

Instead of the new value 52, we still read the old value 52 - 67 (with
wrapping around from 48 to 127) = 64 = 52 + 12.

I have now applied my proposed fix below, I will run a test for the new
few days and report if this finally solved my problem.

However, since I am not familiar with memory barriers, I would like to
ask you for comments if this is the correct way to solve this problem.

Thank you!

Regards, Christian


 drivers/tty/n_tty.c |   20 +++-
 1 file changed, 19 insertions(+), 1 deletion(-)

diff --git a/drivers/tty/n_tty.c b/drivers/tty/n_tty.c

Re: [PATCH 1/1] mtd: cfi_cmdset_0002:add fixup for Micron M29EW after erase operation

2014-09-01 Thread Christian Riesch
On Mon, Sep 1, 2014 at 4:20 AM, bpqw  wrote:
> For Micron M29EW,20ms delay is needed after erase operation.
>
> Signed-off-by: BeanHuo 
> ---
>  drivers/mtd/chips/cfi_cmdset_0002.c |   11 +++
>  1 file changed, 11 insertions(+)
>
> diff --git a/drivers/mtd/chips/cfi_cmdset_0002.c 
> b/drivers/mtd/chips/cfi_cmdset_0002.c
> index 5a4bfe3..9b0de91 100644
> --- a/drivers/mtd/chips/cfi_cmdset_0002.c
> +++ b/drivers/mtd/chips/cfi_cmdset_0002.c
> @@ -509,6 +509,16 @@ static void cfi_fixup_m29ew_delay_after_resume(struct 
> cfi_private *cfi)
> cfi_udelay(500);
>  }
>
> +static void cfi_fixup_m29ew_delay_after_erase(struct cfi_private *cfi)
> +{
> +   /*
> +* Resolving the Delay After ERASE Issue @low temperature.
> +* 20ms delay is needed after erase operation.
> +*/
> +   if (is_m29ew(cfi))
> +   cfi_udelay(2);
> +}
> +
>  struct mtd_info *cfi_cmdset_0002(struct map_info *map, int primary)  {
> struct cfi_private *cfi = map->fldrv_priv; @@ -2397,6 +2407,7 @@ 
> static int __xipram do_erase_oneblock(struct map_info *map, struct flchip 
> *chip,

Missing line break? The patch does not apply.
Christian

> ret = -EIO;
> }
>
> +   cfi_fixup_m29ew_delay_after_erase(cfi);
> chip->state = FL_READY;
> DISABLE_VPP(map);
> put_chip(map, chip, adr);
> --
> 1.7.9.5
>
> __
> Linux MTD discussion mailing list
> http://lists.infradead.org/mailman/listinfo/linux-mtd/
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH 1/1] mtd: cfi_cmdset_0002:add fixup for Micron M29EW after erase operation

2014-09-01 Thread Christian Riesch
On Mon, Sep 1, 2014 at 4:20 AM, bpqw  wrote:
> For Micron M29EW,20ms delay is needed after erase operation.
>
> Signed-off-by: BeanHuo 
> ---
>  drivers/mtd/chips/cfi_cmdset_0002.c |   11 +++
>  1 file changed, 11 insertions(+)
>
> diff --git a/drivers/mtd/chips/cfi_cmdset_0002.c 
> b/drivers/mtd/chips/cfi_cmdset_0002.c
> index 5a4bfe3..9b0de91 100644
> --- a/drivers/mtd/chips/cfi_cmdset_0002.c
> +++ b/drivers/mtd/chips/cfi_cmdset_0002.c
> @@ -509,6 +509,16 @@ static void cfi_fixup_m29ew_delay_after_resume(struct 
> cfi_private *cfi)
> cfi_udelay(500);
>  }
>
> +static void cfi_fixup_m29ew_delay_after_erase(struct cfi_private *cfi)
> +{
> +   /*
> +* Resolving the Delay After ERASE Issue @low temperature.
> +* 20ms delay is needed after erase operation.
> +*/
> +   if (is_m29ew(cfi))
> +   cfi_udelay(2);
> +}
> +
>  struct mtd_info *cfi_cmdset_0002(struct map_info *map, int primary)  {
> struct cfi_private *cfi = map->fldrv_priv; @@ -2397,6 +2407,7 @@ 
> static int __xipram do_erase_oneblock(struct map_info *map, struct flchip 
> *chip,
> ret = -EIO;
> }
>
> +   cfi_fixup_m29ew_delay_after_erase(cfi);
> chip->state = FL_READY;
> DISABLE_VPP(map);
> put_chip(map, chip, adr);
> --
> 1.7.9.5
>
> __
> Linux MTD discussion mailing list
> http://lists.infradead.org/mailman/listinfo/linux-mtd/
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH 1/1] mtd: cfi_cmdset_0002:add fixup for Micron M29EW after erase operation

2014-09-01 Thread Christian Riesch
Hi,

On Mon, Sep 1, 2014 at 4:20 AM, bpqw  wrote:
> For Micron M29EW,20ms delay is needed after erase operation.

Is there a datasheet/application note/technical note from Micron
describing this issue? Like the TN-13-07 for the other M29EW fixes?
Are all M29EW types affected?

Thanks,
Christian

>
> Signed-off-by: BeanHuo 
> ---
>  drivers/mtd/chips/cfi_cmdset_0002.c |   11 +++
>  1 file changed, 11 insertions(+)
>
> diff --git a/drivers/mtd/chips/cfi_cmdset_0002.c 
> b/drivers/mtd/chips/cfi_cmdset_0002.c
> index 5a4bfe3..9b0de91 100644
> --- a/drivers/mtd/chips/cfi_cmdset_0002.c
> +++ b/drivers/mtd/chips/cfi_cmdset_0002.c
> @@ -509,6 +509,16 @@ static void cfi_fixup_m29ew_delay_after_resume(struct 
> cfi_private *cfi)
> cfi_udelay(500);
>  }
>
> +static void cfi_fixup_m29ew_delay_after_erase(struct cfi_private *cfi)
> +{
> +   /*
> +* Resolving the Delay After ERASE Issue @low temperature.
> +* 20ms delay is needed after erase operation.
> +*/
> +   if (is_m29ew(cfi))
> +   cfi_udelay(2);
> +}
> +
>  struct mtd_info *cfi_cmdset_0002(struct map_info *map, int primary)  {
> struct cfi_private *cfi = map->fldrv_priv; @@ -2397,6 +2407,7 @@ 
> static int __xipram do_erase_oneblock(struct map_info *map, struct flchip 
> *chip,
> ret = -EIO;
> }
>
> +   cfi_fixup_m29ew_delay_after_erase(cfi);
> chip->state = FL_READY;
> DISABLE_VPP(map);
> put_chip(map, chip, adr);
> --
> 1.7.9.5
>
> __
> Linux MTD discussion mailing list
> http://lists.infradead.org/mailman/listinfo/linux-mtd/
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH 1/1] mtd: cfi_cmdset_0002:add fixup for Micron M29EW after erase operation

2014-09-01 Thread Christian Riesch
Hi,

On Mon, Sep 1, 2014 at 4:20 AM, bpqw b...@micron.com wrote:
 For Micron M29EW,20ms delay is needed after erase operation.

Is there a datasheet/application note/technical note from Micron
describing this issue? Like the TN-13-07 for the other M29EW fixes?
Are all M29EW types affected?

Thanks,
Christian


 Signed-off-by: BeanHuo b...@micron.com
 ---
  drivers/mtd/chips/cfi_cmdset_0002.c |   11 +++
  1 file changed, 11 insertions(+)

 diff --git a/drivers/mtd/chips/cfi_cmdset_0002.c 
 b/drivers/mtd/chips/cfi_cmdset_0002.c
 index 5a4bfe3..9b0de91 100644
 --- a/drivers/mtd/chips/cfi_cmdset_0002.c
 +++ b/drivers/mtd/chips/cfi_cmdset_0002.c
 @@ -509,6 +509,16 @@ static void cfi_fixup_m29ew_delay_after_resume(struct 
 cfi_private *cfi)
 cfi_udelay(500);
  }

 +static void cfi_fixup_m29ew_delay_after_erase(struct cfi_private *cfi)
 +{
 +   /*
 +* Resolving the Delay After ERASE Issue @low temperature.
 +* 20ms delay is needed after erase operation.
 +*/
 +   if (is_m29ew(cfi))
 +   cfi_udelay(2);
 +}
 +
  struct mtd_info *cfi_cmdset_0002(struct map_info *map, int primary)  {
 struct cfi_private *cfi = map-fldrv_priv; @@ -2397,6 +2407,7 @@ 
 static int __xipram do_erase_oneblock(struct map_info *map, struct flchip 
 *chip,
 ret = -EIO;
 }

 +   cfi_fixup_m29ew_delay_after_erase(cfi);
 chip-state = FL_READY;
 DISABLE_VPP(map);
 put_chip(map, chip, adr);
 --
 1.7.9.5

 __
 Linux MTD discussion mailing list
 http://lists.infradead.org/mailman/listinfo/linux-mtd/
--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH 1/1] mtd: cfi_cmdset_0002:add fixup for Micron M29EW after erase operation

2014-09-01 Thread Christian Riesch
On Mon, Sep 1, 2014 at 4:20 AM, bpqw b...@micron.com wrote:
 For Micron M29EW,20ms delay is needed after erase operation.

 Signed-off-by: BeanHuo b...@micron.com
 ---
  drivers/mtd/chips/cfi_cmdset_0002.c |   11 +++
  1 file changed, 11 insertions(+)

 diff --git a/drivers/mtd/chips/cfi_cmdset_0002.c 
 b/drivers/mtd/chips/cfi_cmdset_0002.c
 index 5a4bfe3..9b0de91 100644
 --- a/drivers/mtd/chips/cfi_cmdset_0002.c
 +++ b/drivers/mtd/chips/cfi_cmdset_0002.c
 @@ -509,6 +509,16 @@ static void cfi_fixup_m29ew_delay_after_resume(struct 
 cfi_private *cfi)
 cfi_udelay(500);
  }

 +static void cfi_fixup_m29ew_delay_after_erase(struct cfi_private *cfi)
 +{
 +   /*
 +* Resolving the Delay After ERASE Issue @low temperature.
 +* 20ms delay is needed after erase operation.
 +*/
 +   if (is_m29ew(cfi))
 +   cfi_udelay(2);
 +}
 +
  struct mtd_info *cfi_cmdset_0002(struct map_info *map, int primary)  {
 struct cfi_private *cfi = map-fldrv_priv; @@ -2397,6 +2407,7 @@ 
 static int __xipram do_erase_oneblock(struct map_info *map, struct flchip 
 *chip,
 ret = -EIO;
 }

 +   cfi_fixup_m29ew_delay_after_erase(cfi);
 chip-state = FL_READY;
 DISABLE_VPP(map);
 put_chip(map, chip, adr);
 --
 1.7.9.5

 __
 Linux MTD discussion mailing list
 http://lists.infradead.org/mailman/listinfo/linux-mtd/
--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH 1/1] mtd: cfi_cmdset_0002:add fixup for Micron M29EW after erase operation

2014-09-01 Thread Christian Riesch
On Mon, Sep 1, 2014 at 4:20 AM, bpqw b...@micron.com wrote:
 For Micron M29EW,20ms delay is needed after erase operation.

 Signed-off-by: BeanHuo b...@micron.com
 ---
  drivers/mtd/chips/cfi_cmdset_0002.c |   11 +++
  1 file changed, 11 insertions(+)

 diff --git a/drivers/mtd/chips/cfi_cmdset_0002.c 
 b/drivers/mtd/chips/cfi_cmdset_0002.c
 index 5a4bfe3..9b0de91 100644
 --- a/drivers/mtd/chips/cfi_cmdset_0002.c
 +++ b/drivers/mtd/chips/cfi_cmdset_0002.c
 @@ -509,6 +509,16 @@ static void cfi_fixup_m29ew_delay_after_resume(struct 
 cfi_private *cfi)
 cfi_udelay(500);
  }

 +static void cfi_fixup_m29ew_delay_after_erase(struct cfi_private *cfi)
 +{
 +   /*
 +* Resolving the Delay After ERASE Issue @low temperature.
 +* 20ms delay is needed after erase operation.
 +*/
 +   if (is_m29ew(cfi))
 +   cfi_udelay(2);
 +}
 +
  struct mtd_info *cfi_cmdset_0002(struct map_info *map, int primary)  {
 struct cfi_private *cfi = map-fldrv_priv; @@ -2397,6 +2407,7 @@ 
 static int __xipram do_erase_oneblock(struct map_info *map, struct flchip 
 *chip,

Missing line break? The patch does not apply.
Christian

 ret = -EIO;
 }

 +   cfi_fixup_m29ew_delay_after_erase(cfi);
 chip-state = FL_READY;
 DISABLE_VPP(map);
 put_chip(map, chip, adr);
 --
 1.7.9.5

 __
 Linux MTD discussion mailing list
 http://lists.infradead.org/mailman/listinfo/linux-mtd/
--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: USB_MUSB_DA8XX with g_multi.ko

2014-06-26 Thread Christian Riesch
Hi Jon,

On Thu, Jun 26, 2014 at 4:46 AM, Jon Ringle  wrote:
> The only thing I needed to do was to remove the
> BROKEN dependency on USB_MUSB_DA8XX. Is there anything else I would
> have to do besides just removing BROKEN to get this accepted back into
> the kernel source tree?

I tried to remove the BROKEN dependency in [1], but without success.
See Felipe's response to my patch for more info. There was also
another discussion about this, see [2].
Christian

[1] http://marc.info/?t=1394061=1=2
[2] http://marc.info/?t=13952576757=1=2
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: USB_MUSB_DA8XX with g_multi.ko

2014-06-26 Thread Christian Riesch
Hi Jon,

On Thu, Jun 26, 2014 at 4:46 AM, Jon Ringle j...@ringle.org wrote:
 The only thing I needed to do was to remove the
 BROKEN dependency on USB_MUSB_DA8XX. Is there anything else I would
 have to do besides just removing BROKEN to get this accepted back into
 the kernel source tree?

I tried to remove the BROKEN dependency in [1], but without success.
See Felipe's response to my patch for more info. There was also
another discussion about this, see [2].
Christian

[1] http://marc.info/?t=1394061r=1w=2
[2] http://marc.info/?t=13952576757r=1w=2
--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH RFC net-next v1 0/9] ptp: dynamic pin control

2014-03-12 Thread Christian Riesch

Hi Richard,

--On March 08, 2014 20:42 +0100 Richard Cochran  
wrote:



This patch series introduces a way of changing the auxiliary PTP
Hardware Clock functions (periodic output signals and time stamping
external signals) at run time. In the past on the netdev list, we have
discussed other ways to handle this, such as module parameters and
ethtool. This series implements a new PHC ioctl because that is the
most natural way. Users already activate the auxiliary functions via
the ioctls. The sysfs interface has also been expanded so that the pin
configuration can be programmed using shell scripts.


I did a few tests on one of my boards, everything works so far! Thanks for 
the patchset, I like it!



The first patch adds the new ioctls. The PHC subsystem does most of
the work of maintaining the function-to-pin mapping. Drivers will only
need to allocate and initialize a pin configuration table and also
provide a new method that validates a particular assignment.

Patches 5 and 6 just clean up a couple of issues in the phyter driver,
and the remaining patches actually hook the phyter's pins into the new
system.

Comments and questions are most welcome.


Do you think it is possible to extend this in the future, e.g. for 
selecting the polarity of periodic output signals or for time stamping of 
external signals (rising edge/falling edge), or duty cycles of the periodic 
signal other than 50%? How could this be done? Using the reserved fields in 
struct ptp_pin_desc?


Do you think the concept allows an extension for single pulse output, e.g. 
programming a pin to output a single pulse at a given time, as supported by 
the DP83640?


If several DP83640 are connected together with the calibration function, 
only the GPIOs of the master device can be used, right? I guess this could 
also be extended in the future to use the GPIOs of all DP83640, right? Or 
do you see a problem with your concept here?


Best regards,
Christian

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH RFC net-next v1 0/9] ptp: dynamic pin control

2014-03-12 Thread Christian Riesch

Hi Richard,

--On March 10, 2014 14:42 +0100 Richard Cochran  
wrote:



On Mon, Mar 10, 2014 at 12:52:57PM +, Sørensen, Stefan wrote:


What are the n_ext_ts and n_per_out supposed to be set to now? The
number of pins configured for the relevant function or the number of
channels that are available for the function?


They are the number of available functions. This is not necessarily the
same as the number of pins. Many chips have more functions than pins.


The implementation is limited to a single function for each pin - the
dp83640 supports an ext_ts and several periodic outputs on the same pin,
but I do not see that many real-world uses.


Yes, it does support different functions on a single pin, but not at
the same time.  You have to choose what function you want on each pin,
and that is what the new ioctl lets you do.

I did not change the n_per_out in this series,


Why not? I think it would be a good idea to set both n_ext_ts and n_per_out 
to the correct value right from the start (8, right?).

Christian


but once this basic
support gets merged, then you will be able to increase n_per_out for
the dp83640 with little extra effort.

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH RFC net-next v1 0/9] ptp: dynamic pin control

2014-03-12 Thread Christian Riesch

Hi Richard,

--On March 10, 2014 14:42 +0100 Richard Cochran richardcoch...@gmail.com 
wrote:



On Mon, Mar 10, 2014 at 12:52:57PM +, Sørensen, Stefan wrote:


What are the n_ext_ts and n_per_out supposed to be set to now? The
number of pins configured for the relevant function or the number of
channels that are available for the function?


They are the number of available functions. This is not necessarily the
same as the number of pins. Many chips have more functions than pins.


The implementation is limited to a single function for each pin - the
dp83640 supports an ext_ts and several periodic outputs on the same pin,
but I do not see that many real-world uses.


Yes, it does support different functions on a single pin, but not at
the same time.  You have to choose what function you want on each pin,
and that is what the new ioctl lets you do.

I did not change the n_per_out in this series,


Why not? I think it would be a good idea to set both n_ext_ts and n_per_out 
to the correct value right from the start (8, right?).

Christian


but once this basic
support gets merged, then you will be able to increase n_per_out for
the dp83640 with little extra effort.

--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH RFC net-next v1 0/9] ptp: dynamic pin control

2014-03-12 Thread Christian Riesch

Hi Richard,

--On March 08, 2014 20:42 +0100 Richard Cochran richardcoch...@gmail.com 
wrote:



This patch series introduces a way of changing the auxiliary PTP
Hardware Clock functions (periodic output signals and time stamping
external signals) at run time. In the past on the netdev list, we have
discussed other ways to handle this, such as module parameters and
ethtool. This series implements a new PHC ioctl because that is the
most natural way. Users already activate the auxiliary functions via
the ioctls. The sysfs interface has also been expanded so that the pin
configuration can be programmed using shell scripts.


I did a few tests on one of my boards, everything works so far! Thanks for 
the patchset, I like it!



The first patch adds the new ioctls. The PHC subsystem does most of
the work of maintaining the function-to-pin mapping. Drivers will only
need to allocate and initialize a pin configuration table and also
provide a new method that validates a particular assignment.

Patches 5 and 6 just clean up a couple of issues in the phyter driver,
and the remaining patches actually hook the phyter's pins into the new
system.

Comments and questions are most welcome.


Do you think it is possible to extend this in the future, e.g. for 
selecting the polarity of periodic output signals or for time stamping of 
external signals (rising edge/falling edge), or duty cycles of the periodic 
signal other than 50%? How could this be done? Using the reserved fields in 
struct ptp_pin_desc?


Do you think the concept allows an extension for single pulse output, e.g. 
programming a pin to output a single pulse at a given time, as supported by 
the DP83640?


If several DP83640 are connected together with the calibration function, 
only the GPIOs of the master device can be used, right? I guess this could 
also be extended in the future to use the GPIOs of all DP83640, right? Or 
do you see a problem with your concept here?


Best regards,
Christian

--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH RFC net-next v1 1/9] ptp: introduce programmable pins.

2014-03-11 Thread Christian Riesch

Hi Richard,

--On March 08, 2014 20:42 +0100 Richard Cochran  
wrote:



This patch adds a pair of new ioctls to the PTP Hardware Clock device
interface. Using the ioctls, user space programs can query each pin to
find out its current function and also reprogram a different function
if desired.

Signed-off-by: Richard Cochran 
---
 drivers/ptp/ptp_chardev.c|  133
+-  drivers/ptp/ptp_clock.c
|   23 +++
 drivers/ptp/ptp_private.h|4 ++
 include/linux/ptp_clock_kernel.h |   33 ++
 include/uapi/linux/ptp_clock.h   |   39 ++-
 5 files changed, 230 insertions(+), 2 deletions(-)

diff --git a/drivers/ptp/ptp_chardev.c b/drivers/ptp/ptp_chardev.c
index 34a0c60..dc13d1e 100644
--- a/drivers/ptp/ptp_chardev.c
+++ b/drivers/ptp/ptp_chardev.c

[...]

+int ptp_setpin(struct ptp_clock *ptp, unsigned int pin,
+  enum ptp_pin_function func, unsigned int chan)
+{
+   struct ptp_clock_info *info = ptp->info;
+   struct ptp_pin_desc *pin1 = NULL, *pin2 = >pin_config[pin];
+   unsigned int i;
+
+   /* Check to see if any other pin previously had this function. */
+   if (mutex_lock_interruptible(>pincfg_mux))
+   return -ERESTARTSYS;
+   for (i = 0; i < info->n_pins; i++) {
+   if (info->pin_config[i].func == func &&
+   info->pin_config[i].chan == chan) {
+   pin1 = >pin_config[i];
+   break;
+   }
+   }
+   mutex_unlock(>pincfg_mux);
+   if (pin1 && i == pin)
+   return 0;
+
+   /* Check the desired function and channel. */
+   switch (func) {
+   case PTP_PF_NONE:
+   break;
+   case PTP_PF_EXTTS:
+   if (chan >= info->n_ext_ts)
+   return -EINVAL;
+   break;
+   case PTP_PF_PEROUT:
+   if (chan >= info->n_per_out)
+   return -EINVAL;
+   break;
+   case PTP_PF_PHYSYNC:
+   pr_err("sorry, cannot reassign the calibration pin\n");
+   return -EINVAL;
+   default:
+   return -EINVAL;
+   }
+
+   if (pin1 && pin1->func == PTP_PF_PHYSYNC) {
+   pr_err("sorry, cannot reprogram the calibration pin\n");
+   return -EINVAL;


   
Will this ever happen? pin1 && pin1->func == PTP_PF_PHYSYNC means that func 
== PTP_PF_PHYSYNC, but in this case you already return -EINVAL a few lines 
above.


Christian

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH RFC net-next v1 1/9] ptp: introduce programmable pins.

2014-03-11 Thread Christian Riesch

Hi Richard,

--On March 08, 2014 20:42 +0100 Richard Cochran richardcoch...@gmail.com 
wrote:



This patch adds a pair of new ioctls to the PTP Hardware Clock device
interface. Using the ioctls, user space programs can query each pin to
find out its current function and also reprogram a different function
if desired.

Signed-off-by: Richard Cochran richardcoch...@gmail.com
---
 drivers/ptp/ptp_chardev.c|  133
+-  drivers/ptp/ptp_clock.c
|   23 +++
 drivers/ptp/ptp_private.h|4 ++
 include/linux/ptp_clock_kernel.h |   33 ++
 include/uapi/linux/ptp_clock.h   |   39 ++-
 5 files changed, 230 insertions(+), 2 deletions(-)

diff --git a/drivers/ptp/ptp_chardev.c b/drivers/ptp/ptp_chardev.c
index 34a0c60..dc13d1e 100644
--- a/drivers/ptp/ptp_chardev.c
+++ b/drivers/ptp/ptp_chardev.c

[...]

+int ptp_setpin(struct ptp_clock *ptp, unsigned int pin,
+  enum ptp_pin_function func, unsigned int chan)
+{
+   struct ptp_clock_info *info = ptp-info;
+   struct ptp_pin_desc *pin1 = NULL, *pin2 = info-pin_config[pin];
+   unsigned int i;
+
+   /* Check to see if any other pin previously had this function. */
+   if (mutex_lock_interruptible(ptp-pincfg_mux))
+   return -ERESTARTSYS;
+   for (i = 0; i  info-n_pins; i++) {
+   if (info-pin_config[i].func == func 
+   info-pin_config[i].chan == chan) {
+   pin1 = info-pin_config[i];
+   break;
+   }
+   }
+   mutex_unlock(ptp-pincfg_mux);
+   if (pin1  i == pin)
+   return 0;
+
+   /* Check the desired function and channel. */
+   switch (func) {
+   case PTP_PF_NONE:
+   break;
+   case PTP_PF_EXTTS:
+   if (chan = info-n_ext_ts)
+   return -EINVAL;
+   break;
+   case PTP_PF_PEROUT:
+   if (chan = info-n_per_out)
+   return -EINVAL;
+   break;
+   case PTP_PF_PHYSYNC:
+   pr_err(sorry, cannot reassign the calibration pin\n);
+   return -EINVAL;
+   default:
+   return -EINVAL;
+   }
+
+   if (pin1  pin1-func == PTP_PF_PHYSYNC) {
+   pr_err(sorry, cannot reprogram the calibration pin\n);
+   return -EINVAL;


   
Will this ever happen? pin1  pin1-func == PTP_PF_PHYSYNC means that func 
== PTP_PF_PHYSYNC, but in this case you already return -EINVAL a few lines 
above.


Christian

--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH v2 RESEND 2/2] mtd: Fix the behavior of otp write if there is not enough room for data

2014-03-06 Thread Christian Riesch

Hi Brian,

--On March 06, 2014 00:49 -0800 Brian Norris  
wrote:



Hi,

On Wed, Mar 05, 2014 at 09:50:35AM +0100, Christian Riesch wrote:

On March 04, 2014 23:20 -0800 Brian Norris 
wrote:
> On Tue, Jan 28, 2014 at 09:29:45AM +0100, Christian Riesch wrote:
>> An OTP write shall write as much data as possible to the OTP memory
>> and return the number of bytes that have actually been written.
>> If no data could be written at all due to lack of OTP memory,
>> return -ENOSPC.
>>
>> Signed-off-by: Christian Riesch 
>> Cc: Artem Bityutskiy 
>> Cc: Kyungmin Park 
>> Cc: Amul Kumar Saha 
>> ---
>> drivers/mtd/chips/cfi_cmdset_0001.c |   13 +++--
>> drivers/mtd/devices/mtd_dataflash.c |   13 +
>> drivers/mtd/mtdchar.c   |7 +++
>> drivers/mtd/onenand/onenand_base.c  |   10 +-
>> 4 files changed, 32 insertions(+), 11 deletions(-)
>>
>> diff --git a/drivers/mtd/chips/cfi_cmdset_0001.c
>> b/drivers/mtd/chips/cfi_cmdset_0001.c index 7aa581f..cf423a6 100644
>> --- a/drivers/mtd/chips/cfi_cmdset_0001.c
>> +++ b/drivers/mtd/chips/cfi_cmdset_0001.c
>> @@ -2387,8 +2387,17 @@ static int
>> cfi_intelext_write_user_prot_reg(struct mtd_info *mtd, loff_t from,
>>size_t len, size_t *retlen,
>> u_char *buf)
>> {
>> -  return cfi_intelext_otp_walk(mtd, from, len, retlen,
>> -   buf, do_otp_write, 1);
>> +  int ret;
>> +
>> +  ret = cfi_intelext_otp_walk(mtd, from, len, retlen,
>> +  buf, do_otp_write, 1);
>> +
>> +  /* if no data could be written due to lack of OTP memory,
>> + return ENOSPC */
>
> /*
> * Can you use this style of mult-line comments please?
> * It's in Documentation/CodingStyle
> */
>

Ok, I will change that.

>> +  if (!ret && len && !(*retlen))
>> +  return -ENOSPC;
>
> Couldn't (shouldn't) this check be pushed to the common
> mtd_write_user_prot_reg() helper in mtdcore.c?

Yes, I don't see why this wouldn't work. But I thought the code
would be easier to understand if we return the correct error code as
soon as the error is detected, not using some additional logic in
some other function. What do you think?


No, this is the purpose of the mtd_xxx() wrappers for the mtd->_xxx
implementations. That way we don't have to inconsistently implement the
same checks in every driver. This caught a few bugs for
mtd_{read,write}() when we unified the bounds checking, I think.


Ok, I will change that.


> And once you do that, you
> will see that cfi_intelext_write_user_prot_reg() (and other
> mtd->_write_user_prot_reg() implementations) will never be called with
> len == 0. So this just becomes (in mtdcore.c):
>
> diff --git a/drivers/mtd/mtdcore.c b/drivers/mtd/mtdcore.c
> index 0a7d77e65335..ee6730748f7e 100644
> --- a/drivers/mtd/mtdcore.c
> +++ b/drivers/mtd/mtdcore.c
> @@ -909,11 +909,16 @@ EXPORT_SYMBOL_GPL(mtd_read_fact_prot_reg);
> int mtd_get_user_prot_info(struct mtd_info *mtd, size_t len, size_t
> *retlen,  struct otp_info *buf)
> {
> +  int ret;
> +
>if (!mtd->_get_user_prot_info)
>return -EOPNOTSUPP;
>if (!len)
>return 0;
> -  return mtd->_get_user_prot_info(mtd, len, retlen, buf);
> +  ret = mtd->_get_user_prot_info(mtd, len, retlen, buf);
> +  if (ret)
> +  return ret;
> +  return !(*retlen) ? -ENOSPC: 0;
> }
> EXPORT_SYMBOL_GPL(mtd_get_user_prot_info);
>
>
>> +
>> +  return ret;
>> }
>>
>> static int cfi_intelext_lock_user_prot_reg(struct mtd_info *mtd,
>> diff --git a/drivers/mtd/devices/mtd_dataflash.c
>> b/drivers/mtd/devices/mtd_dataflash.c index 09c69ce..5236d85 100644
>> --- a/drivers/mtd/devices/mtd_dataflash.c
>> +++ b/drivers/mtd/devices/mtd_dataflash.c
>> @@ -545,14 +545,11 @@ static int dataflash_write_user_otp(struct
>> mtd_info *mtd, struct dataflash*priv = mtd->priv;
>>int status;
>>
>
> I'm not sure I quite follow the logic for the following hunk. I think
> it deserves some more explanation, either in your commit or in a
> comment. As it stands, you're deleting a comment and potentially
> changing the return code behavior subtly.
>
>> -  if (len > 64)
>> -  return -EINVAL;
>> -
>> -  /* Strictly speaking, we *could* truncate the write ... but
>> -   * let's not do that for the only write that's ever possible.
>> -   */
>> - 

Re: [PATCH v2 RESEND 2/2] mtd: Fix the behavior of otp write if there is not enough room for data

2014-03-06 Thread Christian Riesch

Hi Brian,

--On March 06, 2014 00:49 -0800 Brian Norris computersforpe...@gmail.com 
wrote:



Hi,

On Wed, Mar 05, 2014 at 09:50:35AM +0100, Christian Riesch wrote:

On March 04, 2014 23:20 -0800 Brian Norris computersforpe...@gmail.com
wrote:
 On Tue, Jan 28, 2014 at 09:29:45AM +0100, Christian Riesch wrote:
 An OTP write shall write as much data as possible to the OTP memory
 and return the number of bytes that have actually been written.
 If no data could be written at all due to lack of OTP memory,
 return -ENOSPC.

 Signed-off-by: Christian Riesch christian.rie...@omicron.at
 Cc: Artem Bityutskiy artem.bityuts...@linux.intel.com
 Cc: Kyungmin Park kyungmin.p...@samsung.com
 Cc: Amul Kumar Saha amul.s...@samsung.com
 ---
 drivers/mtd/chips/cfi_cmdset_0001.c |   13 +++--
 drivers/mtd/devices/mtd_dataflash.c |   13 +
 drivers/mtd/mtdchar.c   |7 +++
 drivers/mtd/onenand/onenand_base.c  |   10 +-
 4 files changed, 32 insertions(+), 11 deletions(-)

 diff --git a/drivers/mtd/chips/cfi_cmdset_0001.c
 b/drivers/mtd/chips/cfi_cmdset_0001.c index 7aa581f..cf423a6 100644
 --- a/drivers/mtd/chips/cfi_cmdset_0001.c
 +++ b/drivers/mtd/chips/cfi_cmdset_0001.c
 @@ -2387,8 +2387,17 @@ static int
 cfi_intelext_write_user_prot_reg(struct mtd_info *mtd, loff_t from,
size_t len, size_t *retlen,
 u_char *buf)
 {
 -  return cfi_intelext_otp_walk(mtd, from, len, retlen,
 -   buf, do_otp_write, 1);
 +  int ret;
 +
 +  ret = cfi_intelext_otp_walk(mtd, from, len, retlen,
 +  buf, do_otp_write, 1);
 +
 +  /* if no data could be written due to lack of OTP memory,
 + return ENOSPC */

 /*
 * Can you use this style of mult-line comments please?
 * It's in Documentation/CodingStyle
 */


Ok, I will change that.

 +  if (!ret  len  !(*retlen))
 +  return -ENOSPC;

 Couldn't (shouldn't) this check be pushed to the common
 mtd_write_user_prot_reg() helper in mtdcore.c?

Yes, I don't see why this wouldn't work. But I thought the code
would be easier to understand if we return the correct error code as
soon as the error is detected, not using some additional logic in
some other function. What do you think?


No, this is the purpose of the mtd_xxx() wrappers for the mtd-_xxx
implementations. That way we don't have to inconsistently implement the
same checks in every driver. This caught a few bugs for
mtd_{read,write}() when we unified the bounds checking, I think.


Ok, I will change that.


 And once you do that, you
 will see that cfi_intelext_write_user_prot_reg() (and other
 mtd-_write_user_prot_reg() implementations) will never be called with
 len == 0. So this just becomes (in mtdcore.c):

 diff --git a/drivers/mtd/mtdcore.c b/drivers/mtd/mtdcore.c
 index 0a7d77e65335..ee6730748f7e 100644
 --- a/drivers/mtd/mtdcore.c
 +++ b/drivers/mtd/mtdcore.c
 @@ -909,11 +909,16 @@ EXPORT_SYMBOL_GPL(mtd_read_fact_prot_reg);
 int mtd_get_user_prot_info(struct mtd_info *mtd, size_t len, size_t
 *retlen,  struct otp_info *buf)
 {
 +  int ret;
 +
if (!mtd-_get_user_prot_info)
return -EOPNOTSUPP;
if (!len)
return 0;
 -  return mtd-_get_user_prot_info(mtd, len, retlen, buf);
 +  ret = mtd-_get_user_prot_info(mtd, len, retlen, buf);
 +  if (ret)
 +  return ret;
 +  return !(*retlen) ? -ENOSPC: 0;
 }
 EXPORT_SYMBOL_GPL(mtd_get_user_prot_info);


 +
 +  return ret;
 }

 static int cfi_intelext_lock_user_prot_reg(struct mtd_info *mtd,
 diff --git a/drivers/mtd/devices/mtd_dataflash.c
 b/drivers/mtd/devices/mtd_dataflash.c index 09c69ce..5236d85 100644
 --- a/drivers/mtd/devices/mtd_dataflash.c
 +++ b/drivers/mtd/devices/mtd_dataflash.c
 @@ -545,14 +545,11 @@ static int dataflash_write_user_otp(struct
 mtd_info *mtd, struct dataflash*priv = mtd-priv;
int status;


 I'm not sure I quite follow the logic for the following hunk. I think
 it deserves some more explanation, either in your commit or in a
 comment. As it stands, you're deleting a comment and potentially
 changing the return code behavior subtly.

 -  if (len  64)
 -  return -EINVAL;
 -
 -  /* Strictly speaking, we *could* truncate the write ... but
 -   * let's not do that for the only write that's ever possible.
 -   */
 -  if ((from + len)  64)
 -  return -EINVAL;
 +  if ((from + len)  64) {
 +  len = 64 - from;

 Why are you reassigning len? Are you trying to undo the comment above,
 so that you *can* truncate the write? (It looks like there are other
 implmentations which will truncate the write and return -ENOSPC, FWIW.)

Currently we have two kind of implementations: We have
implementations like this one which will refuse to write any data if
the write requests more data to be written than space

Re: [PATCH v2 RESEND 2/2] mtd: Fix the behavior of otp write if there is not enough room for data

2014-03-05 Thread Christian Riesch

Hi Brian,
Thank you very much for your comments on the patch!

--On March 04, 2014 23:20 -0800 Brian Norris  
wrote:



Hi Christian,

A few comments below.

On Tue, Jan 28, 2014 at 09:29:45AM +0100, Christian Riesch wrote:

An OTP write shall write as much data as possible to the OTP memory
and return the number of bytes that have actually been written.
If no data could be written at all due to lack of OTP memory,
return -ENOSPC.

Signed-off-by: Christian Riesch 
Cc: Artem Bityutskiy 
Cc: Kyungmin Park 
Cc: Amul Kumar Saha 
---
 drivers/mtd/chips/cfi_cmdset_0001.c |   13 +++--
 drivers/mtd/devices/mtd_dataflash.c |   13 +
 drivers/mtd/mtdchar.c   |7 +++
 drivers/mtd/onenand/onenand_base.c  |   10 +-
 4 files changed, 32 insertions(+), 11 deletions(-)

diff --git a/drivers/mtd/chips/cfi_cmdset_0001.c
b/drivers/mtd/chips/cfi_cmdset_0001.c index 7aa581f..cf423a6 100644
--- a/drivers/mtd/chips/cfi_cmdset_0001.c
+++ b/drivers/mtd/chips/cfi_cmdset_0001.c
@@ -2387,8 +2387,17 @@ static int
cfi_intelext_write_user_prot_reg(struct mtd_info *mtd, loff_t from,
size_t len, size_t *retlen,
 u_char *buf)
 {
-   return cfi_intelext_otp_walk(mtd, from, len, retlen,
-buf, do_otp_write, 1);
+   int ret;
+
+   ret = cfi_intelext_otp_walk(mtd, from, len, retlen,
+   buf, do_otp_write, 1);
+
+   /* if no data could be written due to lack of OTP memory,
+  return ENOSPC */


/*
 * Can you use this style of mult-line comments please?
 * It's in Documentation/CodingStyle
 */



Ok, I will change that.


+   if (!ret && len && !(*retlen))
+   return -ENOSPC;


Couldn't (shouldn't) this check be pushed to the common
mtd_write_user_prot_reg() helper in mtdcore.c?


Yes, I don't see why this wouldn't work. But I thought the code would be 
easier to understand if we return the correct error code as soon as the 
error is detected, not using some additional logic in some other function. 
What do you think?



And once you do that, you
will see that cfi_intelext_write_user_prot_reg() (and other
mtd->_write_user_prot_reg() implementations) will never be called with
len == 0. So this just becomes (in mtdcore.c):

diff --git a/drivers/mtd/mtdcore.c b/drivers/mtd/mtdcore.c
index 0a7d77e65335..ee6730748f7e 100644
--- a/drivers/mtd/mtdcore.c
+++ b/drivers/mtd/mtdcore.c
@@ -909,11 +909,16 @@ EXPORT_SYMBOL_GPL(mtd_read_fact_prot_reg);
 int mtd_get_user_prot_info(struct mtd_info *mtd, size_t len, size_t
*retlen,   struct otp_info *buf)
 {
+   int ret;
+
if (!mtd->_get_user_prot_info)
return -EOPNOTSUPP;
if (!len)
return 0;
-   return mtd->_get_user_prot_info(mtd, len, retlen, buf);
+   ret = mtd->_get_user_prot_info(mtd, len, retlen, buf);
+   if (ret)
+   return ret;
+   return !(*retlen) ? -ENOSPC: 0;
 }
 EXPORT_SYMBOL_GPL(mtd_get_user_prot_info);



+
+   return ret;
 }

 static int cfi_intelext_lock_user_prot_reg(struct mtd_info *mtd,
diff --git a/drivers/mtd/devices/mtd_dataflash.c
b/drivers/mtd/devices/mtd_dataflash.c index 09c69ce..5236d85 100644
--- a/drivers/mtd/devices/mtd_dataflash.c
+++ b/drivers/mtd/devices/mtd_dataflash.c
@@ -545,14 +545,11 @@ static int dataflash_write_user_otp(struct
mtd_info *mtd, struct dataflash *priv = mtd->priv;
int status;



I'm not sure I quite follow the logic for the following hunk. I think it
deserves some more explanation, either in your commit or in a comment.
As it stands, you're deleting a comment and potentially changing the
return code behavior subtly.


-   if (len > 64)
-   return -EINVAL;
-
-   /* Strictly speaking, we *could* truncate the write ... but
-* let's not do that for the only write that's ever possible.
-*/
-   if ((from + len) > 64)
-   return -EINVAL;
+   if ((from + len) > 64) {
+   len = 64 - from;


Why are you reassigning len? Are you trying to undo the comment above,
so that you *can* truncate the write? (It looks like there are other
implmentations which will truncate the write and return -ENOSPC, FWIW.)


Currently we have two kind of implementations: We have implementations like 
this one which will refuse to write any data if the write requests more 
data to be written than space is available. And we have implementations 
like cfi_intelext_write_user_prot_reg that will truncate the write and 
write as much data that is possible (and return the number of bytes that 
actually have been written, -ENOSPC shall only be returned if no data could 
be written at all).


For a harmonization one of the implementations and their behavior must be 
changed. I chose to change it to "write a

Re: [PATCH v2 RESEND 2/2] mtd: Fix the behavior of otp write if there is not enough room for data

2014-03-05 Thread Christian Riesch

Hi Brian,
Thank you very much for your comments on the patch!

--On March 04, 2014 23:20 -0800 Brian Norris computersforpe...@gmail.com 
wrote:



Hi Christian,

A few comments below.

On Tue, Jan 28, 2014 at 09:29:45AM +0100, Christian Riesch wrote:

An OTP write shall write as much data as possible to the OTP memory
and return the number of bytes that have actually been written.
If no data could be written at all due to lack of OTP memory,
return -ENOSPC.

Signed-off-by: Christian Riesch christian.rie...@omicron.at
Cc: Artem Bityutskiy artem.bityuts...@linux.intel.com
Cc: Kyungmin Park kyungmin.p...@samsung.com
Cc: Amul Kumar Saha amul.s...@samsung.com
---
 drivers/mtd/chips/cfi_cmdset_0001.c |   13 +++--
 drivers/mtd/devices/mtd_dataflash.c |   13 +
 drivers/mtd/mtdchar.c   |7 +++
 drivers/mtd/onenand/onenand_base.c  |   10 +-
 4 files changed, 32 insertions(+), 11 deletions(-)

diff --git a/drivers/mtd/chips/cfi_cmdset_0001.c
b/drivers/mtd/chips/cfi_cmdset_0001.c index 7aa581f..cf423a6 100644
--- a/drivers/mtd/chips/cfi_cmdset_0001.c
+++ b/drivers/mtd/chips/cfi_cmdset_0001.c
@@ -2387,8 +2387,17 @@ static int
cfi_intelext_write_user_prot_reg(struct mtd_info *mtd, loff_t from,
size_t len, size_t *retlen,
 u_char *buf)
 {
-   return cfi_intelext_otp_walk(mtd, from, len, retlen,
-buf, do_otp_write, 1);
+   int ret;
+
+   ret = cfi_intelext_otp_walk(mtd, from, len, retlen,
+   buf, do_otp_write, 1);
+
+   /* if no data could be written due to lack of OTP memory,
+  return ENOSPC */


/*
 * Can you use this style of mult-line comments please?
 * It's in Documentation/CodingStyle
 */



Ok, I will change that.


+   if (!ret  len  !(*retlen))
+   return -ENOSPC;


Couldn't (shouldn't) this check be pushed to the common
mtd_write_user_prot_reg() helper in mtdcore.c?


Yes, I don't see why this wouldn't work. But I thought the code would be 
easier to understand if we return the correct error code as soon as the 
error is detected, not using some additional logic in some other function. 
What do you think?



And once you do that, you
will see that cfi_intelext_write_user_prot_reg() (and other
mtd-_write_user_prot_reg() implementations) will never be called with
len == 0. So this just becomes (in mtdcore.c):

diff --git a/drivers/mtd/mtdcore.c b/drivers/mtd/mtdcore.c
index 0a7d77e65335..ee6730748f7e 100644
--- a/drivers/mtd/mtdcore.c
+++ b/drivers/mtd/mtdcore.c
@@ -909,11 +909,16 @@ EXPORT_SYMBOL_GPL(mtd_read_fact_prot_reg);
 int mtd_get_user_prot_info(struct mtd_info *mtd, size_t len, size_t
*retlen,   struct otp_info *buf)
 {
+   int ret;
+
if (!mtd-_get_user_prot_info)
return -EOPNOTSUPP;
if (!len)
return 0;
-   return mtd-_get_user_prot_info(mtd, len, retlen, buf);
+   ret = mtd-_get_user_prot_info(mtd, len, retlen, buf);
+   if (ret)
+   return ret;
+   return !(*retlen) ? -ENOSPC: 0;
 }
 EXPORT_SYMBOL_GPL(mtd_get_user_prot_info);



+
+   return ret;
 }

 static int cfi_intelext_lock_user_prot_reg(struct mtd_info *mtd,
diff --git a/drivers/mtd/devices/mtd_dataflash.c
b/drivers/mtd/devices/mtd_dataflash.c index 09c69ce..5236d85 100644
--- a/drivers/mtd/devices/mtd_dataflash.c
+++ b/drivers/mtd/devices/mtd_dataflash.c
@@ -545,14 +545,11 @@ static int dataflash_write_user_otp(struct
mtd_info *mtd, struct dataflash *priv = mtd-priv;
int status;



I'm not sure I quite follow the logic for the following hunk. I think it
deserves some more explanation, either in your commit or in a comment.
As it stands, you're deleting a comment and potentially changing the
return code behavior subtly.


-   if (len  64)
-   return -EINVAL;
-
-   /* Strictly speaking, we *could* truncate the write ... but
-* let's not do that for the only write that's ever possible.
-*/
-   if ((from + len)  64)
-   return -EINVAL;
+   if ((from + len)  64) {
+   len = 64 - from;


Why are you reassigning len? Are you trying to undo the comment above,
so that you *can* truncate the write? (It looks like there are other
implmentations which will truncate the write and return -ENOSPC, FWIW.)


Currently we have two kind of implementations: We have implementations like 
this one which will refuse to write any data if the write requests more 
data to be written than space is available. And we have implementations 
like cfi_intelext_write_user_prot_reg that will truncate the write and 
write as much data that is possible (and return the number of bytes that 
actually have been written, -ENOSPC shall only be returned if no data could 
be written at all).


For a harmonization one of the implementations

Re: Fwd: Ethernet controller not starting

2014-03-04 Thread Christian Riesch

Hi Jon,

[Now also cc'ed Prabhakar Lad]

--On March 04, 2014 07:34 -0500 Jon Ringle  wrote:


On Tue, Mar 4, 2014 at 4:06 AM, Christian Riesch
 wrote:

[cc'ed netdev and davinci-linux-open-source]


--On March 03, 2014 19:39 -0500 Jon Ringle  wrote:


On Mon, Mar 3, 2014 at 6:43 PM, Rafael J. Wysocki 
wrote:


On Monday, March 03, 2014 02:41:01 PM Jon Ringle wrote:


I'm working on porting an ARM board from linux-3.10 to linux-3.12 (now
the latest LTS kernel).
I found that Ethernet controller on the board no longer comes up on
linux-3.12. I was able to bisect the issue I'm having to the following
commit:

>   45f0a85c8258741d11bda25c0a5669c06267204a is the first bad commit
>   commit 45f0a85c8258741d11bda25c0a5669c06267204a
>   Author: Rafael J. Wysocki 
>   Date:   Mon Jun 3 21:49:52 2013 +0200
>

[...]


Can anyone offer any suggestions on what I should be looking for to
fix this on my board?



Any pointers to the driver in question?



drivers/net/ethernet/ti/davinci_emac.c



Hi Jon,
I have successfully used the davinci_emac driver on a custom board with
an AM1808 SoC with Kernel 3.13 a few weeks ago. So at least 3.13 should
work. Did you try more recent kernel versions than 3.12?


I have not tried 3.13, but will do so today. Could I get a copy of
your .config for comparison purposes?



I would like to apologize, apparently my testing with 3.13 was quite bad. 
Ethernet comes up on my board and works fine after booting, but I can 
easily reproduce your problem by just doing ifconfig eth0 down /ifconfig 
eth0 up (which should call emac_dev_stop/emac_dev_open).


# ifconfig eth0 up
genirq: Flags mismatch irq 33. .

So probably one of your start scripts (or dhcp or similar) does some 
ifconfig down/up, which then fails.


I had a look at the code again, emac_dev_open requests the interrupts, 
whereas emac_dev_stop does not free them. If emac_dev_open is then called 
again by ifconfig eth0 up, it tries to request the interrupts again, 
resulting in the error above.


I think the problem is a regression caused by

Commit  6892b41d9701283085b655c6086fb57a5d63fa47
net: davinci: emac: Convert to devm_* api
Signed-off-by: Lad, Prabhakar 

This patch replaces request_irq() by devm_request_irq() in emac_dev_open 
and removes free_irq() from emac_dev_stop. But since emac_dev_open is 
called every time we do an ifconfig eth0 up, it tries to request the 
interrupts again and again and again (and fails).


So I guess the correct solution would be to move the calls of 
devm_request_irq() to davinci_emac_probe(). I will send a patch to netdev, 
it solves the problem on my board.


Christian










--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH v2 RESEND 0/2] mtd: Harmonize implementations of OTP write and _get_{fact, user}_prot_info

2014-03-04 Thread Christian Riesch

Hi,

--On January 28, 2014 09:29 +0100 Christian Riesch 
 wrote:



Hi all,

In the discussion on my patchset for the OTP support for
drivers/mtd/chips/cfi_cmdset_0002.c [1-5], Artem requested two changes in
the current code of the OTP write functions and the
_get_{fact,user}_prot_info code.

These two patches are an attempt to make the requested changes.

The first patch adds a retlen parameter to the _get_fact_prot_info and
_get_user_prot_info functions and thus harmonizes the implementation
with those of the write and read functions.

The second patch fixes a problem that I earlier addressed in [1]. After
the discussion about this patch on the mtd mailing list, I think that the
correct behavior of the write function should be the one specified in [6]:
Try to write as many bytes as possible and return the number of bytes
that were written. If no data could be written due to lack of OTP memory,
return -ENOSPC.

Artem, would you please have a look at these patches? I would like to know
if I understood you correctly, or if I missed something here. Please note
that I cannot test these patches since I do not have the hardware. The
patches are compile tested only. If these patches are ok, I will also
respin the OTP support patches for cfi_cmdset_0002.



Sorry for bugging you (Artem, mtd Maintainers) again, but I would really 
like to get this patchset ([a], [b]) and the OTP support for 
cfi_cmdset_0002.c into mainline. Please have a look at the patches and just 
tell me if the changes in them are acceptable, or if I should rather post 
the OTP support without these two patches. Once I have your answer, I will 
respin these patches and my OTP patches, test them again, and submit them. 
But without your help I cannot continue.


[a] http://patchwork.ozlabs.org/patch/314624/
[b] http://patchwork.ozlabs.org/patch/314625/

Thank you very much!

Christian


Changes for v2:
- Fixed buggy cfi_intelext_get_fact_prot_info

Thank you!

Best regards,
Christian

[1] http://patchwork.ozlabs.org/patch/239897/
[2] http://patchwork.ozlabs.org/patch/240010/
[3] http://patchwork.ozlabs.org/patch/240007/
[4] http://patchwork.ozlabs.org/patch/240008/
[5] http://patchwork.ozlabs.org/patch/240009/
[6] http://pubs.opengroup.org/onlinepubs/9699919799/functions/write.html

Cc: Artem Bityutskiy 
Cc: Kyungmin Park 
Cc: Amul Kumar Saha 
Cc: Brian Norris 

Christian Riesch (2):
  mtd: Add a retlen parameter to _get_{fact,user}_prot_info
  mtd: Fix the behavior of otp write if there is not enough room for
data

 drivers/mtd/chips/cfi_cmdset_0001.c |   44
+++  drivers/mtd/devices/mtd_dataflash.c
|   20 +++-
 drivers/mtd/mtdchar.c   |   18 ++
 drivers/mtd/mtdcore.c   |   12 +-
 drivers/mtd/mtdpart.c   |   14 ++-
 drivers/mtd/onenand/onenand_base.c  |   40
---  include/linux/mtd/mtd.h |
16 ++---
 7 files changed, 89 insertions(+), 75 deletions(-)

--
1.7.9.5


__
Linux MTD discussion mailing list
http://lists.infradead.org/mailman/listinfo/linux-mtd/





--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: Ethernet controller not starting

2014-03-04 Thread Christian Riesch

[cc'ed netdev and davinci-linux-open-source]

--On March 03, 2014 19:39 -0500 Jon Ringle  wrote:


On Mon, Mar 3, 2014 at 6:43 PM, Rafael J. Wysocki 
wrote:

On Monday, March 03, 2014 02:41:01 PM Jon Ringle wrote:

I'm working on porting an ARM board from linux-3.10 to linux-3.12 (now
the latest LTS kernel).
I found that Ethernet controller on the board no longer comes up on
linux-3.12. I was able to bisect the issue I'm having to the following
commit:

>   45f0a85c8258741d11bda25c0a5669c06267204a is the first bad commit
>   commit 45f0a85c8258741d11bda25c0a5669c06267204a
>   Author: Rafael J. Wysocki 
>   Date:   Mon Jun 3 21:49:52 2013 +0200
>
>   PM / Runtime: Rework the "runtime idle" helper routine
>
>   The "runtime idle" helper routine, rpm_idle(), currently ignores
>   return values from .runtime_idle() callbacks executed by it.
>   However, it turns out that many subsystems use
>   pm_generic_runtime_idle() which checks the return value of the
>   driver's callback and executes pm_runtime_suspend() for the
>   device unless that value is not 0.  If that logic is moved to
>   rpm_idle() instead, pm_generic_runtime_idle() can be dropped
>   and its users will not need any .runtime_idle() callbacks any
>   more.
>
>   Moreover, the PCI, SCSI, and SATA subsystems' .runtime_idle()
>   routines, pci_pm_runtime_idle(), scsi_runtime_idle(), and
>   ata_port_runtime_idle(), respectively, as well as a few drivers'
>   ones may be simplified if rpm_idle() calls rpm_suspend() after
>   0 has been returned by the .runtime_idle() callback executed by
>   it.
>
>   To reduce overall code bloat, make the changes described above.
>
>   Tested-by: Mika Westerberg 
>   Tested-by: Kevin Hilman 
>   Signed-off-by: Rafael J. Wysocki 
>   Acked-by: Kevin Hilman 
>   Reviewed-by: Ulf Hansson 
>   Acked-by: Alan Stern 

Can anyone offer any suggestions on what I should be looking for to
fix this on my board?


Any pointers to the driver in question?


drivers/net/ethernet/ti/davinci_emac.c



Hi Jon,
I have successfully used the davinci_emac driver on a custom board with an 
AM1808 SoC with Kernel 3.13 a few weeks ago. So at least 3.13 should work. 
Did you try more recent kernel versions than 3.12?



I also get the following output:

 Starting Network Manager Wait Online...
[   30.946509] davinci_mdio davinci_mdio.0: resetting idled controller
[   30.953220] net net0: attached PHY driver [Generic PHY]
(mii_bus:phy_addr=davinci_mdio-0:00, id=7c0f1)
[   30.962938] IPv6: ADDRCONF(NETDEV_UP): net0: link is not ready
[   31.082087] genirq: Flags mismatch irq 33.  (net0) vs.
 (net0)


Is it correct that this warning can only appear in case of shared 
interrupts? See kernel/irq/manage.c. Since we don't use shared interrupts 
here: Are you sure your board configuration is correct with regard to emac 
interrupts? Is your configuration using device tree or not (my 
configuration is a none-devicetree one)? I also wonder why your network 
device is net0, on my board it's eth0, maybe this triggers some bug?


Christian



--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: Ethernet controller not starting

2014-03-04 Thread Christian Riesch

[cc'ed netdev and davinci-linux-open-source]

--On March 03, 2014 19:39 -0500 Jon Ringle j...@ringle.org wrote:


On Mon, Mar 3, 2014 at 6:43 PM, Rafael J. Wysocki r...@rjwysocki.net
wrote:

On Monday, March 03, 2014 02:41:01 PM Jon Ringle wrote:

I'm working on porting an ARM board from linux-3.10 to linux-3.12 (now
the latest LTS kernel).
I found that Ethernet controller on the board no longer comes up on
linux-3.12. I was able to bisect the issue I'm having to the following
commit:

   45f0a85c8258741d11bda25c0a5669c06267204a is the first bad commit
   commit 45f0a85c8258741d11bda25c0a5669c06267204a
   Author: Rafael J. Wysocki rafael.j.wyso...@intel.com
   Date:   Mon Jun 3 21:49:52 2013 +0200

   PM / Runtime: Rework the runtime idle helper routine

   The runtime idle helper routine, rpm_idle(), currently ignores
   return values from .runtime_idle() callbacks executed by it.
   However, it turns out that many subsystems use
   pm_generic_runtime_idle() which checks the return value of the
   driver's callback and executes pm_runtime_suspend() for the
   device unless that value is not 0.  If that logic is moved to
   rpm_idle() instead, pm_generic_runtime_idle() can be dropped
   and its users will not need any .runtime_idle() callbacks any
   more.

   Moreover, the PCI, SCSI, and SATA subsystems' .runtime_idle()
   routines, pci_pm_runtime_idle(), scsi_runtime_idle(), and
   ata_port_runtime_idle(), respectively, as well as a few drivers'
   ones may be simplified if rpm_idle() calls rpm_suspend() after
   0 has been returned by the .runtime_idle() callback executed by
   it.

   To reduce overall code bloat, make the changes described above.

   Tested-by: Mika Westerberg mika.westerb...@linux.intel.com
   Tested-by: Kevin Hilman khil...@linaro.org
   Signed-off-by: Rafael J. Wysocki rafael.j.wyso...@intel.com
   Acked-by: Kevin Hilman khil...@linaro.org
   Reviewed-by: Ulf Hansson ulf.hans...@linaro.org
   Acked-by: Alan Stern st...@rowland.harvard.edu

Can anyone offer any suggestions on what I should be looking for to
fix this on my board?


Any pointers to the driver in question?


drivers/net/ethernet/ti/davinci_emac.c



Hi Jon,
I have successfully used the davinci_emac driver on a custom board with an 
AM1808 SoC with Kernel 3.13 a few weeks ago. So at least 3.13 should work. 
Did you try more recent kernel versions than 3.12?



I also get the following output:

 Starting Network Manager Wait Online...
[   30.946509] davinci_mdio davinci_mdio.0: resetting idled controller
[   30.953220] net net0: attached PHY driver [Generic PHY]
(mii_bus:phy_addr=davinci_mdio-0:00, id=7c0f1)
[   30.962938] IPv6: ADDRCONF(NETDEV_UP): net0: link is not ready
[   31.082087] genirq: Flags mismatch irq 33.  (net0) vs.
 (net0)


Is it correct that this warning can only appear in case of shared 
interrupts? See kernel/irq/manage.c. Since we don't use shared interrupts 
here: Are you sure your board configuration is correct with regard to emac 
interrupts? Is your configuration using device tree or not (my 
configuration is a none-devicetree one)? I also wonder why your network 
device is net0, on my board it's eth0, maybe this triggers some bug?


Christian



--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH v2 RESEND 0/2] mtd: Harmonize implementations of OTP write and _get_{fact, user}_prot_info

2014-03-04 Thread Christian Riesch

Hi,

--On January 28, 2014 09:29 +0100 Christian Riesch 
christian.rie...@omicron.at wrote:



Hi all,

In the discussion on my patchset for the OTP support for
drivers/mtd/chips/cfi_cmdset_0002.c [1-5], Artem requested two changes in
the current code of the OTP write functions and the
_get_{fact,user}_prot_info code.

These two patches are an attempt to make the requested changes.

The first patch adds a retlen parameter to the _get_fact_prot_info and
_get_user_prot_info functions and thus harmonizes the implementation
with those of the write and read functions.

The second patch fixes a problem that I earlier addressed in [1]. After
the discussion about this patch on the mtd mailing list, I think that the
correct behavior of the write function should be the one specified in [6]:
Try to write as many bytes as possible and return the number of bytes
that were written. If no data could be written due to lack of OTP memory,
return -ENOSPC.

Artem, would you please have a look at these patches? I would like to know
if I understood you correctly, or if I missed something here. Please note
that I cannot test these patches since I do not have the hardware. The
patches are compile tested only. If these patches are ok, I will also
respin the OTP support patches for cfi_cmdset_0002.



Sorry for bugging you (Artem, mtd Maintainers) again, but I would really 
like to get this patchset ([a], [b]) and the OTP support for 
cfi_cmdset_0002.c into mainline. Please have a look at the patches and just 
tell me if the changes in them are acceptable, or if I should rather post 
the OTP support without these two patches. Once I have your answer, I will 
respin these patches and my OTP patches, test them again, and submit them. 
But without your help I cannot continue.


[a] http://patchwork.ozlabs.org/patch/314624/
[b] http://patchwork.ozlabs.org/patch/314625/

Thank you very much!

Christian


Changes for v2:
- Fixed buggy cfi_intelext_get_fact_prot_info

Thank you!

Best regards,
Christian

[1] http://patchwork.ozlabs.org/patch/239897/
[2] http://patchwork.ozlabs.org/patch/240010/
[3] http://patchwork.ozlabs.org/patch/240007/
[4] http://patchwork.ozlabs.org/patch/240008/
[5] http://patchwork.ozlabs.org/patch/240009/
[6] http://pubs.opengroup.org/onlinepubs/9699919799/functions/write.html

Cc: Artem Bityutskiy artem.bityuts...@linux.intel.com
Cc: Kyungmin Park kyungmin.p...@samsung.com
Cc: Amul Kumar Saha amul.s...@samsung.com
Cc: Brian Norris computersforpe...@gmail.com

Christian Riesch (2):
  mtd: Add a retlen parameter to _get_{fact,user}_prot_info
  mtd: Fix the behavior of otp write if there is not enough room for
data

 drivers/mtd/chips/cfi_cmdset_0001.c |   44
+++  drivers/mtd/devices/mtd_dataflash.c
|   20 +++-
 drivers/mtd/mtdchar.c   |   18 ++
 drivers/mtd/mtdcore.c   |   12 +-
 drivers/mtd/mtdpart.c   |   14 ++-
 drivers/mtd/onenand/onenand_base.c  |   40
---  include/linux/mtd/mtd.h |
16 ++---
 7 files changed, 89 insertions(+), 75 deletions(-)

--
1.7.9.5


__
Linux MTD discussion mailing list
http://lists.infradead.org/mailman/listinfo/linux-mtd/





--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: Fwd: Ethernet controller not starting

2014-03-04 Thread Christian Riesch

Hi Jon,

[Now also cc'ed Prabhakar Lad]

--On March 04, 2014 07:34 -0500 Jon Ringle j...@ringle.org wrote:


On Tue, Mar 4, 2014 at 4:06 AM, Christian Riesch
christian.rie...@omicron.at wrote:

[cc'ed netdev and davinci-linux-open-source]


--On March 03, 2014 19:39 -0500 Jon Ringle j...@ringle.org wrote:


On Mon, Mar 3, 2014 at 6:43 PM, Rafael J. Wysocki r...@rjwysocki.net
wrote:


On Monday, March 03, 2014 02:41:01 PM Jon Ringle wrote:


I'm working on porting an ARM board from linux-3.10 to linux-3.12 (now
the latest LTS kernel).
I found that Ethernet controller on the board no longer comes up on
linux-3.12. I was able to bisect the issue I'm having to the following
commit:

   45f0a85c8258741d11bda25c0a5669c06267204a is the first bad commit
   commit 45f0a85c8258741d11bda25c0a5669c06267204a
   Author: Rafael J. Wysocki rafael.j.wyso...@intel.com
   Date:   Mon Jun 3 21:49:52 2013 +0200


[...]


Can anyone offer any suggestions on what I should be looking for to
fix this on my board?



Any pointers to the driver in question?



drivers/net/ethernet/ti/davinci_emac.c



Hi Jon,
I have successfully used the davinci_emac driver on a custom board with
an AM1808 SoC with Kernel 3.13 a few weeks ago. So at least 3.13 should
work. Did you try more recent kernel versions than 3.12?


I have not tried 3.13, but will do so today. Could I get a copy of
your .config for comparison purposes?



I would like to apologize, apparently my testing with 3.13 was quite bad. 
Ethernet comes up on my board and works fine after booting, but I can 
easily reproduce your problem by just doing ifconfig eth0 down /ifconfig 
eth0 up (which should call emac_dev_stop/emac_dev_open).


# ifconfig eth0 up
genirq: Flags mismatch irq 33. .

So probably one of your start scripts (or dhcp or similar) does some 
ifconfig down/up, which then fails.


I had a look at the code again, emac_dev_open requests the interrupts, 
whereas emac_dev_stop does not free them. If emac_dev_open is then called 
again by ifconfig eth0 up, it tries to request the interrupts again, 
resulting in the error above.


I think the problem is a regression caused by

Commit  6892b41d9701283085b655c6086fb57a5d63fa47
net: davinci: emac: Convert to devm_* api
Signed-off-by: Lad, Prabhakar prabhakar.cse...@gmail.com

This patch replaces request_irq() by devm_request_irq() in emac_dev_open 
and removes free_irq() from emac_dev_stop. But since emac_dev_open is 
called every time we do an ifconfig eth0 up, it tries to request the 
interrupts again and again and again (and fails).


So I guess the correct solution would be to move the calls of 
devm_request_irq() to davinci_emac_probe(). I will send a patch to netdev, 
it solves the problem on my board.


Christian










--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH v2 RESEND 1/2] mtd: Add a retlen parameter to _get_{fact,user}_prot_info

2014-01-28 Thread Christian Riesch
Signed-off-by: Christian Riesch 
Cc: Artem Bityutskiy 
Cc: Brian Norris 
---
 drivers/mtd/chips/cfi_cmdset_0001.c |   31 +--
 drivers/mtd/devices/mtd_dataflash.c |7 ---
 drivers/mtd/mtdchar.c   |   11 ++-
 drivers/mtd/mtdcore.c   |   12 ++--
 drivers/mtd/mtdpart.c   |   14 --
 drivers/mtd/onenand/onenand_base.c  |   30 --
 include/linux/mtd/mtd.h |   16 
 7 files changed, 57 insertions(+), 64 deletions(-)

diff --git a/drivers/mtd/chips/cfi_cmdset_0001.c 
b/drivers/mtd/chips/cfi_cmdset_0001.c
index 7751443..7aa581f 100644
--- a/drivers/mtd/chips/cfi_cmdset_0001.c
+++ b/drivers/mtd/chips/cfi_cmdset_0001.c
@@ -69,10 +69,10 @@ static int cfi_intelext_read_fact_prot_reg (struct mtd_info 
*, loff_t, size_t, s
 static int cfi_intelext_read_user_prot_reg (struct mtd_info *, loff_t, size_t, 
size_t *, u_char *);
 static int cfi_intelext_write_user_prot_reg (struct mtd_info *, loff_t, 
size_t, size_t *, u_char *);
 static int cfi_intelext_lock_user_prot_reg (struct mtd_info *, loff_t, size_t);
-static int cfi_intelext_get_fact_prot_info (struct mtd_info *,
-   struct otp_info *, size_t);
-static int cfi_intelext_get_user_prot_info (struct mtd_info *,
-   struct otp_info *, size_t);
+static int cfi_intelext_get_fact_prot_info(struct mtd_info *, size_t,
+  size_t *, struct otp_info *);
+static int cfi_intelext_get_user_prot_info(struct mtd_info *, size_t,
+  size_t *, struct otp_info *);
 #endif
 static int cfi_intelext_suspend (struct mtd_info *);
 static void cfi_intelext_resume (struct mtd_info *);
@@ -2399,24 +2399,19 @@ static int cfi_intelext_lock_user_prot_reg(struct 
mtd_info *mtd,
 NULL, do_otp_lock, 1);
 }
 
-static int cfi_intelext_get_fact_prot_info(struct mtd_info *mtd,
-  struct otp_info *buf, size_t len)
-{
-   size_t retlen;
-   int ret;
+static int cfi_intelext_get_fact_prot_info(struct mtd_info *mtd, size_t len,
+  size_t *retlen, struct otp_info *buf)
 
-   ret = cfi_intelext_otp_walk(mtd, 0, len, , (u_char *)buf, NULL, 
0);
-   return ret ? : retlen;
+{
+   return cfi_intelext_otp_walk(mtd, 0, len, retlen, (u_char *)buf,
+NULL, 0);
 }
 
-static int cfi_intelext_get_user_prot_info(struct mtd_info *mtd,
-  struct otp_info *buf, size_t len)
+static int cfi_intelext_get_user_prot_info(struct mtd_info *mtd, size_t len,
+  size_t *retlen, struct otp_info *buf)
 {
-   size_t retlen;
-   int ret;
-
-   ret = cfi_intelext_otp_walk(mtd, 0, len, , (u_char *)buf, NULL, 
1);
-   return ret ? : retlen;
+   return cfi_intelext_otp_walk(mtd, 0, len, retlen, (u_char *)buf,
+NULL, 1);
 }
 
 #endif
diff --git a/drivers/mtd/devices/mtd_dataflash.c 
b/drivers/mtd/devices/mtd_dataflash.c
index 28779b6..09c69ce 100644
--- a/drivers/mtd/devices/mtd_dataflash.c
+++ b/drivers/mtd/devices/mtd_dataflash.c
@@ -442,8 +442,8 @@ static int dataflash_write(struct mtd_info *mtd, loff_t to, 
size_t len,
 
 #ifdef CONFIG_MTD_DATAFLASH_OTP
 
-static int dataflash_get_otp_info(struct mtd_info *mtd,
-   struct otp_info *info, size_t len)
+static int dataflash_get_otp_info(struct mtd_info *mtd, size_t len,
+ size_t *retlen, struct otp_info *info)
 {
/* Report both blocks as identical:  bytes 0..64, locked.
 * Unless the user block changed from all-ones, we can't
@@ -452,7 +452,8 @@ static int dataflash_get_otp_info(struct mtd_info *mtd,
info->start = 0;
info->length = 64;
info->locked = 1;
-   return sizeof(*info);
+   *retlen = sizeof(*info);
+   return 0;
 }
 
 static ssize_t otp_read(struct spi_device *spi, unsigned base,
diff --git a/drivers/mtd/mtdchar.c b/drivers/mtd/mtdchar.c
index 684bfa3..0edb0ca 100644
--- a/drivers/mtd/mtdchar.c
+++ b/drivers/mtd/mtdchar.c
@@ -888,25 +888,26 @@ static int mtdchar_ioctl(struct file *file, u_int cmd, 
u_long arg)
case OTPGETREGIONINFO:
{
struct otp_info *buf = kmalloc(4096, GFP_KERNEL);
+   size_t retlen;
if (!buf)
return -ENOMEM;
switch (mfi->mode) {
case MTD_FILE_MODE_OTP_FACTORY:
-   ret = mtd_get_fact_prot_info(mtd, buf, 4096);
+   ret = mtd_get_fact_prot_info(mtd, 4096, , buf);
break;
case MTD_FILE_MODE_OTP_USER:
-   ret = mtd_get_user_prot_info(mt

[PATCH v2 RESEND 2/2] mtd: Fix the behavior of otp write if there is not enough room for data

2014-01-28 Thread Christian Riesch
An OTP write shall write as much data as possible to the OTP memory
and return the number of bytes that have actually been written.
If no data could be written at all due to lack of OTP memory,
return -ENOSPC.

Signed-off-by: Christian Riesch 
Cc: Artem Bityutskiy 
Cc: Kyungmin Park 
Cc: Amul Kumar Saha 
---
 drivers/mtd/chips/cfi_cmdset_0001.c |   13 +++--
 drivers/mtd/devices/mtd_dataflash.c |   13 +
 drivers/mtd/mtdchar.c   |7 +++
 drivers/mtd/onenand/onenand_base.c  |   10 +-
 4 files changed, 32 insertions(+), 11 deletions(-)

diff --git a/drivers/mtd/chips/cfi_cmdset_0001.c 
b/drivers/mtd/chips/cfi_cmdset_0001.c
index 7aa581f..cf423a6 100644
--- a/drivers/mtd/chips/cfi_cmdset_0001.c
+++ b/drivers/mtd/chips/cfi_cmdset_0001.c
@@ -2387,8 +2387,17 @@ static int cfi_intelext_write_user_prot_reg(struct 
mtd_info *mtd, loff_t from,
size_t len, size_t *retlen,
 u_char *buf)
 {
-   return cfi_intelext_otp_walk(mtd, from, len, retlen,
-buf, do_otp_write, 1);
+   int ret;
+
+   ret = cfi_intelext_otp_walk(mtd, from, len, retlen,
+   buf, do_otp_write, 1);
+
+   /* if no data could be written due to lack of OTP memory,
+  return ENOSPC */
+   if (!ret && len && !(*retlen))
+   return -ENOSPC;
+
+   return ret;
 }
 
 static int cfi_intelext_lock_user_prot_reg(struct mtd_info *mtd,
diff --git a/drivers/mtd/devices/mtd_dataflash.c 
b/drivers/mtd/devices/mtd_dataflash.c
index 09c69ce..5236d85 100644
--- a/drivers/mtd/devices/mtd_dataflash.c
+++ b/drivers/mtd/devices/mtd_dataflash.c
@@ -545,14 +545,11 @@ static int dataflash_write_user_otp(struct mtd_info *mtd,
struct dataflash*priv = mtd->priv;
int status;
 
-   if (len > 64)
-   return -EINVAL;
-
-   /* Strictly speaking, we *could* truncate the write ... but
-* let's not do that for the only write that's ever possible.
-*/
-   if ((from + len) > 64)
-   return -EINVAL;
+   if ((from + len) > 64) {
+   len = 64 - from;
+   if (len <= 0)
+   return -ENOSPC;
+   }
 
/* OUT: OP_WRITE_SECURITY, 3 zeroes, 64 data-or-zero bytes
 * IN:  ignore all
diff --git a/drivers/mtd/mtdchar.c b/drivers/mtd/mtdchar.c
index 0edb0ca..db99031 100644
--- a/drivers/mtd/mtdchar.c
+++ b/drivers/mtd/mtdchar.c
@@ -323,6 +323,13 @@ static ssize_t mtdchar_write(struct file *file, const char 
__user *buf, size_t c
default:
ret = mtd_write(mtd, *ppos, len, , kbuf);
}
+   /* return -ENOSPC only if no data was written */
+   if ((ret == -ENOSPC) && (total_retlen)) {
+   ret = 0;
+   retlen = 0;
+   /* drop the remaining data */
+   count = 0;
+   }
if (!ret) {
*ppos += retlen;
total_retlen += retlen;
diff --git a/drivers/mtd/onenand/onenand_base.c 
b/drivers/mtd/onenand/onenand_base.c
index 419c538..6c49a6f 100644
--- a/drivers/mtd/onenand/onenand_base.c
+++ b/drivers/mtd/onenand/onenand_base.c
@@ -3316,7 +3316,15 @@ static int onenand_read_user_prot_reg(struct mtd_info 
*mtd, loff_t from,
 static int onenand_write_user_prot_reg(struct mtd_info *mtd, loff_t from,
size_t len, size_t *retlen, u_char *buf)
 {
-   return onenand_otp_walk(mtd, from, len, retlen, buf, do_otp_write, 
MTD_OTP_USER);
+   int ret;
+   ret = onenand_otp_walk(mtd, from, len, retlen, buf, do_otp_write, 
MTD_OTP_USER);
+
+   /* if no data could be written due to lack of OTP memory,
+  return ENOSPC */
+   if (!ret && len && !(*retlen))
+   return -ENOSPC;
+
+   return ret;
 }
 
 /**
-- 
1.7.9.5

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH v2 RESEND 0/2] mtd: Harmonize implementations of OTP write and _get_{fact,user}_prot_info

2014-01-28 Thread Christian Riesch
Hi all,

In the discussion on my patchset for the OTP support for
drivers/mtd/chips/cfi_cmdset_0002.c [1-5], Artem requested two changes in the
current code of the OTP write functions and the _get_{fact,user}_prot_info
code.

These two patches are an attempt to make the requested changes.

The first patch adds a retlen parameter to the _get_fact_prot_info and
_get_user_prot_info functions and thus harmonizes the implementation
with those of the write and read functions.

The second patch fixes a problem that I earlier addressed in [1]. After
the discussion about this patch on the mtd mailing list, I think that the
correct behavior of the write function should be the one specified in [6]:
Try to write as many bytes as possible and return the number of bytes
that were written. If no data could be written due to lack of OTP memory,
return -ENOSPC.

Artem, would you please have a look at these patches? I would like to know
if I understood you correctly, or if I missed something here. Please note
that I cannot test these patches since I do not have the hardware. The
patches are compile tested only. If these patches are ok, I will also
respin the OTP support patches for cfi_cmdset_0002.

Changes for v2:
- Fixed buggy cfi_intelext_get_fact_prot_info

Thank you!

Best regards,
Christian

[1] http://patchwork.ozlabs.org/patch/239897/
[2] http://patchwork.ozlabs.org/patch/240010/
[3] http://patchwork.ozlabs.org/patch/240007/
[4] http://patchwork.ozlabs.org/patch/240008/
[5] http://patchwork.ozlabs.org/patch/240009/
[6] http://pubs.opengroup.org/onlinepubs/9699919799/functions/write.html

Cc: Artem Bityutskiy 
Cc: Kyungmin Park 
Cc: Amul Kumar Saha 
Cc: Brian Norris 

Christian Riesch (2):
  mtd: Add a retlen parameter to _get_{fact,user}_prot_info
  mtd: Fix the behavior of otp write if there is not enough room for
data

 drivers/mtd/chips/cfi_cmdset_0001.c |   44 +++
 drivers/mtd/devices/mtd_dataflash.c |   20 +++-
 drivers/mtd/mtdchar.c   |   18 ++
 drivers/mtd/mtdcore.c   |   12 +-
 drivers/mtd/mtdpart.c   |   14 ++-
 drivers/mtd/onenand/onenand_base.c  |   40 ---
 include/linux/mtd/mtd.h |   16 ++---
 7 files changed, 89 insertions(+), 75 deletions(-)

-- 
1.7.9.5

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH v2 RESEND 2/2] mtd: Fix the behavior of otp write if there is not enough room for data

2014-01-28 Thread Christian Riesch
An OTP write shall write as much data as possible to the OTP memory
and return the number of bytes that have actually been written.
If no data could be written at all due to lack of OTP memory,
return -ENOSPC.

Signed-off-by: Christian Riesch christian.rie...@omicron.at
Cc: Artem Bityutskiy artem.bityuts...@linux.intel.com
Cc: Kyungmin Park kyungmin.p...@samsung.com
Cc: Amul Kumar Saha amul.s...@samsung.com
---
 drivers/mtd/chips/cfi_cmdset_0001.c |   13 +++--
 drivers/mtd/devices/mtd_dataflash.c |   13 +
 drivers/mtd/mtdchar.c   |7 +++
 drivers/mtd/onenand/onenand_base.c  |   10 +-
 4 files changed, 32 insertions(+), 11 deletions(-)

diff --git a/drivers/mtd/chips/cfi_cmdset_0001.c 
b/drivers/mtd/chips/cfi_cmdset_0001.c
index 7aa581f..cf423a6 100644
--- a/drivers/mtd/chips/cfi_cmdset_0001.c
+++ b/drivers/mtd/chips/cfi_cmdset_0001.c
@@ -2387,8 +2387,17 @@ static int cfi_intelext_write_user_prot_reg(struct 
mtd_info *mtd, loff_t from,
size_t len, size_t *retlen,
 u_char *buf)
 {
-   return cfi_intelext_otp_walk(mtd, from, len, retlen,
-buf, do_otp_write, 1);
+   int ret;
+
+   ret = cfi_intelext_otp_walk(mtd, from, len, retlen,
+   buf, do_otp_write, 1);
+
+   /* if no data could be written due to lack of OTP memory,
+  return ENOSPC */
+   if (!ret  len  !(*retlen))
+   return -ENOSPC;
+
+   return ret;
 }
 
 static int cfi_intelext_lock_user_prot_reg(struct mtd_info *mtd,
diff --git a/drivers/mtd/devices/mtd_dataflash.c 
b/drivers/mtd/devices/mtd_dataflash.c
index 09c69ce..5236d85 100644
--- a/drivers/mtd/devices/mtd_dataflash.c
+++ b/drivers/mtd/devices/mtd_dataflash.c
@@ -545,14 +545,11 @@ static int dataflash_write_user_otp(struct mtd_info *mtd,
struct dataflash*priv = mtd-priv;
int status;
 
-   if (len  64)
-   return -EINVAL;
-
-   /* Strictly speaking, we *could* truncate the write ... but
-* let's not do that for the only write that's ever possible.
-*/
-   if ((from + len)  64)
-   return -EINVAL;
+   if ((from + len)  64) {
+   len = 64 - from;
+   if (len = 0)
+   return -ENOSPC;
+   }
 
/* OUT: OP_WRITE_SECURITY, 3 zeroes, 64 data-or-zero bytes
 * IN:  ignore all
diff --git a/drivers/mtd/mtdchar.c b/drivers/mtd/mtdchar.c
index 0edb0ca..db99031 100644
--- a/drivers/mtd/mtdchar.c
+++ b/drivers/mtd/mtdchar.c
@@ -323,6 +323,13 @@ static ssize_t mtdchar_write(struct file *file, const char 
__user *buf, size_t c
default:
ret = mtd_write(mtd, *ppos, len, retlen, kbuf);
}
+   /* return -ENOSPC only if no data was written */
+   if ((ret == -ENOSPC)  (total_retlen)) {
+   ret = 0;
+   retlen = 0;
+   /* drop the remaining data */
+   count = 0;
+   }
if (!ret) {
*ppos += retlen;
total_retlen += retlen;
diff --git a/drivers/mtd/onenand/onenand_base.c 
b/drivers/mtd/onenand/onenand_base.c
index 419c538..6c49a6f 100644
--- a/drivers/mtd/onenand/onenand_base.c
+++ b/drivers/mtd/onenand/onenand_base.c
@@ -3316,7 +3316,15 @@ static int onenand_read_user_prot_reg(struct mtd_info 
*mtd, loff_t from,
 static int onenand_write_user_prot_reg(struct mtd_info *mtd, loff_t from,
size_t len, size_t *retlen, u_char *buf)
 {
-   return onenand_otp_walk(mtd, from, len, retlen, buf, do_otp_write, 
MTD_OTP_USER);
+   int ret;
+   ret = onenand_otp_walk(mtd, from, len, retlen, buf, do_otp_write, 
MTD_OTP_USER);
+
+   /* if no data could be written due to lack of OTP memory,
+  return ENOSPC */
+   if (!ret  len  !(*retlen))
+   return -ENOSPC;
+
+   return ret;
 }
 
 /**
-- 
1.7.9.5

--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH v2 RESEND 0/2] mtd: Harmonize implementations of OTP write and _get_{fact,user}_prot_info

2014-01-28 Thread Christian Riesch
Hi all,

In the discussion on my patchset for the OTP support for
drivers/mtd/chips/cfi_cmdset_0002.c [1-5], Artem requested two changes in the
current code of the OTP write functions and the _get_{fact,user}_prot_info
code.

These two patches are an attempt to make the requested changes.

The first patch adds a retlen parameter to the _get_fact_prot_info and
_get_user_prot_info functions and thus harmonizes the implementation
with those of the write and read functions.

The second patch fixes a problem that I earlier addressed in [1]. After
the discussion about this patch on the mtd mailing list, I think that the
correct behavior of the write function should be the one specified in [6]:
Try to write as many bytes as possible and return the number of bytes
that were written. If no data could be written due to lack of OTP memory,
return -ENOSPC.

Artem, would you please have a look at these patches? I would like to know
if I understood you correctly, or if I missed something here. Please note
that I cannot test these patches since I do not have the hardware. The
patches are compile tested only. If these patches are ok, I will also
respin the OTP support patches for cfi_cmdset_0002.

Changes for v2:
- Fixed buggy cfi_intelext_get_fact_prot_info

Thank you!

Best regards,
Christian

[1] http://patchwork.ozlabs.org/patch/239897/
[2] http://patchwork.ozlabs.org/patch/240010/
[3] http://patchwork.ozlabs.org/patch/240007/
[4] http://patchwork.ozlabs.org/patch/240008/
[5] http://patchwork.ozlabs.org/patch/240009/
[6] http://pubs.opengroup.org/onlinepubs/9699919799/functions/write.html

Cc: Artem Bityutskiy artem.bityuts...@linux.intel.com
Cc: Kyungmin Park kyungmin.p...@samsung.com
Cc: Amul Kumar Saha amul.s...@samsung.com
Cc: Brian Norris computersforpe...@gmail.com

Christian Riesch (2):
  mtd: Add a retlen parameter to _get_{fact,user}_prot_info
  mtd: Fix the behavior of otp write if there is not enough room for
data

 drivers/mtd/chips/cfi_cmdset_0001.c |   44 +++
 drivers/mtd/devices/mtd_dataflash.c |   20 +++-
 drivers/mtd/mtdchar.c   |   18 ++
 drivers/mtd/mtdcore.c   |   12 +-
 drivers/mtd/mtdpart.c   |   14 ++-
 drivers/mtd/onenand/onenand_base.c  |   40 ---
 include/linux/mtd/mtd.h |   16 ++---
 7 files changed, 89 insertions(+), 75 deletions(-)

-- 
1.7.9.5

--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH v2 RESEND 1/2] mtd: Add a retlen parameter to _get_{fact,user}_prot_info

2014-01-28 Thread Christian Riesch
Signed-off-by: Christian Riesch christian.rie...@omicron.at
Cc: Artem Bityutskiy artem.bityuts...@linux.intel.com
Cc: Brian Norris computersforpe...@gmail.com
---
 drivers/mtd/chips/cfi_cmdset_0001.c |   31 +--
 drivers/mtd/devices/mtd_dataflash.c |7 ---
 drivers/mtd/mtdchar.c   |   11 ++-
 drivers/mtd/mtdcore.c   |   12 ++--
 drivers/mtd/mtdpart.c   |   14 --
 drivers/mtd/onenand/onenand_base.c  |   30 --
 include/linux/mtd/mtd.h |   16 
 7 files changed, 57 insertions(+), 64 deletions(-)

diff --git a/drivers/mtd/chips/cfi_cmdset_0001.c 
b/drivers/mtd/chips/cfi_cmdset_0001.c
index 7751443..7aa581f 100644
--- a/drivers/mtd/chips/cfi_cmdset_0001.c
+++ b/drivers/mtd/chips/cfi_cmdset_0001.c
@@ -69,10 +69,10 @@ static int cfi_intelext_read_fact_prot_reg (struct mtd_info 
*, loff_t, size_t, s
 static int cfi_intelext_read_user_prot_reg (struct mtd_info *, loff_t, size_t, 
size_t *, u_char *);
 static int cfi_intelext_write_user_prot_reg (struct mtd_info *, loff_t, 
size_t, size_t *, u_char *);
 static int cfi_intelext_lock_user_prot_reg (struct mtd_info *, loff_t, size_t);
-static int cfi_intelext_get_fact_prot_info (struct mtd_info *,
-   struct otp_info *, size_t);
-static int cfi_intelext_get_user_prot_info (struct mtd_info *,
-   struct otp_info *, size_t);
+static int cfi_intelext_get_fact_prot_info(struct mtd_info *, size_t,
+  size_t *, struct otp_info *);
+static int cfi_intelext_get_user_prot_info(struct mtd_info *, size_t,
+  size_t *, struct otp_info *);
 #endif
 static int cfi_intelext_suspend (struct mtd_info *);
 static void cfi_intelext_resume (struct mtd_info *);
@@ -2399,24 +2399,19 @@ static int cfi_intelext_lock_user_prot_reg(struct 
mtd_info *mtd,
 NULL, do_otp_lock, 1);
 }
 
-static int cfi_intelext_get_fact_prot_info(struct mtd_info *mtd,
-  struct otp_info *buf, size_t len)
-{
-   size_t retlen;
-   int ret;
+static int cfi_intelext_get_fact_prot_info(struct mtd_info *mtd, size_t len,
+  size_t *retlen, struct otp_info *buf)
 
-   ret = cfi_intelext_otp_walk(mtd, 0, len, retlen, (u_char *)buf, NULL, 
0);
-   return ret ? : retlen;
+{
+   return cfi_intelext_otp_walk(mtd, 0, len, retlen, (u_char *)buf,
+NULL, 0);
 }
 
-static int cfi_intelext_get_user_prot_info(struct mtd_info *mtd,
-  struct otp_info *buf, size_t len)
+static int cfi_intelext_get_user_prot_info(struct mtd_info *mtd, size_t len,
+  size_t *retlen, struct otp_info *buf)
 {
-   size_t retlen;
-   int ret;
-
-   ret = cfi_intelext_otp_walk(mtd, 0, len, retlen, (u_char *)buf, NULL, 
1);
-   return ret ? : retlen;
+   return cfi_intelext_otp_walk(mtd, 0, len, retlen, (u_char *)buf,
+NULL, 1);
 }
 
 #endif
diff --git a/drivers/mtd/devices/mtd_dataflash.c 
b/drivers/mtd/devices/mtd_dataflash.c
index 28779b6..09c69ce 100644
--- a/drivers/mtd/devices/mtd_dataflash.c
+++ b/drivers/mtd/devices/mtd_dataflash.c
@@ -442,8 +442,8 @@ static int dataflash_write(struct mtd_info *mtd, loff_t to, 
size_t len,
 
 #ifdef CONFIG_MTD_DATAFLASH_OTP
 
-static int dataflash_get_otp_info(struct mtd_info *mtd,
-   struct otp_info *info, size_t len)
+static int dataflash_get_otp_info(struct mtd_info *mtd, size_t len,
+ size_t *retlen, struct otp_info *info)
 {
/* Report both blocks as identical:  bytes 0..64, locked.
 * Unless the user block changed from all-ones, we can't
@@ -452,7 +452,8 @@ static int dataflash_get_otp_info(struct mtd_info *mtd,
info-start = 0;
info-length = 64;
info-locked = 1;
-   return sizeof(*info);
+   *retlen = sizeof(*info);
+   return 0;
 }
 
 static ssize_t otp_read(struct spi_device *spi, unsigned base,
diff --git a/drivers/mtd/mtdchar.c b/drivers/mtd/mtdchar.c
index 684bfa3..0edb0ca 100644
--- a/drivers/mtd/mtdchar.c
+++ b/drivers/mtd/mtdchar.c
@@ -888,25 +888,26 @@ static int mtdchar_ioctl(struct file *file, u_int cmd, 
u_long arg)
case OTPGETREGIONINFO:
{
struct otp_info *buf = kmalloc(4096, GFP_KERNEL);
+   size_t retlen;
if (!buf)
return -ENOMEM;
switch (mfi-mode) {
case MTD_FILE_MODE_OTP_FACTORY:
-   ret = mtd_get_fact_prot_info(mtd, buf, 4096);
+   ret = mtd_get_fact_prot_info(mtd, 4096, retlen, buf);
break;
case

[PATCH v2 2/2] mtd: Fix the behavior of otp write if there is not enough room for data

2013-12-19 Thread Christian Riesch
An OTP write shall write as much data as possible to the OTP memory
and return the number of bytes that have actually been written.
If no data could be written at all due to lack of OTP memory,
return -ENOSPC.

Signed-off-by: Christian Riesch 
Cc: Artem Bityutskiy 
Cc: Kyungmin Park 
Cc: Amul Kumar Saha 
---
 drivers/mtd/chips/cfi_cmdset_0001.c |   13 +++--
 drivers/mtd/devices/mtd_dataflash.c |   13 +
 drivers/mtd/mtdchar.c   |7 +++
 drivers/mtd/onenand/onenand_base.c  |   10 +-
 4 files changed, 32 insertions(+), 11 deletions(-)

diff --git a/drivers/mtd/chips/cfi_cmdset_0001.c 
b/drivers/mtd/chips/cfi_cmdset_0001.c
index 7aa581f..cf423a6 100644
--- a/drivers/mtd/chips/cfi_cmdset_0001.c
+++ b/drivers/mtd/chips/cfi_cmdset_0001.c
@@ -2387,8 +2387,17 @@ static int cfi_intelext_write_user_prot_reg(struct 
mtd_info *mtd, loff_t from,
size_t len, size_t *retlen,
 u_char *buf)
 {
-   return cfi_intelext_otp_walk(mtd, from, len, retlen,
-buf, do_otp_write, 1);
+   int ret;
+
+   ret = cfi_intelext_otp_walk(mtd, from, len, retlen,
+   buf, do_otp_write, 1);
+
+   /* if no data could be written due to lack of OTP memory,
+  return ENOSPC */
+   if (!ret && len && !(*retlen))
+   return -ENOSPC;
+
+   return ret;
 }
 
 static int cfi_intelext_lock_user_prot_reg(struct mtd_info *mtd,
diff --git a/drivers/mtd/devices/mtd_dataflash.c 
b/drivers/mtd/devices/mtd_dataflash.c
index 09c69ce..5236d85 100644
--- a/drivers/mtd/devices/mtd_dataflash.c
+++ b/drivers/mtd/devices/mtd_dataflash.c
@@ -545,14 +545,11 @@ static int dataflash_write_user_otp(struct mtd_info *mtd,
struct dataflash*priv = mtd->priv;
int status;
 
-   if (len > 64)
-   return -EINVAL;
-
-   /* Strictly speaking, we *could* truncate the write ... but
-* let's not do that for the only write that's ever possible.
-*/
-   if ((from + len) > 64)
-   return -EINVAL;
+   if ((from + len) > 64) {
+   len = 64 - from;
+   if (len <= 0)
+   return -ENOSPC;
+   }
 
/* OUT: OP_WRITE_SECURITY, 3 zeroes, 64 data-or-zero bytes
 * IN:  ignore all
diff --git a/drivers/mtd/mtdchar.c b/drivers/mtd/mtdchar.c
index 0edb0ca..db99031 100644
--- a/drivers/mtd/mtdchar.c
+++ b/drivers/mtd/mtdchar.c
@@ -323,6 +323,13 @@ static ssize_t mtdchar_write(struct file *file, const char 
__user *buf, size_t c
default:
ret = mtd_write(mtd, *ppos, len, , kbuf);
}
+   /* return -ENOSPC only if no data was written */
+   if ((ret == -ENOSPC) && (total_retlen)) {
+   ret = 0;
+   retlen = 0;
+   /* drop the remaining data */
+   count = 0;
+   }
if (!ret) {
*ppos += retlen;
total_retlen += retlen;
diff --git a/drivers/mtd/onenand/onenand_base.c 
b/drivers/mtd/onenand/onenand_base.c
index 419c538..6c49a6f 100644
--- a/drivers/mtd/onenand/onenand_base.c
+++ b/drivers/mtd/onenand/onenand_base.c
@@ -3316,7 +3316,15 @@ static int onenand_read_user_prot_reg(struct mtd_info 
*mtd, loff_t from,
 static int onenand_write_user_prot_reg(struct mtd_info *mtd, loff_t from,
size_t len, size_t *retlen, u_char *buf)
 {
-   return onenand_otp_walk(mtd, from, len, retlen, buf, do_otp_write, 
MTD_OTP_USER);
+   int ret;
+   ret = onenand_otp_walk(mtd, from, len, retlen, buf, do_otp_write, 
MTD_OTP_USER);
+
+   /* if no data could be written due to lack of OTP memory,
+  return ENOSPC */
+   if (!ret && len && !(*retlen))
+   return -ENOSPC;
+
+   return ret;
 }
 
 /**
-- 
1.7.9.5

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH v2 0/2] mtd: Harmonize implementations of OTP write and _get_{fact,user}_prot_info

2013-12-19 Thread Christian Riesch
Hi all,

In the discussion on my patchset for the OTP support for
drivers/mtd/chips/cfi_cmdset_0002.c [1-5], Artem requested two changes in the
current code of the OTP write functions and the _get_{fact,user}_prot_info
code.

These two patches are an attempt to make the requested changes.

The first patch adds a retlen parameter to the _get_fact_prot_info and
_get_user_prot_info functions and thus harmonizes the implementation
with those of the write and read functions.

The second patch fixes a problem that I earlier addressed in [1]. After
the discussion about this patch on the mtd mailing list, I think that the
correct behavior of the write function should be the one specified in [6]:
Try to write as many bytes as possible and return the number of bytes
that were written. If no data could be written due to lack of OTP memory,
return -ENOSPC.

Artem, would you please have a look at these patches? I would like to know
if I understood you correctly, or if I missed something here. Please note
that I cannot test these patches since I do not have the hardware. The
patches are compile tested only. If these patches are ok, I will also
respin the OTP support patches for cfi_cmdset_0002.

Changes for v2:
- Fixed buggy cfi_intelext_get_fact_prot_info

Thank you!

Best regards,
Christian

[1] http://patchwork.ozlabs.org/patch/239897/
[2] http://patchwork.ozlabs.org/patch/240010/
[3] http://patchwork.ozlabs.org/patch/240007/
[4] http://patchwork.ozlabs.org/patch/240008/
[5] http://patchwork.ozlabs.org/patch/240009/
[6] http://pubs.opengroup.org/onlinepubs/9699919799/functions/write.html

Cc: Artem Bityutskiy 
Cc: Kyungmin Park 
Cc: Amul Kumar Saha 
Cc: Brian Norris 

Christian Riesch (2):
  mtd: Add a retlen parameter to _get_{fact,user}_prot_info
  mtd: Fix the behavior of otp write if there is not enough room for
data

 drivers/mtd/chips/cfi_cmdset_0001.c |   44 +++
 drivers/mtd/devices/mtd_dataflash.c |   20 +++-
 drivers/mtd/mtdchar.c   |   18 ++
 drivers/mtd/mtdcore.c   |   12 +-
 drivers/mtd/mtdpart.c   |   14 ++-
 drivers/mtd/onenand/onenand_base.c  |   40 ---
 include/linux/mtd/mtd.h |   16 ++---
 7 files changed, 89 insertions(+), 75 deletions(-)

-- 
1.7.9.5

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH v2 1/2] mtd: Add a retlen parameter to _get_{fact,user}_prot_info

2013-12-19 Thread Christian Riesch
Signed-off-by: Christian Riesch 
Cc: Artem Bityutskiy 
Cc: Brian Norris 
---
 drivers/mtd/chips/cfi_cmdset_0001.c |   31 +--
 drivers/mtd/devices/mtd_dataflash.c |7 ---
 drivers/mtd/mtdchar.c   |   11 ++-
 drivers/mtd/mtdcore.c   |   12 ++--
 drivers/mtd/mtdpart.c   |   14 --
 drivers/mtd/onenand/onenand_base.c  |   30 --
 include/linux/mtd/mtd.h |   16 
 7 files changed, 57 insertions(+), 64 deletions(-)

diff --git a/drivers/mtd/chips/cfi_cmdset_0001.c 
b/drivers/mtd/chips/cfi_cmdset_0001.c
index 7751443..7aa581f 100644
--- a/drivers/mtd/chips/cfi_cmdset_0001.c
+++ b/drivers/mtd/chips/cfi_cmdset_0001.c
@@ -69,10 +69,10 @@ static int cfi_intelext_read_fact_prot_reg (struct mtd_info 
*, loff_t, size_t, s
 static int cfi_intelext_read_user_prot_reg (struct mtd_info *, loff_t, size_t, 
size_t *, u_char *);
 static int cfi_intelext_write_user_prot_reg (struct mtd_info *, loff_t, 
size_t, size_t *, u_char *);
 static int cfi_intelext_lock_user_prot_reg (struct mtd_info *, loff_t, size_t);
-static int cfi_intelext_get_fact_prot_info (struct mtd_info *,
-   struct otp_info *, size_t);
-static int cfi_intelext_get_user_prot_info (struct mtd_info *,
-   struct otp_info *, size_t);
+static int cfi_intelext_get_fact_prot_info(struct mtd_info *, size_t,
+  size_t *, struct otp_info *);
+static int cfi_intelext_get_user_prot_info(struct mtd_info *, size_t,
+  size_t *, struct otp_info *);
 #endif
 static int cfi_intelext_suspend (struct mtd_info *);
 static void cfi_intelext_resume (struct mtd_info *);
@@ -2399,24 +2399,19 @@ static int cfi_intelext_lock_user_prot_reg(struct 
mtd_info *mtd,
 NULL, do_otp_lock, 1);
 }
 
-static int cfi_intelext_get_fact_prot_info(struct mtd_info *mtd,
-  struct otp_info *buf, size_t len)
-{
-   size_t retlen;
-   int ret;
+static int cfi_intelext_get_fact_prot_info(struct mtd_info *mtd, size_t len,
+  size_t *retlen, struct otp_info *buf)
 
-   ret = cfi_intelext_otp_walk(mtd, 0, len, , (u_char *)buf, NULL, 
0);
-   return ret ? : retlen;
+{
+   return cfi_intelext_otp_walk(mtd, 0, len, retlen, (u_char *)buf,
+NULL, 0);
 }
 
-static int cfi_intelext_get_user_prot_info(struct mtd_info *mtd,
-  struct otp_info *buf, size_t len)
+static int cfi_intelext_get_user_prot_info(struct mtd_info *mtd, size_t len,
+  size_t *retlen, struct otp_info *buf)
 {
-   size_t retlen;
-   int ret;
-
-   ret = cfi_intelext_otp_walk(mtd, 0, len, , (u_char *)buf, NULL, 
1);
-   return ret ? : retlen;
+   return cfi_intelext_otp_walk(mtd, 0, len, retlen, (u_char *)buf,
+NULL, 1);
 }
 
 #endif
diff --git a/drivers/mtd/devices/mtd_dataflash.c 
b/drivers/mtd/devices/mtd_dataflash.c
index 28779b6..09c69ce 100644
--- a/drivers/mtd/devices/mtd_dataflash.c
+++ b/drivers/mtd/devices/mtd_dataflash.c
@@ -442,8 +442,8 @@ static int dataflash_write(struct mtd_info *mtd, loff_t to, 
size_t len,
 
 #ifdef CONFIG_MTD_DATAFLASH_OTP
 
-static int dataflash_get_otp_info(struct mtd_info *mtd,
-   struct otp_info *info, size_t len)
+static int dataflash_get_otp_info(struct mtd_info *mtd, size_t len,
+ size_t *retlen, struct otp_info *info)
 {
/* Report both blocks as identical:  bytes 0..64, locked.
 * Unless the user block changed from all-ones, we can't
@@ -452,7 +452,8 @@ static int dataflash_get_otp_info(struct mtd_info *mtd,
info->start = 0;
info->length = 64;
info->locked = 1;
-   return sizeof(*info);
+   *retlen = sizeof(*info);
+   return 0;
 }
 
 static ssize_t otp_read(struct spi_device *spi, unsigned base,
diff --git a/drivers/mtd/mtdchar.c b/drivers/mtd/mtdchar.c
index 684bfa3..0edb0ca 100644
--- a/drivers/mtd/mtdchar.c
+++ b/drivers/mtd/mtdchar.c
@@ -888,25 +888,26 @@ static int mtdchar_ioctl(struct file *file, u_int cmd, 
u_long arg)
case OTPGETREGIONINFO:
{
struct otp_info *buf = kmalloc(4096, GFP_KERNEL);
+   size_t retlen;
if (!buf)
return -ENOMEM;
switch (mfi->mode) {
case MTD_FILE_MODE_OTP_FACTORY:
-   ret = mtd_get_fact_prot_info(mtd, buf, 4096);
+   ret = mtd_get_fact_prot_info(mtd, 4096, , buf);
break;
case MTD_FILE_MODE_OTP_USER:
-   ret = mtd_get_user_prot_info(mt

[PATCH v2 1/2] mtd: Add a retlen parameter to _get_{fact,user}_prot_info

2013-12-19 Thread Christian Riesch
Signed-off-by: Christian Riesch christian.rie...@omicron.at
Cc: Artem Bityutskiy artem.bityuts...@linux.intel.com
Cc: Brian Norris computersforpe...@gmail.com
---
 drivers/mtd/chips/cfi_cmdset_0001.c |   31 +--
 drivers/mtd/devices/mtd_dataflash.c |7 ---
 drivers/mtd/mtdchar.c   |   11 ++-
 drivers/mtd/mtdcore.c   |   12 ++--
 drivers/mtd/mtdpart.c   |   14 --
 drivers/mtd/onenand/onenand_base.c  |   30 --
 include/linux/mtd/mtd.h |   16 
 7 files changed, 57 insertions(+), 64 deletions(-)

diff --git a/drivers/mtd/chips/cfi_cmdset_0001.c 
b/drivers/mtd/chips/cfi_cmdset_0001.c
index 7751443..7aa581f 100644
--- a/drivers/mtd/chips/cfi_cmdset_0001.c
+++ b/drivers/mtd/chips/cfi_cmdset_0001.c
@@ -69,10 +69,10 @@ static int cfi_intelext_read_fact_prot_reg (struct mtd_info 
*, loff_t, size_t, s
 static int cfi_intelext_read_user_prot_reg (struct mtd_info *, loff_t, size_t, 
size_t *, u_char *);
 static int cfi_intelext_write_user_prot_reg (struct mtd_info *, loff_t, 
size_t, size_t *, u_char *);
 static int cfi_intelext_lock_user_prot_reg (struct mtd_info *, loff_t, size_t);
-static int cfi_intelext_get_fact_prot_info (struct mtd_info *,
-   struct otp_info *, size_t);
-static int cfi_intelext_get_user_prot_info (struct mtd_info *,
-   struct otp_info *, size_t);
+static int cfi_intelext_get_fact_prot_info(struct mtd_info *, size_t,
+  size_t *, struct otp_info *);
+static int cfi_intelext_get_user_prot_info(struct mtd_info *, size_t,
+  size_t *, struct otp_info *);
 #endif
 static int cfi_intelext_suspend (struct mtd_info *);
 static void cfi_intelext_resume (struct mtd_info *);
@@ -2399,24 +2399,19 @@ static int cfi_intelext_lock_user_prot_reg(struct 
mtd_info *mtd,
 NULL, do_otp_lock, 1);
 }
 
-static int cfi_intelext_get_fact_prot_info(struct mtd_info *mtd,
-  struct otp_info *buf, size_t len)
-{
-   size_t retlen;
-   int ret;
+static int cfi_intelext_get_fact_prot_info(struct mtd_info *mtd, size_t len,
+  size_t *retlen, struct otp_info *buf)
 
-   ret = cfi_intelext_otp_walk(mtd, 0, len, retlen, (u_char *)buf, NULL, 
0);
-   return ret ? : retlen;
+{
+   return cfi_intelext_otp_walk(mtd, 0, len, retlen, (u_char *)buf,
+NULL, 0);
 }
 
-static int cfi_intelext_get_user_prot_info(struct mtd_info *mtd,
-  struct otp_info *buf, size_t len)
+static int cfi_intelext_get_user_prot_info(struct mtd_info *mtd, size_t len,
+  size_t *retlen, struct otp_info *buf)
 {
-   size_t retlen;
-   int ret;
-
-   ret = cfi_intelext_otp_walk(mtd, 0, len, retlen, (u_char *)buf, NULL, 
1);
-   return ret ? : retlen;
+   return cfi_intelext_otp_walk(mtd, 0, len, retlen, (u_char *)buf,
+NULL, 1);
 }
 
 #endif
diff --git a/drivers/mtd/devices/mtd_dataflash.c 
b/drivers/mtd/devices/mtd_dataflash.c
index 28779b6..09c69ce 100644
--- a/drivers/mtd/devices/mtd_dataflash.c
+++ b/drivers/mtd/devices/mtd_dataflash.c
@@ -442,8 +442,8 @@ static int dataflash_write(struct mtd_info *mtd, loff_t to, 
size_t len,
 
 #ifdef CONFIG_MTD_DATAFLASH_OTP
 
-static int dataflash_get_otp_info(struct mtd_info *mtd,
-   struct otp_info *info, size_t len)
+static int dataflash_get_otp_info(struct mtd_info *mtd, size_t len,
+ size_t *retlen, struct otp_info *info)
 {
/* Report both blocks as identical:  bytes 0..64, locked.
 * Unless the user block changed from all-ones, we can't
@@ -452,7 +452,8 @@ static int dataflash_get_otp_info(struct mtd_info *mtd,
info-start = 0;
info-length = 64;
info-locked = 1;
-   return sizeof(*info);
+   *retlen = sizeof(*info);
+   return 0;
 }
 
 static ssize_t otp_read(struct spi_device *spi, unsigned base,
diff --git a/drivers/mtd/mtdchar.c b/drivers/mtd/mtdchar.c
index 684bfa3..0edb0ca 100644
--- a/drivers/mtd/mtdchar.c
+++ b/drivers/mtd/mtdchar.c
@@ -888,25 +888,26 @@ static int mtdchar_ioctl(struct file *file, u_int cmd, 
u_long arg)
case OTPGETREGIONINFO:
{
struct otp_info *buf = kmalloc(4096, GFP_KERNEL);
+   size_t retlen;
if (!buf)
return -ENOMEM;
switch (mfi-mode) {
case MTD_FILE_MODE_OTP_FACTORY:
-   ret = mtd_get_fact_prot_info(mtd, buf, 4096);
+   ret = mtd_get_fact_prot_info(mtd, 4096, retlen, buf);
break;
case

[PATCH v2 2/2] mtd: Fix the behavior of otp write if there is not enough room for data

2013-12-19 Thread Christian Riesch
An OTP write shall write as much data as possible to the OTP memory
and return the number of bytes that have actually been written.
If no data could be written at all due to lack of OTP memory,
return -ENOSPC.

Signed-off-by: Christian Riesch christian.rie...@omicron.at
Cc: Artem Bityutskiy artem.bityuts...@linux.intel.com
Cc: Kyungmin Park kyungmin.p...@samsung.com
Cc: Amul Kumar Saha amul.s...@samsung.com
---
 drivers/mtd/chips/cfi_cmdset_0001.c |   13 +++--
 drivers/mtd/devices/mtd_dataflash.c |   13 +
 drivers/mtd/mtdchar.c   |7 +++
 drivers/mtd/onenand/onenand_base.c  |   10 +-
 4 files changed, 32 insertions(+), 11 deletions(-)

diff --git a/drivers/mtd/chips/cfi_cmdset_0001.c 
b/drivers/mtd/chips/cfi_cmdset_0001.c
index 7aa581f..cf423a6 100644
--- a/drivers/mtd/chips/cfi_cmdset_0001.c
+++ b/drivers/mtd/chips/cfi_cmdset_0001.c
@@ -2387,8 +2387,17 @@ static int cfi_intelext_write_user_prot_reg(struct 
mtd_info *mtd, loff_t from,
size_t len, size_t *retlen,
 u_char *buf)
 {
-   return cfi_intelext_otp_walk(mtd, from, len, retlen,
-buf, do_otp_write, 1);
+   int ret;
+
+   ret = cfi_intelext_otp_walk(mtd, from, len, retlen,
+   buf, do_otp_write, 1);
+
+   /* if no data could be written due to lack of OTP memory,
+  return ENOSPC */
+   if (!ret  len  !(*retlen))
+   return -ENOSPC;
+
+   return ret;
 }
 
 static int cfi_intelext_lock_user_prot_reg(struct mtd_info *mtd,
diff --git a/drivers/mtd/devices/mtd_dataflash.c 
b/drivers/mtd/devices/mtd_dataflash.c
index 09c69ce..5236d85 100644
--- a/drivers/mtd/devices/mtd_dataflash.c
+++ b/drivers/mtd/devices/mtd_dataflash.c
@@ -545,14 +545,11 @@ static int dataflash_write_user_otp(struct mtd_info *mtd,
struct dataflash*priv = mtd-priv;
int status;
 
-   if (len  64)
-   return -EINVAL;
-
-   /* Strictly speaking, we *could* truncate the write ... but
-* let's not do that for the only write that's ever possible.
-*/
-   if ((from + len)  64)
-   return -EINVAL;
+   if ((from + len)  64) {
+   len = 64 - from;
+   if (len = 0)
+   return -ENOSPC;
+   }
 
/* OUT: OP_WRITE_SECURITY, 3 zeroes, 64 data-or-zero bytes
 * IN:  ignore all
diff --git a/drivers/mtd/mtdchar.c b/drivers/mtd/mtdchar.c
index 0edb0ca..db99031 100644
--- a/drivers/mtd/mtdchar.c
+++ b/drivers/mtd/mtdchar.c
@@ -323,6 +323,13 @@ static ssize_t mtdchar_write(struct file *file, const char 
__user *buf, size_t c
default:
ret = mtd_write(mtd, *ppos, len, retlen, kbuf);
}
+   /* return -ENOSPC only if no data was written */
+   if ((ret == -ENOSPC)  (total_retlen)) {
+   ret = 0;
+   retlen = 0;
+   /* drop the remaining data */
+   count = 0;
+   }
if (!ret) {
*ppos += retlen;
total_retlen += retlen;
diff --git a/drivers/mtd/onenand/onenand_base.c 
b/drivers/mtd/onenand/onenand_base.c
index 419c538..6c49a6f 100644
--- a/drivers/mtd/onenand/onenand_base.c
+++ b/drivers/mtd/onenand/onenand_base.c
@@ -3316,7 +3316,15 @@ static int onenand_read_user_prot_reg(struct mtd_info 
*mtd, loff_t from,
 static int onenand_write_user_prot_reg(struct mtd_info *mtd, loff_t from,
size_t len, size_t *retlen, u_char *buf)
 {
-   return onenand_otp_walk(mtd, from, len, retlen, buf, do_otp_write, 
MTD_OTP_USER);
+   int ret;
+   ret = onenand_otp_walk(mtd, from, len, retlen, buf, do_otp_write, 
MTD_OTP_USER);
+
+   /* if no data could be written due to lack of OTP memory,
+  return ENOSPC */
+   if (!ret  len  !(*retlen))
+   return -ENOSPC;
+
+   return ret;
 }
 
 /**
-- 
1.7.9.5

--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH v2 0/2] mtd: Harmonize implementations of OTP write and _get_{fact,user}_prot_info

2013-12-19 Thread Christian Riesch
Hi all,

In the discussion on my patchset for the OTP support for
drivers/mtd/chips/cfi_cmdset_0002.c [1-5], Artem requested two changes in the
current code of the OTP write functions and the _get_{fact,user}_prot_info
code.

These two patches are an attempt to make the requested changes.

The first patch adds a retlen parameter to the _get_fact_prot_info and
_get_user_prot_info functions and thus harmonizes the implementation
with those of the write and read functions.

The second patch fixes a problem that I earlier addressed in [1]. After
the discussion about this patch on the mtd mailing list, I think that the
correct behavior of the write function should be the one specified in [6]:
Try to write as many bytes as possible and return the number of bytes
that were written. If no data could be written due to lack of OTP memory,
return -ENOSPC.

Artem, would you please have a look at these patches? I would like to know
if I understood you correctly, or if I missed something here. Please note
that I cannot test these patches since I do not have the hardware. The
patches are compile tested only. If these patches are ok, I will also
respin the OTP support patches for cfi_cmdset_0002.

Changes for v2:
- Fixed buggy cfi_intelext_get_fact_prot_info

Thank you!

Best regards,
Christian

[1] http://patchwork.ozlabs.org/patch/239897/
[2] http://patchwork.ozlabs.org/patch/240010/
[3] http://patchwork.ozlabs.org/patch/240007/
[4] http://patchwork.ozlabs.org/patch/240008/
[5] http://patchwork.ozlabs.org/patch/240009/
[6] http://pubs.opengroup.org/onlinepubs/9699919799/functions/write.html

Cc: Artem Bityutskiy artem.bityuts...@linux.intel.com
Cc: Kyungmin Park kyungmin.p...@samsung.com
Cc: Amul Kumar Saha amul.s...@samsung.com
Cc: Brian Norris computersforpe...@gmail.com

Christian Riesch (2):
  mtd: Add a retlen parameter to _get_{fact,user}_prot_info
  mtd: Fix the behavior of otp write if there is not enough room for
data

 drivers/mtd/chips/cfi_cmdset_0001.c |   44 +++
 drivers/mtd/devices/mtd_dataflash.c |   20 +++-
 drivers/mtd/mtdchar.c   |   18 ++
 drivers/mtd/mtdcore.c   |   12 +-
 drivers/mtd/mtdpart.c   |   14 ++-
 drivers/mtd/onenand/onenand_base.c  |   40 ---
 include/linux/mtd/mtd.h |   16 ++---
 7 files changed, 89 insertions(+), 75 deletions(-)

-- 
1.7.9.5

--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH] ax88179_178a: ASIX AX88179_178A USB 3.0/2.0 to gigabit ethernet adapter driver

2013-01-11 Thread Christian Riesch

Hi,

On 2013-01-11 03:45, Ming Lei wrote:

Cc netdev and usb lists.


On Fri, Jan 11, 2013 at 9:17 AM,   wrote:

From: Freddy Xin 

This patch adds a driver for ASIX's AX88179 family of USB 3.0/2.0
to gigabit ethernet adapters. It's based on the AX88xxx driver but
the usb commands used to access registers for AX88179 are completely different.
This driver had been verified on x86 system with AX88179/AX88178A and
Sitcomm LN-032 USB dongles.

Signed-off-by: Freddy Xin 
---
  drivers/net/usb/Kconfig|   18 +
  drivers/net/usb/Makefile   |1 +
  drivers/net/usb/ax88179_178a.c | 1457 
  3 files changed, 1476 insertions(+)
  create mode 100644 drivers/net/usb/ax88179_178a.c



[...]


diff --git a/drivers/net/usb/ax88179_178a.c b/drivers/net/usb/ax88179_178a.c
new file mode 100644
index 000..47504ea
--- /dev/null
+++ b/drivers/net/usb/ax88179_178a.c

[...]

+static int ax88179_read_cmd(struct usbnet *dev, u8 cmd, u16 value, u16 index,
+   u16 size, void *data)
+{
+   int ret;
+   ret = usbnet_read_cmd(dev, cmd,
+  USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
+  value, index, data, size);
+
+   if (ret != size && ret >= 0)
+   return -EINVAL;
+   return ret;
+}
+
+static int ax88179_write_cmd(struct usbnet *dev, u8 cmd, u16 value, u16 index,
+u16 size, void *data)
+{
+   return usbnet_write_cmd(dev, cmd, USB_DIR_OUT | USB_TYPE_VENDOR
+   | USB_RECIP_DEVICE, value, index, data, size);
+}
+
+static void
+ax88179_write_cmd_async(struct usbnet *dev, u8 cmd, u16 value, u16 index,
+   u16 size, void *data)
+{
+   usbnet_write_cmd_async(dev, cmd,
+  USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
+  value, index, data, size);
+}
+


ax88179_read_cmd, ax88179_write_cmd, and ax88179_write_cmd_async 
duplicate code from asix_common.c.


[...]


+static int ax88179_get_eeprom(struct net_device *net,
+ struct ethtool_eeprom *eeprom, u8 *data)
+{
+   struct usbnet *dev = netdev_priv(net);
+   u16 *ebuf = (u16 *)data;
+   int i;
+
+   /* Crude hack to ensure that we don't overwrite memory
+* if an odd length is supplied


Have a look at asix_get_eeprom() in asix_common.c for a better 
implementation. There is also code for programming the eeprom 
(asix_set_eeprom in asix_common.c), can this be used for the 
AX88179/178A as well?


Regards, Christian


+*/
+   if (eeprom->len % 2)
+   return -EINVAL;
+
+   /* ax8817x returns 2 bytes from eeprom on read */
+   for (i = 0; i < eeprom->len / 2; i++) {
+   if (ax88179_read_cmd(dev, AX_ACCESS_EEPROM,
+   eeprom->offset + i, 1, 2, [i]) < 0)
+   return -EINVAL;
+   }
+   return 0;
+}
+


--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH] ax88179_178a: ASIX AX88179_178A USB 3.0/2.0 to gigabit ethernet adapter driver

2013-01-11 Thread Christian Riesch

Hi,

On 2013-01-11 03:45, Ming Lei wrote:

Cc netdev and usb lists.


On Fri, Jan 11, 2013 at 9:17 AM,  fre...@asix.com.tw wrote:

From: Freddy Xin fre...@asix.com.tw

This patch adds a driver for ASIX's AX88179 family of USB 3.0/2.0
to gigabit ethernet adapters. It's based on the AX88xxx driver but
the usb commands used to access registers for AX88179 are completely different.
This driver had been verified on x86 system with AX88179/AX88178A and
Sitcomm LN-032 USB dongles.

Signed-off-by: Freddy Xin fre...@asix.com.tw
---
  drivers/net/usb/Kconfig|   18 +
  drivers/net/usb/Makefile   |1 +
  drivers/net/usb/ax88179_178a.c | 1457 
  3 files changed, 1476 insertions(+)
  create mode 100644 drivers/net/usb/ax88179_178a.c



[...]


diff --git a/drivers/net/usb/ax88179_178a.c b/drivers/net/usb/ax88179_178a.c
new file mode 100644
index 000..47504ea
--- /dev/null
+++ b/drivers/net/usb/ax88179_178a.c

[...]

+static int ax88179_read_cmd(struct usbnet *dev, u8 cmd, u16 value, u16 index,
+   u16 size, void *data)
+{
+   int ret;
+   ret = usbnet_read_cmd(dev, cmd,
+  USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
+  value, index, data, size);
+
+   if (ret != size  ret = 0)
+   return -EINVAL;
+   return ret;
+}
+
+static int ax88179_write_cmd(struct usbnet *dev, u8 cmd, u16 value, u16 index,
+u16 size, void *data)
+{
+   return usbnet_write_cmd(dev, cmd, USB_DIR_OUT | USB_TYPE_VENDOR
+   | USB_RECIP_DEVICE, value, index, data, size);
+}
+
+static void
+ax88179_write_cmd_async(struct usbnet *dev, u8 cmd, u16 value, u16 index,
+   u16 size, void *data)
+{
+   usbnet_write_cmd_async(dev, cmd,
+  USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
+  value, index, data, size);
+}
+


ax88179_read_cmd, ax88179_write_cmd, and ax88179_write_cmd_async 
duplicate code from asix_common.c.


[...]


+static int ax88179_get_eeprom(struct net_device *net,
+ struct ethtool_eeprom *eeprom, u8 *data)
+{
+   struct usbnet *dev = netdev_priv(net);
+   u16 *ebuf = (u16 *)data;
+   int i;
+
+   /* Crude hack to ensure that we don't overwrite memory
+* if an odd length is supplied


Have a look at asix_get_eeprom() in asix_common.c for a better 
implementation. There is also code for programming the eeprom 
(asix_set_eeprom in asix_common.c), can this be used for the 
AX88179/178A as well?


Regards, Christian


+*/
+   if (eeprom-len % 2)
+   return -EINVAL;
+
+   /* ax8817x returns 2 bytes from eeprom on read */
+   for (i = 0; i  eeprom-len / 2; i++) {
+   if (ax88179_read_cmd(dev, AX_ACCESS_EEPROM,
+   eeprom-offset + i, 1, 2, ebuf[i])  0)
+   return -EINVAL;
+   }
+   return 0;
+}
+


--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: linux-next: build failure after merge of the net-next tree

2012-07-19 Thread Christian Riesch

[Sent again due to problems with email client]

Hi,

On 07/20/2012 04:01 AM, Stephen Rothwell wrote:

Hi all,

After merging the net-next tree, today's linux-next build (powerpc
pmac32_defconfig) failed like this:

ERROR: "phy_disconnect" [drivers/net/usb/asix.ko] undefined!
ERROR: "phy_stop" [drivers/net/usb/asix.ko] undefined!
ERROR: "phy_ethtool_gset" [drivers/net/usb/asix.ko] undefined!
ERROR: "mdiobus_unregister" [drivers/net/usb/asix.ko] undefined!
ERROR: "phy_start_aneg" [drivers/net/usb/asix.ko] undefined!
ERROR: "phy_print_status" [drivers/net/usb/asix.ko] undefined!
ERROR: "phy_start" [drivers/net/usb/asix.ko] undefined!
ERROR: "mdiobus_free" [drivers/net/usb/asix.ko] undefined!
ERROR: "mdiobus_register" [drivers/net/usb/asix.ko] undefined!
ERROR: "genphy_resume" [drivers/net/usb/asix.ko] undefined!
ERROR: "phy_connect" [drivers/net/usb/asix.ko] undefined!
ERROR: "phy_mii_ioctl" [drivers/net/usb/asix.ko] undefined!
ERROR: "phy_ethtool_sset" [drivers/net/usb/asix.ko] undefined!
ERROR: "mdiobus_alloc_size" [drivers/net/usb/asix.ko] undefined!

Caused by commit 16626b0cc3d5 ("asix: Add a new driver for the AX88172A")
and reverting that commit fixes the build.


Sorry about that. I missed the dependency of the new driver on phylib. A 
fix for this problem is already in net-next, see commit 215029375c83.


Thanks, Christian



Thanks to Mikey for reporting this porblem.


--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: linux-next: build failure after merge of the net-next tree

2012-07-19 Thread Christian Riesch

[Sent again due to problems with email client]

Hi,

On 07/20/2012 04:01 AM, Stephen Rothwell wrote:

Hi all,

After merging the net-next tree, today's linux-next build (powerpc
pmac32_defconfig) failed like this:

ERROR: phy_disconnect [drivers/net/usb/asix.ko] undefined!
ERROR: phy_stop [drivers/net/usb/asix.ko] undefined!
ERROR: phy_ethtool_gset [drivers/net/usb/asix.ko] undefined!
ERROR: mdiobus_unregister [drivers/net/usb/asix.ko] undefined!
ERROR: phy_start_aneg [drivers/net/usb/asix.ko] undefined!
ERROR: phy_print_status [drivers/net/usb/asix.ko] undefined!
ERROR: phy_start [drivers/net/usb/asix.ko] undefined!
ERROR: mdiobus_free [drivers/net/usb/asix.ko] undefined!
ERROR: mdiobus_register [drivers/net/usb/asix.ko] undefined!
ERROR: genphy_resume [drivers/net/usb/asix.ko] undefined!
ERROR: phy_connect [drivers/net/usb/asix.ko] undefined!
ERROR: phy_mii_ioctl [drivers/net/usb/asix.ko] undefined!
ERROR: phy_ethtool_sset [drivers/net/usb/asix.ko] undefined!
ERROR: mdiobus_alloc_size [drivers/net/usb/asix.ko] undefined!

Caused by commit 16626b0cc3d5 (asix: Add a new driver for the AX88172A)
and reverting that commit fixes the build.


Sorry about that. I missed the dependency of the new driver on phylib. A 
fix for this problem is already in net-next, see commit 215029375c83.


Thanks, Christian



Thanks to Mikey for reporting this porblem.


--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/