Форум программистов «Весельчак У»
  *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

  • Рекомендуем проверить настройки временной зоны в вашем профиле (страница "Внешний вид форума", пункт "Часовой пояс:").
  • У нас больше нет рассылок. Если вам приходят письма от наших бывших рассылок mail.ru и subscribe.ru, то знайте, что это не мы рассылаем.
   Начало  
Наши сайты
Помощь Поиск Календарь Почта Войти Регистрация  
 
Страниц: [1]   Вниз
  Печать  
Автор Тема: pci-express и extended configuration space  (Прочитано 10754 раз)
0 Пользователей и 1 Гость смотрят эту тему.
kiara
Гость
« : 11-09-2008 13:00 » 

Добрый день!
Мне необходимо из драйвера (под Windows XP) читать (писать) в extended configuration space девайса на шине PCI-EXPRESS
Пытаюсь использовать Numega Driver Studio. Сделал вот такую нехитрую функцию:
u8 pci_read_byte(struct pci_dev * dev, int pos) /* Access to configuration space */
{
      KPciConfiguration cfg(dev->bus,dev->dev,dev->func);

      char ret=0;
      cfg.ReadHeader(&ret,pos,1);
      if(pos >255)
      {
         KdPrint(("rb from 0x%04x : 0x%02x\n",pos,ret));
      }

      return ret;

}

при чтении из обычного конфиг. пр-ва pci (pos<256) всё прекрасно, при больших значениях выдаётся явно не то. Помогите, пожалуйста!
Спасибо!
Записан
Ochkarik
Модератор

ru
Offline Offline
Пол: Мужской

« Ответ #1 : 11-09-2008 14:01 » 

не забивайте мозг ерундой...

пример приведен в DDK
"Obtaining Device Configuration Information at IRQL = PASSIVE_LEVEL"
Код:
Obtaining Device Configuration Information at IRQL = PASSIVE_LEVEL
To access device configuration space at IRQL = PASSIVE_LEVEL, you must use IRP_MN_READ_CONFIG and IRP_MN_WRITE_CONFIG.
You indicate in the IRP stack which configuration space you wish to access and where the I/O buffer is.
See the description of the IO_STACK_LOCATION structure for further details.

The following code sample demonstrates how to access a device's configuration space.


NTSTATUS
ReadWriteConfigSpace(
    IN PDEVICE_OBJECT DeviceObject,
    IN ULONG      ReadOrWrite, // 0 for read 1 for write
    IN PVOID      Buffer,
    IN ULONG      Offset,
    IN ULONG      Length
    )
{
    KEVENT event;
    NTSTATUS status;
    PIRP irp;
    IO_STATUS_BLOCK ioStatusBlock;
    PIO_STACK_LOCATION irpStack;
    PDEVICE_OBJECT targetObject;

    PAGED_CODE();
    KeInitializeEvent( &event, NotificationEvent, FALSE );
    targetObject = IoGetAttachedDeviceReference( DeviceObject );
    irp = IoBuildSynchronousFsdRequest( IRP_MJ_PNP,
                                        targetObject,
                                        NULL,
                                        0,
                                        NULL,
                                        &event,
                                        &ioStatusBlock );
    if (irp == NULL) {
        status = STATUS_INSUFFICIENT_RESOURCES;
        goto End;
    }
    irpStack = IoGetNextIrpStackLocation( irp );
    if (ReadOrWrite == 0) {
        irpStack->MinorFunction = IRP_MN_READ_CONFIG;
    }else {
        irpStack->MinorFunction = IRP_MN_WRITE_CONFIG;
    }
    irpStack->Parameters.ReadWriteConfig.WhichSpace = PCI_WHICHSPACE_CONFIG;
    irpStack->Parameters.ReadWriteConfig.Buffer = Buffer;
    irpStack->Parameters.ReadWriteConfig.Offset = Offset;
    irpStack->Parameters.ReadWriteConfig.Length = Length;
    // Initialize the status to error in case the bus driver does not
    // set it correctly.
    irp->IoStatus.Status = STATUS_NOT_SUPPORTED ;
    status = IoCallDriver( targetObject, irp );
    if (status == STATUS_PENDING) {
        KeWaitForSingleObject( &event, Executive, KernelMode, FALSE, NULL );
        status = ioStatusBlock.Status;
    }
End:
    // Done with reference
    ObDereferenceObject( targetObject );
    return status;
}

