[PATCH v3] ath10k: Add the target register read/write and memory dump debugfs interface
Li, Yanbo
yanbol at qti.qualcomm.com
Tue Oct 21 08:10:04 PDT 2014
Hi Michal,
Thanks for your comments. answered as below,
> -----Original Message-----
> From: Michal Kazior [mailto:michal.kazior at tieto.com]
> Sent: Tuesday, October 21, 2014 2:56 PM
> To: Li, Yanbo
> Cc: Valo, Kalle; ath10k-devel; Balasubramanian, Senthil Kumar;
> dreamfly281 at gmail.com; linux-wireless; ath10k at lists.infradead.org
> Subject: Re: [PATCH v3] Add the target register read/write and memory dump
> debugfs interface
>
> You're missing "ath10k: " prefix in the patch subject.
>
Change the subject, :)
>
> On 20 October 2014 18:38, Yanbo Li <yanbol at qti.qualcomm.com> wrote:
> > The debugfs interface reg_addr®_val used to read and write the
> > target register.
> > The interface mem_addr&mem_val used to dump the targer memory and also
> > can be used to assign value to target memory
> >
> > The basic usage explain as below:
> >
> > Register read/write:
> > reg_addr (the register address) (read&write)
> > reg_value (the register value, output is ASCII) (read&write)
> >
> > Read operation:
> > 1. Write the reg address to reg_addr
> > IE: echo 0x100000 > reg_addr
> > 2. Read the value from reg_value
> > IE: cat reg_value
> > Write operation:
> > 1. Write the reg address to reg_addr IE: echo 0x100000 > reg_addr 2.
> > Write the value to the reg_value IE: echo 0x2400 > reg_value
> >
> > Target memory dump:
> > mem_addr (the memory address the length also can used as the second
> > paramenter address length) (read&write)
> > mem_value (the content of the memory with the length, output is binary)
> > (read&write)
> > Read operation:
> > 1. Write the address and length to mem_addr
> > IE: echo 0x400000 1024 > mem_addr
>
> So mem_addr is actually used to store both _addr_ and _length_. I think length
> could be skipped and be read implicitly from each read() request along with the
> offset. This way userspace would be able to determine read length on demand, e.g.
> via "dd if=mem_value bs=1024 count=4" (read 4 KiB of data). If you want to see
> hex, you would pipe it through "hexdump" or "xxd" or your other favourite
> hexdump program.
> Or even better - you could drop the mem_addr altogether and expect userspace to
> seek & read/write data it wants via, e.g. `dd` program:
>
> dd if=mem_value bs=1 count=1024 skip=$(printf "%d" 0x400000) | xxd -g1
> echo 0x01020304 | xxd -r | dd of=mem_value bs=1 seek=$(printf "%d" 0x400400)
>
Agree with you, that will be easy to access and avoid the one variable (mem_addr)store two different values.
>
> > 2. Read the value from mem value, the output is binary format
> > IE: hexdump mem_value
> > Write operation:
> > 1. Write the start mem address to mem_addr
> > IE: echo 0x400000 > mem_addr
> > 2. Dump the binary value to the mem_value
> > IE: echo 0x2400 > mem_value or echo 0x2400 0x3400 ... > mem_addr
> > (the value number should be separated with spacebar)
>
> I don't really like the idea of input being different than the output, but maybe that's
> just me.
>
Hmm, I will implement another version to keep the read and write use the same interface,
the extra effort is the user need edit the binary file to construct the input number.
>
> [...]
> > +static ssize_t ath10k_mem_value_write(struct file *file,
> > + const char __user *user_buf,
> > + size_t count, loff_t *ppos) {
> > + struct ath10k *ar = file->private_data;
> > + u8 *buf;
> > + __le32 *value;
> > + char *sptr, *token;
> > + int i, ret;
> > + u32 mem_addr;
> > + u32 mem_val;
> > +
> > + mem_addr = ar->debug.mem_addr;
>
> There's double space following "=".
>
Good catch.
>
> [...]
> > + i = 0;
> > + while (sptr) {
> > + if (!sptr)
> > + break;
> > +
> > + token = strsep(&sptr, " ");
> > +
> > + ret = kstrtou32(token, 0, &mem_val);
> > + if (ret)
> > + goto err_free_value;
> > +
> > + value[i] = mem_val;
> > + i++;
> > + }
> > +
> > + ret = ath10k_hif_diag_write(ar, mem_addr, (const void *)value,
> > + i * sizeof(mem_val));
> > + if (ret) {
> > + ath10k_warn(ar, "failed to write address 0x%08x via diagnose window
> from debugfs: %d\n",
> > + mem_addr, ret);
> > + goto err_free_value;
> > + }
>
> I believe userspace may call write() multiple number of times with different offsets
> and fragment the data breaking it in the middle of your string hex words. This
> code will most likely fail with larger chunks of data or you can try to simulate the
> fragmentation with:
>
> echo 0x0001 0x0002 | dd bs=1 of=mem_value
>
> (Please correct me if I'm wrong :-)
>
Not full understand what’s you mean, do you mean this segment need be protect with lock
to avoid multi write operation access the mem_value at the same time?
>
> Michał
More information about the ath10k
mailing list