pci_attach_device()

Назначить драйвер PCI-устройству

Прототип:

#include <hw/pci.h>
void * pci_attach_device( void *handle,
uint32_t flags,
uint16_t idx,
struct pci_dev_info *info );

Аргументы:

handle
Дескриптор, идентифицирующий устройство. При первом вызове этой функции установите дескриптор handle на NULL. Функция возвращает дескриптор, который вы можете использовать в последующем вызове для выделения ресурсов для устройства.
flags
Флаги, которые сообщают серверу PCI, желаемый способ инициализации ресурсов и их перечень. какие ресурсы искать, и какие выделять.
idx
Индекс устройства: 0 для первого устройства, 1 для второго и так далее.
info
Указатель на структуру struct pci_dev_info, который определяет код класса, идентификатор производителя/устройства или номер шины и номер устройства/функции, которые необходимо найти. Функция заполняет эту структуру информацией об устройстве.

Библиотека:

libc

Описание:

Функция pci_attach_device() подключает драйвер к устройству PCI.


Note: Необходимо добиться успешного выполнения функции pci_attach() перед вызовом любой другой функции PCI.

Обычно драйверы используют эту функцию для подключения к устройству PCI, чтобы другие драйверы не могли подключаться к одному и тому же устройству. Если указать флаг PCI_SHARE, то несколько драйверов могут подключаться к одному и тому же устройству.

Сервер может выполнять поиск на основе кода класса, идентификатора производителя, идентификатора производителя и идентификатора устройства, номера шины и номера функции устройства. Для управления опрашиванием сервера инициализируйте соответствующие поля в структуре info и установите соответствующие флаги.

Когда впервые выполняется подключение к неинициализированному устройству, сервер PCI назначает все порты ввода-вывода, память и IRQ, необходимые для устройства. Он также выполняет маршрутизацию IRQ. Как только эти процессы завершаются успешно, он заполняет все необходимые значения в структуре struct pci_dev_info чтобы вернуть их приложению.

Когда драйвер подключается к устройству, сервер PCI выделяет необходимые ресурсы для устройства из procnto-* с помощью вызовов rsrcdbmgr*(). В системах X86 BIOS эти ресурсы обычно выделяются с помощью BIOS, но в системах, отличных от x86, эти ресурсы должны быть выделены procnto-*.

Отключить драйвер от устройства можно, передав его дескриптор в pci_detach_device(). Если вызывается pci_detach(), любые ресурсы, которые pci_attach_device() ранее выделил освобождаются.


Note: Функция pci_attach_device() не отображает какие-либо области ввода-вывода или памяти в адресное пространство процесса. Адреса, возвращаемые в struct pci_dev_info, являются физическими адресами.

Флаги

Параметр flags сообщает серверу PCI, как следует обрабатывать ресурсы, какие ресурсы следует искать и выделять

Эти биты управляют тем, как обрабатываются ресурсы:

PCI_SHARE
Разрешить совместное использование ресурсов с другими драйверами. Если этот параметр не установлен, другие драйверы не смогут подключиться к устройству.
PCI_PERSIST
Ресурсы сохраняются после отключения устройства.

Следующие биты управляют поиском устройств PCI сервером на основе указанных вами полей в структуре, на которую указывает info:

PCI_SEARCH_VEND
Идентификатор производителя VendorID
PCI_SEARCH_VENDEV
Идентификатор устройства DeviceId и идентификатор производителя VendorId
PCI_SEARCH_CLASS
Код класса Class
PCI_SEARCH_BUSDEV
Номер шины BusNumber и номер функции DevFunc

Эти биты определяют, какие элементы структуры сервер должен инициализировать:

PCI_INIT_IRQ
Irq
PCI_INIT_ROM
PciRom and CpuRom
PCI_INIT_BASE0 ... PCI_INIT_BASE5
Определенные записи массивов PciBaseAddress и CpuBaseAddress
PCI_INIT_ALL
Все виды элементов структуры, кроме PciRom и CpuRom

К битам также относятся:

PCI_MASTER_ENABLE
Разрешить мастеринг шины на устройстве.

Если вы передаете 0 для флагов, по умолчанию используется PCI_SEARCH_VENDEV.

Проверка и конвертация адресов

Контроль и преобразование адресов подробно рассмотрено на странице struct pci_dev_info.

Возвращаемое значение:

Дескриптор, который будет использоваться для других вызовов pci_*(), связанных с дескриптором.

Если возникла ошибка функция возвращает NULL, код ошибки записывается в errno.

Коды ошибок:

EBUSY
Приложение уже подключено к устройству. Если совместное использование устройства безопасно, укажите PCI_SHARE в поле flags.
EINVAL
Функция не смогла присоединить ресурс к устройству.
ENODEV
Это устройство не найдено.

Примеры:

Подключение и выделениее всех необходимых ресурсов для первого появления адаптера Adaptec 2940:

#include <hw/pci.h>
#include <hw/pci_devices.h>
#include <stdio.h>
#include <stdlib.h>
int main( void )
{
int pidx;
void *hdl;
int phdl;
struct pci_dev_info inf;
/* Connect to the PCI server */
phdl = pci_attach( 0 );
if ( phdl == -1 )
{
fprintf( stderr, "Unable to initialize PCI\n" );
return (EXIT_FAILURE);
}
/* Initialize the pci_dev_info structure */
memset( &inf, 0, sizeof( inf ) );
pidx = 0;
inf.VendorId = PCI_VENDOR_ID_ADAPTEC;
inf.DeviceId = PCI_DEVICE_ID_ADAPTEC_2940F;
hdl = pci_attach_device( NULL, PCI_INIT_ALL, pidx, &inf );
if ( hdl == NULL )
{
fprintf( stderr, "Unable to locate adapter\n" );
} else {
/* Do something to the adapter */
pci_detach_device( hdl );
}
/* Disconnect from the PCI server */
pci_detach( phdl );
return (EXIT_SUCCESS);
}

Присоединение к первому экземпляру адаптера Adapter 2940 и выделение ресурсов во втором вызове:

#include <hw/pci.h>
#include <hw/pci_devices.h>
#include <stdio.h>
#include <stdlib.h>
int main( void )
{
int pidx;
void *hdl;
void *retval;
int phdl;
struct pci_dev_info inf;
phdl = pci_attach( 0 );
if ( phdl == -1 )
{
fprintf( stderr, "Unable to initialize PCI\n" );
return (EXIT_FAILURE);
}
memset( &inf, 0, sizeof( inf ) );
pidx = 0;
inf.VendorId = PCI_VENDOR_ID_ADAPTEC;
inf.DeviceId = PCI_DEVICE_ID_ADAPTEC_2940F;
hdl = pci_attach_device( NULL, 0, pidx, &inf );
if ( hdl == NULL )
{
fprintf( stderr, "Unable to locate adapter\n" );
}
retval = pci_attach_device( hdl, PCI_INIT_ALL, pidx, &inf );
if ( retval == NULL )
{
fprintf( stderr, "Unable allocate resources\n" );
}
pci_detach( phdl );
return (EXIT_SUCCESS);
}

Классификация:

ЗОСРВ «Нейтрино»

Точка остановки потока
Да
Обработчик прерываний
Нет
Обработчик сигналов
Да
В потоке
Да

Тематические ссылки:

struct pci_dev_info, pci_attach(), pci_detach(), pci_detach_device(), pci_find_class(), pci_find_device(), pci_present(), pci_read_config(), pci_read_config8(), pci_read_config16(), pci_read_config32(), pci_rescan_bus(), pci_write_config()

procnto-*




Предыдущий раздел: Описание API системной библиотеки