Назначить драйвер PCI-устройству
#include <hw/pci.h>void * pci_attach_device( void *handle,uint32_t flags,uint16_t idx,struct pci_dev_info *info );
NULL
. Функция возвращает дескриптор, который вы можете использовать в последующем вызове для выделения ресурсов для устройства.0
для первого устройства, 1
для второго и так далее.libc
Функция pci_attach_device() подключает драйвер к устройству PCI.
Необходимо добиться успешного выполнения функции 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() ранее выделил освобождаются.
Функция pci_attach_device() не отображает какие-либо области ввода-вывода или памяти в адресное пространство процесса. Адреса, возвращаемые в struct pci_dev_info, являются физическими адресами. |
Флаги
Параметр flags сообщает серверу PCI, как следует обрабатывать ресурсы, какие ресурсы следует искать и выделять
Эти биты управляют тем, как обрабатываются ресурсы:
Следующие биты управляют поиском устройств PCI сервером на основе указанных вами полей в структуре, на которую указывает info:
Эти биты определяют, какие элементы структуры сервер должен инициализировать:
К битам также относятся:
Если вы передаете 0
для флагов, по умолчанию используется PCI_SEARCH_VENDEV
.
Проверка и конвертация адресов
Контроль и преобразование адресов подробно рассмотрено на странице struct pci_dev_info.
Дескриптор, который будет использоваться для других вызовов pci_*(), связанных с дескриптором.
Если возникла ошибка функция возвращает NULL
, код ошибки записывается в errno.
PCI_SHARE
в поле flags. Подключение и выделениее всех необходимых ресурсов для первого появления адаптера 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()
Предыдущий раздел: Описание API системной библиотеки