и
"Obtaining Device Configuration Information at IRQL = DISPATCH_LEVEL"
копировать не буду.


PS
НУ ЗАЧЕМ!? зачем вы используете чужие, плоходокументированные, криво работающие классы в драйверах?!?!?!
« Последнее редактирование: 11-09-2008 14:50 от Ochkarik » Записан

RTFM уже хоть раз наконец!  RTFM :[ ну или хотя бы STFW...
Ochkarik
Модератор

ru
Offline Offline
Пол: Мужской

« Ответ #2 : 11-09-2008 14:56 » 

а кроме того...
KPciConfiguration::ReadHeader
  Count - Number of bytes to transfer. Default is sizeof(PCI_CONFIG_HEADER_0).
Comments
The function is guaranteed not to access any area of the configuration space other than that specified by the arguments.
See Also
WriteHeader, ReadDeviceSpecificConfig


KPciConfiguration::ReadDeviceSpecificConfig
  Comments
The configuration space of a PCI device is a total of 256 bytes. The PCI specification defines the format of the first 64 bytes (cf. Type PCI_CONFIG_HEADER_0). The format of the remaining 192 bytes is device specific. This function is provided for accessing the device specific area of the configuration space.

а теперь внимание вопрос:
а поддержан ли в классах нумеги размер более 256?

PS и... плата разве обязана отдавать больше? там же только хедер обязателен. большее - на усмотрение производителя
« Последнее редактирование: 11-09-2008 19:23 от Ochkarik » Записан

RTFM уже хоть раз наконец!  RTFM :[ ну или хотя бы STFW...
kiara
Гость
« Ответ #3 : 22-09-2008 12:42 » 

не забивайте мозг ерундой...

пример приведен в DDK
"Obtaining Device Configuration Information at IRQL = PASSIVE_LEVEL"
Код:
Obtaining Device Configuration Information at IRQL = PASSIVE_LEVEL
To access device configuration space at IRQL = PASSIVE_LEVEL, you must use IRP_MN_READ_CONFIG and IRP_MN_WRITE_CONFIG.
You indicate in the IRP stack which configuration space you wish to access and where the I/O buffer is.
See the description of the IO_STACK_LOCATION structure for further details.

The following code sample demonstrates how to access a device's configuration space.


NTSTATUS
ReadWriteConfigSpace(
    IN PDEVICE_OBJECT DeviceObject,
    IN ULONG      ReadOrWrite, // 0 for read 1 for write
    IN PVOID      Buffer,
    IN ULONG      Offset,
    IN ULONG      Length
    )
{
    KEVENT event;
    NTSTATUS status;
    PIRP irp;
    IO_STATUS_BLOCK ioStatusBlock;
    PIO_STACK_LOCATION irpStack;
    PDEVICE_OBJECT targetObject;

    PAGED_CODE();
    KeInitializeEvent( &event, NotificationEvent, FALSE );
    targetObject = IoGetAttachedDeviceReference( DeviceObject );
    irp = IoBuildSynchronousFsdRequest( IRP_MJ_PNP,
                                        targetObject,
                                        NULL,
                                        0,
                                        NULL,
                                        &event,
                                        &ioStatusBlock );
    if (irp == NULL) {
        status = STATUS_INSUFFICIENT_RESOURCES;
        goto End;
    }
    irpStack = IoGetNextIrpStackLocation( irp );
    if (ReadOrWrite == 0) {
        irpStack->MinorFunction = IRP_MN_READ_CONFIG;
    }else {
        irpStack->MinorFunction = IRP_MN_WRITE_CONFIG;
    }
    irpStack->Parameters.ReadWriteConfig.WhichSpace = PCI_WHICHSPACE_CONFIG;
    irpStack->Parameters.ReadWriteConfig.Buffer = Buffer;
    irpStack->Parameters.ReadWriteConfig.Offset = Offset;
    irpStack->Parameters.ReadWriteConfig.Length = Length;
    // Initialize the status to error in case the bus driver does not
    // set it correctly.
    irp->IoStatus.Status = STATUS_NOT_SUPPORTED ;
    status = IoCallDriver( targetObject, irp );
    if (status == STATUS_PENDING) {
        KeWaitForSingleObject( &event, Executive, KernelMode, FALSE, NULL );
        status = ioStatusBlock.Status;
    }
End:
    // Done with reference
    ObDereferenceObject( targetObject );
    return status;
}

и
"Obtaining Device Configuration Information at IRQL = DISPATCH_LEVEL"
копировать не буду.


PS
НУ ЗАЧЕМ!? зачем вы используете чужие, плоходокументированные, криво работающие классы в драйверах?!?!?!


1.Для вызова предложенной Вами ReadWriteConfigSpace(...) требуется значение DeviceObject. У меня драйвер не Wdm. Поэтому есть только bus, dev и func моего физического устройства (предварительно найденного по конкретным vend_id и dev_id). Можно не пользоваться "плохо документированым и чужим" KPciConfiguration::ReadDeviceSpecificConfig(...),а просто вызвать
ULONG
  HalGetBusDataByOffset(
    IN BUS_DATA_TYPE  BusDataType,
    IN ULONG  BusNumber,
    IN ULONG  SlotNumber,
    IN PVOID  Buffer,
    IN ULONG  Offset,
    IN ULONG  Length
    );
хотя несчастная Нумега делает то же самое.
Вот только результат будет тем же- дальше 256 наступает смещение 0.
Подскажите, как получить необходимый DeviceObject для вызова ReadWriteConfigSpace?
Записан
Ochkarik
Модератор

ru
Offline Offline
Пол: Мужской

« Ответ #4 : 22-09-2008 13:08 » 

гы)
а какойу вас драйвер? KWDF? UWDF?

KDevice::operator PDEVICE_OBJECT( )
« Последнее редактирование: 22-09-2008 13:31 от Ochkarik » Записан

RTFM уже хоть раз наконец!  RTFM :[ ну или хотя бы STFW...
kiara
Гость
« Ответ #5 : 22-09-2008 14:24 » 

гы)
а какойу вас драйвер? KWDF? UWDF?

KDevice::operator PDEVICE_OBJECT( )
Нет, я всё-таки не совсем ещё дошёл до ручки:))
Драйвер обычный, если угодно- generic, т.е. KDevice и соответствующий DeviceObject   создаётся в DriverEntry и никакого отношения к искомому pdevice не имеет.
Записан
Ochkarik
Модератор

ru
Offline Offline
Пол: Мужской

« Ответ #6 : 22-09-2008 16:03 » 

пардон, я почему то подумал, что вы драйвер к стеку запрашиваемого устройства все таки подключаете... 
тогда боюсь их все перпечислять надо по очереди...
« Последнее редактирование: 22-09-2008 16:44 от Ochkarik » Записан

RTFM уже хоть раз наконец!  RTFM :[ ну или хотя бы STFW...
Ochkarik
Модератор

ru
Offline Offline
Пол: Мужской

« Ответ #7 : 11-10-2008 18:52 » 

получилось что нибудь?
Записан

RTFM уже хоть раз наконец!  RTFM :[ ну или хотя бы STFW...
Страниц: [1]   Вверх
  Печать  
 

Powered by SMF 1.1.21 | SMF © 2015, Simple Machines