[RFC 1/7] staging: fbtft: add lcd register abstraction
Dan Carpenter
dan.carpenter at oracle.com
Tue Mar 3 12:28:47 UTC 2015
On Tue, Mar 03, 2015 at 01:19:52PM +0100, Noralf Trønnes wrote:
> >>+static ssize_t lcdreg_debugfs_read_wr(struct file *file,
> >>+ const char __user *user_buf,
> >>+ size_t count, loff_t *ppos)
> >>+{
> >>+ struct lcdreg *reg = file->private_data;
> >>+ struct lcdreg_transfer tr = {
> >>+ .index = (reg->quirks & LCDREG_INDEX0_ON_READ) ? 0 : 1,
> >>+ .width = reg->debugfs_read_width,
> >>+ .count = 1,
> >>+ };
> >>+ u32 txbuf[1];
> >>+ char *buf = NULL;
> >>+ int ret;
> >>+
> >>+ ret = lcdreg_userbuf_to_u32(user_buf, count, txbuf, ARRAY_SIZE(txbuf));
> >>+ if (ret != 1)
> >>+ return -EINVAL;
> >>+
> >>+ tr.buf = kmalloc(lcdreg_bytes_per_word(tr.width), GFP_KERNEL);
> >>+ if (!tr.buf)
> >>+ return -ENOMEM;
> >>+
> >>+ add_taint(TAINT_USER, LOCKDEP_STILL_OK);
> >>+
> >>+ lcdreg_lock(reg);
> >>+ ret = lcdreg_read(reg, txbuf[0], &tr);
> >>+ lcdreg_unlock(reg);
> >>+ if (ret)
> >>+ goto error_out;
> >>+
> >>+ if (!reg->debugfs_read_result) {
> >>+ reg->debugfs_read_result = kmalloc(16, GFP_KERNEL);
> >>+ if (!reg->debugfs_read_result) {
> >>+ ret = -ENOMEM;
> >>+ goto error_out;
> >>+ }
> >>+ }
> >Allocating here is strange. We only free ->debugfs_read_result on
> >error so it's sort of buggy as well. Also is it racy if we have
> >multiple readers and writers at once?
> I spent some time on figuring out how to do this.
> To read a register, first write the register number to the 'read' file.
> Then get the result by reading the 'read' file.
> So I have to keep the result somewhere, but you're right this leaks
> memory. Maybe I can use devm_kmalloc here.
> And yes this is racy. I'm not sure if this is a problem.
> This is to be used during development or debugging, so
> the user should have this under control.
>
> But I'm open to other ways of doing this. This is the best I could
> come up with after several iterations on this code.
> My other solutions where worse :-)
We can't do it probe()? We could add another flag to say if we had
written to it. I haven't looked at this closely so whatever you decide
is fine.
> >>+#if defined(CONFIG_DYNAMIC_DEBUG)
> >>+
> >>+#define lcdreg_dbg_transfer_buf(transfer) \
> >>+do { \
> >>+ int groupsize = lcdreg_bytes_per_word(transfer->width); \
> >>+ size_t len = min_t(size_t, 32, transfer->count * groupsize); \
> >>+ \
> >>+ print_hex_dump_debug(" buf=", DUMP_PREFIX_NONE, 32, \
> >>+ groupsize, transfer->buf, len, false); \
> >>+} while (0)
> >>+
> >>+#elif defined(DEBUG)
> >>+
> >>+#define lcdreg_dbg_transfer_buf(transfer) \
> >>+do { \
> >>+ int groupsize = lcdreg_bytes_per_word(transfer->width); \
> >>+ size_t len = min_t(size_t, 32, transfer->count * groupsize); \
> >>+ \
> >>+ print_hex_dump(KERN_DEBUG, " buf=", DUMP_PREFIX_NONE, 32, \
> >>+ groupsize, transfer->buf, len, false); \
> >>+} while (0)
> >I don't understand this. Why can't we use print_hex_dump_debug() for
> >both? In other words:
> >
> >#if defined(CONFIG_DYNAMIC_DEBUG) || defined(DEBUG)
> >...
> >#else
> The reason I do this is to be able to switch on/off debugging
> quickly when developing.
> I have dynamic debug enabled, but it's more cumbersome to use, so I
> define DEBUG
> when I need this output.
> print_hex_dump_debug() doesn't look at DEBUG, it only cares about
> DYNAMIC_DEBUG.
> But, it's not suited for production code, so I guess I have to use a
> script or something
> to easily switch dynamic debug on/off instead.
>
Fine fine. Whatever you decide is ok.
regards,
dan carpenter
More information about the devel
mailing list