From: Arnd Bergmann <arnd@arndb.de>
To: Greg KH <greg@kroah.com>
Cc: Stephen Boyd <sboyd@codeaurora.org>,
linux-kernel@vger.kernel.org, linux-mmc@vger.kernel.org,
"linux-arm-msm@vger.kernel.org" <linux-arm-msm@vger.kernel.org>,
Alexander Kolesnikov <akolesni@codeaurora.org>,
Konstantin Dorfman <kdorfman@codeaurora.org>
Subject: Re: char interface to sdio, chdio.c
Date: Thu, 17 Jul 2014 12:17 +0200 [thread overview]
Message-ID: <7228146.FsqiNq1Vpj@wuerfel> (raw)
In-Reply-To: <20140717053347.GB22970@kroah.com>
On Wednesday 16 July 2014 22:33:47 Greg KH wrote:
> + mmc: Char SDIO Device Driver
A few comments on the ioctl interface, since I suppose we'll have
to live with that once it gets merged.
> +Interface
> +=========
> +The Char SDIO Device Driver has two char device interfaces:
> + - Control Interface;
> + - Function Interface.
> +
> +Char SDIO Device Driver Control Interface consists of:
> + - open() - device node is /dev/csdio0;
> + - close()
> + - ioctl() - the following options are available:
> + - CSDIO_IOC_ENABLE_HIGHSPEED_MODE;
> + - CSDIO_IOC_SET_DATA_TRANSFER_CLOCKS;
> + - CSDIO_IOC_ENABLE_ISR;
> + - CSDIO_IOC_DISABLE_ISR.
The documentation doesn't match the code.:
CSDIO_IOC_GET/SET_VDD are implemented in the control device,
not the function device, and that is probably a good idea.
CSDIO_IOC_ENABLE_HIGHSPEED_MODE is not implemented
at all. CSDIO_IOC_ENABLE_ISR seems redundant with what
the CSDIO_IOC_{DIS,}CONNECT_ISR functions do, but I could be
wrong here.
The sysfs interface may actually be more appropriate than the
control node, if I was to pick one of the two.
> +Char SDIO Device Driver Function Interface consists of:
> + - open() - device node is /dev/csdiofX, where X is Function Id;
> + - close()
> + - read() - send CMD53 read;
> + - write() - send CMD53 write;
> + - ioctl() - the following options are available:
> + - CSDIO_IOC_SET_OP_CODE - 0 fixed adrress, 1 autoincrement.
> + - CSDIO_IOC_FUNCTION_SET_BLOCK_SIZE;
> + - CSDIO_IOC_SET_BLOCK_MODE - 0 byte mode, 1 block mode;
> + - CSDIO_IOC_CMD52 - execute CMD52, receives the
> + following structure as a parameter:
> + struct csdio_cmd52_ctrl_t {
> + uint32_t m_write; // 0 - read, 1 -write
> + uint32_t m_address;
> + uint32_t m_data; // data to write or read data
> + uint32_t m_ret; // command execution status
> + }__attribute__ ((packed));
> + - CSDIO_IOC_CMD53 - setup CMD53 data transfer, receives the
> + following structure as a parameter:
> + struct csdio_cmd53_ctrl_t {
> + uint32_t m_block_mode;
> + uint32_t m_op_code;
> + uint32_t m_address;
> + }__attribute__ ((packed));
> + - CSDIO_IOC_CONNECT_ISR;
> + - CSDIO_IOC_DISCONNECT_ISR;
> + - CSDIO_IOC_GET_VDD;
> + - CSDIO_IOC_SET_VDD.
> +
> +Additionally, user space application can use fcntl system call with
> +parameters F_SETOWN and F_SETFL in order to set an asynchronous
> +callback for SDIO interrupt.
The read/write API seems very strange. SDIO has multiple ways of
passing data between OS and device using CMD52 and CMD53, and they
are all done differently here:
- A one-byte read or write uses a single CSDIO_IOC_CMD52 ioctl.
This could be done using pread/pwrite with length '1' rather than
an ioctl, if we want to.
- a byte-addressed multi-byte read/write needs to first 'seek' using
CSDIO_IOC_CMD53 or and then transfer using read() or write().
- a block-addressed read/write is similar, but the number of bytes
copied to/from user space is now multiplied with the block size (!).
The block size needs to be set using both CSDIO_IOC_SET_BLOCK_MODE
and CSDIO_IOC_CMD53, using the same value.
- to do a multi-byte read/write at a constant address rather than
a block copy, CSDIO_IOC_CMD53 needs to set at least one bit (not
necessarily the one used in the actual command) in m_op_code.
I guess all of this could be done using pread/pwrite, using the
loff_t value to encode the m_address in the lower bits and the
mode (single-byte, multi-byte, multi-byte auto-increment,
block, block auto-increment) in some of the upper bits.
Alternatively, the read/write functions could be removed completely
and everything be done in the ioctls, but in a more consistent
way.
> +
> +#define CSDIO_IOC_MAGIC 'm'
> +
> +#define CSDIO_IOC_ENABLE_HIGHSPEED_MODE _IO(CSDIO_IOC_MAGIC, 0)
> +#define CSDIO_IOC_SET_DATA_TRANSFER_CLOCKS _IO(CSDIO_IOC_MAGIC, 1)
> +#define CSDIO_IOC_SET_OP_CODE _IO(CSDIO_IOC_MAGIC, 2)
> +#define CSDIO_IOC_FUNCTION_SET_BLOCK_SIZE _IO(CSDIO_IOC_MAGIC, 3)
> +#define CSDIO_IOC_SET_BLOCK_MODE _IO(CSDIO_IOC_MAGIC, 4)
> +#define CSDIO_IOC_CONNECT_ISR _IO(CSDIO_IOC_MAGIC, 5)
> +#define CSDIO_IOC_DISCONNECT_ISR _IO(CSDIO_IOC_MAGIC, 6)
> +#define CSDIO_IOC_CMD52 _IO(CSDIO_IOC_MAGIC, 7)
> +#define CSDIO_IOC_CMD53 _IO(CSDIO_IOC_MAGIC, 8)
> +#define CSDIO_IOC_ENABLE_ISR _IO(CSDIO_IOC_MAGIC, 9)
> +#define CSDIO_IOC_DISABLE_ISR _IO(CSDIO_IOC_MAGIC, 10)
> +#define CSDIO_IOC_SET_VDD _IO(CSDIO_IOC_MAGIC, 11)
> +#define CSDIO_IOC_GET_VDD _IO(CSDIO_IOC_MAGIC, 12)
> +
> +#define CSDIO_IOC_MAXNR 12
The command codes above should use _IOR or _IOW where appropriate to
encode the size of the transferred data.
> +
> +struct csdio_cmd53_ctrl_t {
> + uint32_t m_block_mode; /* data tran. byte(0)/block(1) mode */
> + uint32_t m_op_code; /* address auto increment flag */
> + uint32_t m_address;
> +} __attribute__ ((packed));
> +
> +struct csdio_cmd52_ctrl_t {
> + uint32_t m_write;
> + uint32_t m_address;
> + uint32_t m_data;
> + uint32_t m_ret;
> +} __attribute__ ((packed));
The packing is not necessary here, but at least all of these are
compatible between 32 and 64 bit, so enabling compat mode is a one-line
change and requires no conversion.
Arnd
next prev parent reply other threads:[~2014-07-17 10:17 UTC|newest]
Thread overview: 9+ messages / expand[flat|nested] mbox.gz Atom feed top
2014-07-16 3:26 char interface to sdio, chdio.c Greg KH
2014-07-16 18:21 ` Stephen Boyd
2014-07-16 18:44 ` Greg KH
2014-07-16 19:38 ` Stephen Boyd
2014-07-16 23:08 ` Stephen Boyd
2014-07-16 23:11 ` Greg KH
2014-07-17 5:33 ` Greg KH
2014-07-17 10:17 ` Arnd Bergmann [this message]
2014-07-18 3:08 ` Greg KH
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=7228146.FsqiNq1Vpj@wuerfel \
--to=arnd@arndb.de \
--cc=akolesni@codeaurora.org \
--cc=greg@kroah.com \
--cc=kdorfman@codeaurora.org \
--cc=linux-arm-msm@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-mmc@vger.kernel.org \
--cc=sboyd@codeaurora.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox