All of lore.kernel.org
 help / color / mirror / Atom feed
* Re[2]: UDEV.
@ 2010-08-19 15:07 Тима
  2010-08-24  9:27 ` Тима
  0 siblings, 1 reply; 2+ messages in thread
From: Тима @ 2010-08-19 15:07 UTC (permalink / raw)
  To: linux-hotplug

Thanks. 
My question (I think) is very easy. But I could not find answer in the Internet, and did not get it on forum.
My aim is to make UDEV create device node automatically on loading module.
I tied rule:
KERNEL="math", NAME="math"
meaning my device name (register char dev) is "math" and the node name I want is "math".
But nothing happens.
Is there any possibility to make such rule?
Maybe I do not export some required information to SysFS?
If you need module code I can send it to you with Makefile.



> Wed, 18 Aug 2010 05:49:31 -0700 письмо от Greg KH <greg@kroah.com>:
> 
> > On Wed, Aug 18, 2010 at 01:51:11PM +0400, ???? wrote:
> > > Hello All!
> > > My name is Tima, I'm embedded software developer.
> > > I'm working on driver for Satellite Digital Video Receiver.
> > > 
> > > May I ask some question about UDEV?
> > 
> > You never have to ask the question "can I ask a question?" :)

--
To unsubscribe from this list: send the line "unsubscribe linux-hotplug" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 2+ messages in thread

* Re[2]: UDEV.
  2010-08-19 15:07 Re[2]: UDEV Тима
@ 2010-08-24  9:27 ` Тима
  0 siblings, 0 replies; 2+ messages in thread
From: Тима @ 2010-08-24  9:27 UTC (permalink / raw)
  To: linux-hotplug

> 
> A: No.
> Q: Should I include quotations after my reply?
> 
> http://daringfireball.net/2007/07/on_top
> 
> On Thu, Aug 19, 2010 at 07:07:40PM +0400, ???? wrote:
> > Thanks. 
> > My question (I think) is very easy. But I could not find answer in the Internet, and did not get it on forum.
> > My aim is to make UDEV create device node automatically on loading module.
> > I tied rule:
> > KERNEL="math", NAME="math"
> > meaning my device name (register char dev) is "math" and the node name I want is "math".
> > But nothing happens.
> > Is there any possibility to make such rule?
> > Maybe I do not export some required information to SysFS?
> > If you need module code I can send it to you with Makefile.
> 
> Yes, please post your kernel code.  You need to hook into the driver
> model to properly be able to have udev pick up your device information.
> Have you done that?
> 
> thanks,
> 
> greg k-h

Yes, here is my code.
(Sorry for comments in russian. If you need something to understand - ask me and I'll translate it.)
I want kernel to make, for example, /dev/math on loading this module. What should I add to this code or to UDEV rules?

#include <linux/module.h>       // Необходим для любого модуля ядра
#include <linux/kernel.h>       // Здесь находится определения KERN_*
#include <linux/init.h>         // Здесь находятся определения макросов
#include <linux/fs.h>           // Фаил для работы с фаиловой системой
#include <asm/uaccess.h>        // Определение функции put_user
#include <linux/device.h>
static char *DeviceName = "math";
static char *ParamStr = "NULL";
module_param (ParamStr, charp, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
// Третий аргумент функции - права доступа к соответствующему фаилу в SysFS.
// В нашем случае Read User, Write User, Read Group, Read Others.
MODULE_PARM_DESC (ParamStr, " String Parameter.");

static int DevMajor = -1;
#define STR_LEN 256
static char Expression [STR_LEN];
static char FirstOperand [STR_LEN];
static char SecondOperand [STR_LEN];
static char Answer [STR_LEN];

static int Calculate (void)
{ // Функция выполняющая разбор заданного выражения и вычисление результата.
  // Принимает Expression, результат вычислений возвращает в Answer.
  int lStr = 0;
  int lOperation = -1;
  int Operand1, Operand2 = 0;
  // lOperation: -1 - "Error"; 0 - "+"; 1 - "-"; 2 - "*"; 3 - "/";
  sprintf (Answer, "No Calculated Result.\n");
  Answer[strlen ("No Calculated Result.\n")] = 0;
  // Ищем знак математической операции:
  while (lStr < strlen (Expression))
  {
    if (Expression[lStr] = '+')
    {
      lOperation = 0;
      break;
    } else
    if (Expression[lStr] = '-')
    {
      lOperation = 1;
      break;
    } else
    if (Expression[lStr] = '*')
    {
      lOperation = 2;
      break;
    } else
    if (Expression[lStr] = '/')
    {
      lOperation = 3;
      break;
    };
    lStr++;
  };
  if (lOperation = -1)
  {// Если знак операции не найден - выводим подсказку.
    sprintf (Answer, "Error in Expression. Please use as \"Operand1 [+, -, *, /] Operand2\".\n");
  } else
  {
    memcpy (FirstOperand, &Expression[0], lStr);
    memcpy (SecondOperand, &Expression[lStr + 1], strlen (Expression) - lStr - 1);
    Operand1 = simple_strtol (FirstOperand, &FirstOperand, 10);
    Operand2 = simple_strtol (SecondOperand, &SecondOperand, 10);
    // Сосчитаем что просят:
    switch (lOperation)
    {
      case 0: // +
        sprintf (Answer, "%s = %d\n", Expression, Operand1 + Operand2);
      break;
      case 1: // -
        sprintf (Answer, "%s = %d\n", Expression, Operand1 - Operand2);
      break;
      case 2: // *
        sprintf (Answer, "%s = %d\n", Expression, Operand1 * Operand2);
      break;
      case 3: // /
        if (Operand2 = 0)
        {
          sprintf (Answer, "Sorry, division by Zero is not implemented yet.\n");
        } else sprintf (Answer, "%s = %d\n", Expression, Operand1 / Operand2);
      break;
      default:
        sprintf (Answer, "Error in Expression. Please use as \"Operand1 [+, -, *, /] Operand2\".\n");
      break;
    };
  };
  return lOperation;
};

static ssize_t DevWrite (struct file * _File, const char __user * _Buffer, size_t _Count, loff_t *_PPos)
{ // Функция отвечает за запись в устройство.
  memcpy (&Expression[0], &_Buffer[0], _Count);
  Expression[_Count] = 0;
  // Вычисляем заданное выражение:
  Calculate ();
  // Нужно вернуть количество записавшихся (или полученных) байт.
  // Иначе будет цикл бесконечной записи в устройство.
  // Видимо кернел продолжает попытки записать в устройство если возвращать 0.
  // Если устройство вообще не желает принимать данные, нуж но вернуть -EINVAL.
  // Но это будет обрабатываться именно как ошибка:
  // echo -n "123" > /dev/coffee
  // bash: echo: write error: Invalid argument
  // Мы выбираем самый приемлемый для нас вариант:
  return _Count;
};

static ssize_t DevRead (struct file * _File, char __user * _Buffer, size_t _Count, loff_t *_PPos)
{ // Функция отвечает за чтение из устройства.
  size_t BytesWritten = strlen (Answer) - *_PPos;
  // Проверяем чтобы запрашиваемая позиция в фаиле не выходила за его размер,
  // чтобы предоставляемый буффер был достаточного размера
  // и чтобы буффер вообще существовал. Если что-то не так, возвращаем 0
  // как признак конца фаила.
  if ((*_PPos > strlen (Answer)) || (_Count < strlen (Expression))
       || (!_Buffer)) return 0;
  // Т.к. буфер данных находится в пространсвте пользователя,
  // а мы находимся в пространстве ядра, то для копирования
  // данных в буфер пользователя мы используем функцию copy_to_user:
  if (BytesWritten != 0)
  {
    if (_Count < BytesWritten) BytesWritten = _Count;
    copy_to_user (_Buffer, Answer + *_PPos, BytesWritten);
    *_PPos += BytesWritten;
  }
  return BytesWritten;
};

static ssize_t DevRelease (struct inode *_INode, struct file *_File)
{
  module_put (THIS_MODULE);
  return 0;
};

static ssize_t DevOpen (struct inode *_INode, struct file *_File)
{
  try_module_get (THIS_MODULE);
  return 0;
};

static const struct file_operations DevOps {
  // Здесь мы задаём фнкции, отвечающие за операции с нашим устройством
  // и указываем адреса процедур отвечающих за эти операции.
  // В нашем случае - чтение из устройства, запись в него и отработка обращений.
  .owner = THIS_MODULE,
  .read  = DevRead,
  .write = DevWrite,
  .release = DevRelease,
  .open = DevOpen
};

int init (void)
{
  printk (KERN_INFO "Given Parameter String is \"%s\".\n", ParamStr);
  // Запрашиваем динамический старший номер устройства (драйвера - т.е. нас).
  // В случае успеха, функция вернет Device Major.
  DevMajor = register_chrdev (0, DeviceName, &DevOps);
  if ((DevMajor) < 0)
  {
    printk (KERN_ERR "Error! Char Device Could not be Registerd.\n");
    // В любом случае, вернем то что получилось. Пусть лубуются.
    return DevMajor;
  };
  printk ("Use 'mknod /dev/%s c %d 0' to create device file.\n", DeviceName, DevMajor);
  // Если вернуть ненулевое значение, то это будет воспринято как ошибка,
  // возникшая в процессе работы init_module; и модуль не будет загружен.
  sprintf (Expression, "Empty Expression.\n");
  sprintf (Answer, "Empty Answer.\n");
  return 0;
}

void cleanup (void)
{
  // Освобождаем номер, выданный нам ранее.
  // С версии 2.6.23 unregister_chrdev возвращает void т.е. ничего.
  // Нет возможности проконтролировать работу этой функции.
  printk (KERN_INFO "unregister_chrdev ();");
  unregister_chrdev (DevMajor, DeviceName);
}

// Начиная с версии 2.3.13, требования к именованию начальной и конечной функций
// модуля были сняты. Достигается это с помощью макроопределений module_init()
// и module_exit(). Воспользуемся этим, т.к. теперь это считается правильно:
module_init (init);
module_exit (cleanup);
// Описание модуля (может быть прочтено программой modinfo):
MODULE_LICENSE("GPL");                    // Нужно для функции class_create.
MODULE_AUTHOR("Timofey Chernigovskiy");   // Автор.
MODULE_DESCRIPTION("Math-Device Module"); // Описание.
MODULE_VERSION("0.1");                    // Версия.
MODULE_SUPPORTED_DEVICE(DeviceName);      // Тип устройств поддерживаемых модулем.

--
To unsubscribe from this list: send the line "unsubscribe linux-hotplug" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2010-08-24  9:27 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2010-08-19 15:07 Re[2]: UDEV Тима
2010-08-24  9:27 ` Тима

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.