다음을 통해 공유


스토리지 클래스 드라이버의 BuildRequest 루틴

모든 상위 수준 커널 모드 드라이버와 마찬가지로 스토리지 클래스 드라이버는 스토리지 주변 디바이스에 대한 요청을 처리할 때 다음 하위 드라이버에 대한 IRP의 I/O 스택 위치를 설정해야 합니다. 클래스 드라이버가 시스템에서 제공하는 포트 드라이버에 대해 SRB로 설정하는 IRP에서 포트 드라이버의 I/O 스택 위치는 다음과 같이 설정됩니다.

  • MajorFunction 에는 IRP_MJ_SCSI 포함됩니다.

  • Parameters.Scsi.Srb 에는 SRB에 대한 포인터가 포함되어 있습니다.

각 클래스 드라이버는 SRB에 대한 메모리를 할당하고 기본 스토리지 포트 드라이버에 대한 CDB를 사용하여 설정하는 작업을 담당합니다. 클래스 드라이버는 ExInitializeNPageLookasideList 를 사용하여 해당 SRB에 대한 lookaside 목록을 설정하거나 페이지가 없는 메모리에 대해 ExAllocatePool을 호출할 수 있습니다. lookaside 목록 및 비페이지 풀 사용에 대한 자세한 내용은 Lookaside 목록 사용을 참조하세요.

풀에서 메모리를 할당하든 드라이버에서 만든 lookaside 목록에서든 모든 스토리지 클래스 드라이버는 SRB에 할당된 메모리를 해제해야 합니다. 스토리지 클래스 드라이버의 IoCompletion 루틴에 설명된 스토리지 클래스 드라이버의 IoCompletion 루틴은 일반적으로 SRB에 할당된 메모리를 lookaside 목록으로 다시 해제합니다.

클래스 드라이버의 BuildRequest 루틴은 디바이스와 통신하도록 설정한 CDB의 길이를 포함하여 SRB 멤버에 적절한 값을 설정해야 합니다. 요청 감지 정보를 반환하거나 드라이버가 다시 시도해야 할 수도 있는 요청의 경우 IRP에서 IoCompletion 루틴을 설정합니다. 읽기 또는 쓰기 요청의 경우 SrbFlags 를 각각 적절한 전송 방향(SRB_FLAGS_DATA_IN 또는 SRB_FLAGS_DATA_OUT)으로 읽습니다.

BuildRequest 루틴은 SRB를 SendSrbSynchronousSendSrbAsynchronous 루틴 쌍과 함께 설정하는 책임을 공유할 수 있습니다. 즉, BuildRequest 루틴은 모든 요청에 대해 일반적으로 설정된 SRB 멤버를 설정할 수 있지만 SendSrbXxx 루틴은 각 요청 유형에만 SRB 값을 설정합니다. IRP가 SendSrbAsynchronous 루틴에서 포트 드라이버로 전달되면 드라이버 제공 IoCompletion 루틴을 사용하여 IRP를 설정해야 합니다.

클래스 드라이버가 로드된 후 함수 멤버가 SRB_FUNCTION_EXECUTE_SCSI 설정된 대부분의 SRB를 설정하여 버스를 통해 전송할 디바이스 I/O 요청을 나타냅니다.

시스템 정의 SRB 멤버 및 해당 값에 대한 자세한 내용은 SCSI_REQUEST_BLOCK 참조하세요.

요청 센스용 SRB 설정

클래스 드라이버는 대상 컨트롤러가 검사 조건을 반환할 때 포트 드라이버가 SCSI 요청 센스 또는 동등한 정보를 반환할 것을 요청할 수 있습니다. 이를 위해 클래스 드라이버는 SRB에서 SenseInfoBuffer 포인터 및 SenseInfoBufferLength를 설정하므로 포트 드라이버는 검사 조건이 발생하는 경우 요청 감지 정보를 반환할 수 있습니다. 포트 드라이버는 IRP를 반환할 때 SrbStatus 멤버를 SRB_STATUS_AUTOSENSE_VALID 설정하여 요청 감지 정보를 반환했음을 나타냅니다. InterpretSenseInfo 루틴에 대한 자세한 내용은 Storage 클래스 드라이버의 InterpretRequestSense 루틴을 참조하세요.

재시도

스토리지 클래스 드라이버는 대상/컨트롤러 오류, 버스 재설정 또는 요청 시간 제한으로 인해 실패한 요청을 다시 시도해야 합니다. 따라서 많은 클래스 드라이버는 IRP의 자체 I/O 스택 위치에서 재시도 횟수를 유지 관리합니다. 이러한 클래스 드라이버의 BuildRequest 루틴은 IoCompletion 루틴을 설정하고 IRP를 포트 드라이버로 보내기 전에 지정된 요청에 대한 재시도 제한을 초기화할 수도 있습니다. RetryRequest 루틴에 대한 자세한 내용은 스토리지 클래스 드라이버의 RetryRequest 루틴을 참조하세요.