Re: [PATCH v6] mmc: Add mmc CMD+ACMD passthrough ioctl

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



W dniu 21 kwietnia 2011 14:39 użytkownik Arnd Bergmann <arnd@xxxxxxxx> napisał:
> On Thursday 21 April 2011, Michał Mirosław wrote:
>> W dniu 21 kwietnia 2011 13:15 użytkownik Arnd Bergmann <arnd@xxxxxxxx> napisał:
>
>> static int mmc_blk_compat_ioctl(struct block_device *bdev, fmode_t mode,
>>     unsigned int cmd, unsigned long arg)
>> {
>>   struct mmc_ioc_cmd blk;
>>
>>   if (cmd != MMC_IOC_CMD)
>>     return -EINVAL;
>>
>>   copy_from_user(compat_ptr(arg), &blk) ...
>>   blk.data_ptr = compat_ptr(blk.__data_ptr_storage32);
>>
>>   return mmc_blk_ioctl_cmd(bdev, &blk);
>> }
>
> Yes, this works, but it requires having a compat_ioctl() handler function that
> knows about the data structure, which we generally try to avoid.
> The same method would even work if you only had a pointer member in the
> structure and did not even attempt to make the structure compatible.

Not really. If the structures were different, you would need write
code to translate it fully (this doesn't really apply for this simple
case, where there is only one pointer at the end of the structure). My
example only fixes/converts pointers in place.

The compat/native handler could be made in one function that takes
another bool arg and ioctl handlers would look like the code below. In
this scheme you avoid having to duplicate ioctl handler at all and let
compiler optimize out conditionals (you can even force
__mmc_blk_ioctl() inline to make sure of it).

#ifndef CONFIG_COMPAT
static inline void *compat_ptr(unsigned long) { BUG(); return NULL; }
#endif

static int __mmc_blk_ioctl(struct block_device *bdev, fmode_t mode,
    unsigned int cmd, unsigned long arg, bool compat32)
{
  void __user *p;
...
  p = compat32 ? compat_ptr(arg) : (void *)arg;
...
  if (compat32)
    blk.data_ptr = compat_ptr(blk.__data_ptr_storage32);
...
}

static int mmc_blk_ioctl(struct block_device *bdev, fmode_t mode,
    unsigned int cmd, unsigned long arg)
{
  return __mmc_blk_ioctl(bdev, mode, cmd, arg, false);
}

#ifdef CONFIG_COMPAT
static int mmc_blk_compat_ioctl(struct block_device *bdev, fmode_t mode,
    unsigned int cmd, unsigned long arg)
{
  return __mmc_blk_ioctl(bdev, mode, cmd, arg, true);
}
#endif
--
To unsubscribe from this list: send the line "unsubscribe linux-mmc" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Index of Archives]     [Linux USB Devel]     [Linux Media]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux