Я новичок, пытающийся закодировать последовательный драйвер (на основе PCI), и я не хочу использовать container_of()
из-за отсутствия обратной совместимости. Версию ядра я могу скомпилировать
будет <2.6.x, поэтому я хочу сделать его совместимым с большинством старых и новых версий. </p>
я хочу получить доступ к элементу (ам) структуры драйвера последовательной карты. Структура является пользовательской, содержащей атомарную переменную, например - use_count и связанную с ней операцию - atomic_inc(&serial_card->use_count)
. Я не хочу получать доступ их с помощью функции container_of()
, которая даст мне содержащую структуру
Есть ли какая-нибудь альтернатива функции container_of (). Если я не ошибаюсь, текст драйверов драйверов LINux от Аллесандро Рубини описывает путь на странице № 174 | Глава 6: Расширенные операции с драйверами Char.
Но я все еще исправлен о том, как назначить что-то вроде struct scull_dev *dev = &scull_s_device
.
если сама структура содержит переменную типа struct pc_device *dev
, вышеприведенный оператор заполняет аналогичную переменную, которая присваивается dev,
в моем случае я объявил структуру и связанную функцию, как показано ниже
struct serial_card
{
unsigned int id; // to identify the each card
//atomic_t use_count; // variable used to check whether the device is already opened or not
wait_queue_head_t rx_queue[64]; // queue in which the process are stored
unsigned int data_ready[64]; // queue in which the process is ready
unsigned int rx_chan; // used by interrupt handler
unsigned int base, len; // holds physical base address , holds the total area ( for each card )
unsigned int *base; // holds virtual address
/*struct cdev cdev; // kernel uses this structure to represent the EACH char device
not using the new method to represent char devices in kernel instead using the old method of register_chrdev();*/
struct pci_dev *device; // pci_dev structure for EACH device.
//struct semaphore sem; //Semaphore needed to handle the co-ordination of processes,use incase need arises
};
static struct serial_card *serial_cards; // pointer to array of structures [ depending on number of cards ],NO_OF_CARDS #defined in header file
static int serialcard_open(struct inode *inode,struct file *filep)
{
//getting the structure details of type struct serialcard,using the pointer inode->i_cdev and field type cdev
//struct serial_card *serial_cards = container_of(inode->i_cdev, struct serial_card, cdev);
// read the current value of use_count
static int Device_Open = 0;
if ( Device_Open ) //Device_Open is static varibale used here for checking the no of times a device is opened
{
printk("cPCIserial: Open attempt rejected\n");
return -EBUSY;
}
Device_Open++;
// using the card so increment use_count
//atomic_inc(&serial_cards->use_count);
//filep->private_data = serial_cards;
return 0;
}
полное описание на стр. 174 - 175 выглядит следующим образом
одноразовые устройства
Грубым способом обеспечения контроля доступа является разрешение устройства открываться
только один процесс за раз (одна открытость). Эту технику лучше избегать, потому что она
подавляет изобретательность пользователя. Пользователь может захотеть запустить разные процессы на одном и том же
устройство, одно считывает информацию о состоянии, а другое записывает данные. В некоторых случаях,
пользователи могут многое сделать, запустив несколько простых программ через скрипт оболочки, как
Пока они могут получить доступ к устройству одновременно. Другими словами, реализация SingleOpen
поведение сводится к созданию политики, которая может помешать тому, что ваши
пользователи хотят сделать. Разрешение только одному процессу открывать устройство имеет нежелательные свойства, но это также самый простой способ управления доступом для драйвера устройства, поэтому он показан здесь.
Исходный код извлекается из устройства под названием scullsingle.
Устройство scullsingle поддерживает переменную atomic_t с именем scull_s_available; тот
переменная инициализируется значением 1, указывающим, что устройство действительно доступно.
Открытый вызов уменьшает и проверяет scull_s_available и отказывает в доступе, если кто-то
еще устройство уже открыто:
static atomic_t scull_s_available = ATOMIC_INIT(1);
static int scull_s_open(struct inode *inode, struct file *filp)
{
struct scull_dev *dev = &scull_s_device; /* device information */
if (! atomic_dec_and_test (&scull_s_available)) {
atomic_inc(&scull_s_available);
return -EBUSY; /* already open */
}
/* then, everything else is copied from the bare scull device */
if ( (filp->f_flags & O_ACCMODE) = = O_WRONLY) {
scull_trim(dev);
filp->private_data = dev;
return 0; /* success */
}
С другой стороны, разъединительный звонок помечает устройство как не занятое:
static int scull_s_release(struct inode *inode, struct file *filp)
{
atomic_inc(&scull_s_available); /* release the device */
return 0;
}
Обычно мы рекомендуем ставить флаг открытия scull_s_available внутри
device structure (Scull_Dev here)
потому что концептуально это относится к устройству.
Драйвер scull, однако, использует автономные переменные для хранения флага, чтобы он мог использовать тот же
структура и методы устройства как устройство с открытым исходным кодом и минимизация дублирования кода.
Пожалуйста, дайте мне знать любую альтернативу для этого
спасибо и всего наилучшего