Как драйверу застолбить за собой ресурс
От: Alexius-R СССР  
Дата: 11.11.10 08:34
Оценка:
Здравствуйте

Эта тема является логическим продолжением указанной ниже темы, однако выделяю ее в отдельный поток, потому что вопрос будет немного о другом.
http://rsdn.ru/forum/asm/4011385.1.aspx
Автор: Alexius-R
Дата: 25.10.10


Итак, еще раз:
"Есть SMbus контроллер в составе AMD CS5536 устройства (PCI\VEN_1022&DEV_2090)
Хочется получить в драйвере базовый адрес для SMBus, чтобы потом управлять этим устройством."

Базовый адрес получил по методу подсказанному Геннадием Майко в предыдущей теме при помощи "старых добрых функций HalGetBusData и HalGetBusDataByOffset".
Драйвер в итоге работает, однако как и упоминалось в предыдущей, теме ресурсов никаких не занимает, а хотелось бы, чтобы в диспетчере устройств честно было указано,
что драйвер занимает с такого-то по такой-то адреса ввода/вывода.

В IRP_MN_START_DEVICE и IRP_MN_FILTER_RESOURCE_REQUIREMENTS приходят нули вместо ресурсов.

Что пытаюсь делать:
Уолтер Они в своей замечательной книжке (Глава 6 в под параграфе "Фильтрация требований к ресурсам" )показывает как добавить в запросе свой ресурс К СПИСКУ УЖЕ ИМЕЮЩИХСЯ в обработке IRP_MN_FILTER_RESOURCE_REQUIREMENTS.
Однако когда я взял его код, кое-что подкрутил и пытаюсь добавить вместо пришедшего нуля свой список получаю STATUS_NOT_SUPPORTED.

Хотелось бы знать во-первых оценку, можно ли так делать, и если так делать можно, то в чем может быть ошибка? Привожу код:
NTSTATUS SmbHandleFilterResources(PDEVICE_OBJECT DeviceObject, PIRP Irp)
{
    NTSTATUS status;
    PIO_STACK_LOCATION irpStack = IoGetCurrentIrpStackLocation(Irp);
    PIO_RESOURCE_REQUIREMENTS_LIST original;
    PIO_RESOURCE_REQUIREMENTS_LIST filtered; 
    PIO_RESOURCE_REQUIREMENTS_LIST source;
    PIO_RESOURCE_REQUIREMENTS_LIST newlist;
    PIO_RESOURCE_DESCRIPTOR resource = NULL;
    PSMB_DEVICE_EXTENSION pDeviceExtension = (PSMB_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
    PCI_COMMON_CONFIG config = {0};
    PCI_SLOT_NUMBER slot = {0};
    ULONG sizelist;

    original = irpStack->Parameters.FilterResourceRequirements.IoResourceRequirementList; //здесь NULL
    filtered = (PIO_RESOURCE_REQUIREMENTS_LIST) Irp->IoStatus.Information;                //и здесь NULL
    source = filtered ? filtered : original;                                              //ну и здесь NULL
    sizelist = (source) ? source->ListSize : 0;

//следующая функция ищет необходимую запись в pci configuration space по заданному Vendor и Device id и возвращает слот и собственно запись
    status = FindConfigByVendorAndDeviceID(SMB_VENDOR_ID_AMD_CS5536, SMB_DEVICE_ID_AMD_CS5536, &config, &slot);
    if(NT_SUCCESS(status))
    {
        sizelist = sizelist ? (sizelist + sizeof(IO_RESOURCE_DESCRIPTOR)) : 
            sizeof(IO_RESOURCE_REQUIREMENTS_LIST); 

        newlist = (PIO_RESOURCE_REQUIREMENTS_LIST) ExAllocatePool(PagedPool, sizelist);

        if (!newlist)
            return STATUS_UNSUCCESSFUL;

        RtlZeroMemory(newlist, sizelist);

        if (source)
        {
            memcpy(newlist, source, sizelist);
            newlist->ListSize += sizeof(IO_RESOURCE_DESCRIPTOR);
        }
        else
        {
            newlist->ListSize = sizelist;
            newlist->SlotNumber = slot.u.AsULONG;
            newlist->List[0].Count = 0;
            newlist->List[0].Version = 1;
            newlist->List[0].Revision = 1;
        }            

        resource = &newlist->List[0].Descriptors[newlist->List[0].Count++];
        resource->Option = 0;
        resource->Flags = CM_RESOURCE_PORT_IO|CM_RESOURCE_PORT_16_BIT_DECODE;;
        resource->u.Port.Length = 8; //пространство ввода/вывода с 0xF000 до 0xF008
        resource->u.Port.Alignment = 0x01; 
        resource->u.Port.MinimumAddress.QuadPart = pDeviceExtension->Base; //0xF000 найден ранее
        resource->u.Port.MaximumAddress.QuadPart = pDeviceExtension->Base + resource->u.Memory.Length; //Base+8h
        resource->Type = CmResourceTypePort;
        resource->ShareDisposition = CmResourceShareDeviceExclusive;
        Irp->IoStatus.Information = (ULONG_PTR) newlist;
        if(filtered && filtered != original)
            ExFreePool(filtered);
    }
    
//а эта функция полностью соответствует функции Уолтера Они и всего лишь отправляет IRP ниже и ждет когда запрос вернется обратно, при этом его не завершая пока
    status = SmbForwardAndWait(pDeviceExtension, Irp);
    if(NT_SUCCESS(status))
    {
             //ничего пока не делаю
    }
    return status; //ВОТ ЗДЕСЬ ПОЛУЧАЮ STATUS_NOT_SUPPORTED ???!!!
}
pci configuration space resource базовый адрес
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.