SPB 프레임워크 확장(SpbCx)은 I/O 전송 시퀀스를 지원합니다. I/O 전송 시퀀스는 단일 원자 버스 작업으로 수행되는 순서가 지정된 버스 전송(읽기 및 쓰기 작업) 집합입니다. I/O 전송 시퀀스의 모든 전송은 버스의 동일한 대상 디바이스에 액세스합니다. 시퀀스를 수행하는 동안 SPB 컨트롤러 드라이버가 I/O 전송 시퀀스가 완료되기 전에 다른 디바이스에 대한 I/O 요청을 받을 수 있더라도 버스의 다른 디바이스에 액세스할 수 없습니다.
I/O 전송 시퀀스의 예로는 버스를 대상으로 한 쓰기 작업에 이어서 읽기 작업을 수행하는 쓰기-읽기 작업이 있습니다. 클라이언트 주변 장치 드라이버는 이러한 유형의 시퀀스를 사용하여 SPB에 연결된 주변 디바이스의 함수 선택 레지스터에 쓴 다음 선택한 디바이스 함수의 값을 읽을 수 있습니다. 이 두 전송은 길이가 다를 수 있습니다. 예를 들어 쓰기 작업은 1바이트의 데이터를 전송할 수 있으며 읽기 작업은 많은 바이트의 데이터를 전송할 수 있습니다.
I/O 전송 시퀀스 유형
클라이언트는 다음 방법 중 하나로 I/O 전송 시퀀스를 시작할 수 있습니다.
클라이언트는 IOCTL_SPB_EXECUTE_SEQUENCE I/O 컨트롤 요청에서 전체 시퀀스를 지정할 수 있습니다. 이 요청을 통해 SPB 컨트롤러 드라이버는 전송 시퀀스를 수행하는 데 사용할 수 있는 하드웨어별 성능 최적화를 사용할 수 있습니다. 자세한 내용은 Single-Request 시퀀스를 참조하세요.
클라이언트는 IOCTL_SPB_LOCK_CONTROLLER I/O 컨트롤 요청을 보내 시퀀스의 시작 부분에 컨트롤러를 잠그고 시퀀스가 완료되면 IOCTL_SPB_UNLOCK_CONTROLLER 보낼 수 있습니다. 컨트롤러가 잠겨 있는 동안 클라이언트는 시퀀스의 각 읽기 또는 쓰기 작업에 대해 별도의 I /O 요청( IRP_MJ_READ 또는 IRP_MJ_WRITE)을 보냅니다. 자세한 내용은 Client-Implemented 시퀀스를 참조하세요.
가능하면 클라이언트는 IOCTL_SPB_EXECUTE_SEQUENCE 요청을 사용해야 합니다. 이 요청은 오류 발생 가능성이 적고, 다른 클라이언트가 버스에 접근하지 못하는 시간을 현저히 줄입니다. 그러나 시퀀스의 전송 중 하나에서 읽은 값을 확인해야 하여 이후 전송을 시퀀스에서 시작할 수 있는 경우, 클라이언트는 IOCTL_SPB_LOCK_CONTROLLER 및 IOCTL_SPB_UNLOCK_CONTROLLER 요청을 사용할 수 있습니다. 이 경우 필요한 것보다 오랫동안 버스에서 다른 클라이언트를 잠그지 않도록 주의 깊게 설계해야 하며, 잘못 설계된 주변 장치 드라이버는 전반적인 시스템 성능을 저하시킬 수 있습니다.
Single-Request 시퀀스
성능을 향상시키려면 SPB 컨트롤러 드라이버가 EvtSpbControllerIoSequence 콜백 함수를 구현하여 IOCTL_SPB_EXECUTE_SEQUENCE 요청을 처리해야 합니다. 이 방법은 SPB 컨트롤러 드라이버에 복잡성을 더하지만 다른 클라이언트가 버스에서 잠긴 동안 클라이언트가 일련의 개별 읽기 및 쓰기 작업으로 I/O 전송 시퀀스를 수행하도록 요구하지 않습니다.
비고
EvtSpbControllerIoSequence 함수를 구현하는 것이 강력히 권장되며 Windows 8에 대한 요구 사항이 될 수 있습니다.
전송 시퀀스의 구현은 간단한 읽기 또는 쓰기 작업의 구현과 유사하지만 시퀀스의 개별 전송 간에 시퀀스 작업의 저장된 상태에 대한 업데이트가 추가로 필요합니다. 첫 번째 전송이 완료되면 SPB 컨트롤러 드라이버는 시퀀스 상태를 업데이트하여 시퀀스에서 다음 전송을 선택합니다. 시퀀스 상태는 디바이스 컨텍스트에 저장되며 EvtSpbControllerIoSequence 콜백에 전달되는 SPBREQUEST 핸들을 포함합니다. SPB 컨트롤러 드라이버는 이 핸들을 사용하여 시퀀스의 개별 전송에 대한 버퍼, 길이, 방향 및 위치 매개 변수를 가져옵니다. 이러한 매개 변수를 가져오는 방법에 대한 자세한 내용은 SpbRequestGetTransferParameters를 참조하세요.
SPB 컨트롤러 드라이버가 요청된 IOCTL_SPB_EXECUTE_SEQUENCE 작업을 수행할 수 없는 경우 실패 코드로 요청을 완료합니다. 이러한 오류가 발생하는 경우 클라이언트는 옵션으로 버스를 잠그고 일련의 간단한 I/O 요청으로 I/O 전송 시퀀스를 명시적으로 수행한 다음 버스의 잠금을 해제할 수 있습니다. 자세한 내용은 Client-Implemented 시퀀스를 참조하세요.
SpbCx는 주변 장치 드라이버에서 수신하는 IOCTL_SPB_XXX 요청에 대해 매개 변수 검사를 수행합니다. IOCTL_SPB_EXECUTE_SEQUENCE 요청의 경우 SpbCx는 빈 시퀀스와 NULL 버퍼 포인터 또는 길이가 0인 버퍼를 포함하는 시퀀스를 모두 거부합니다.
SPB 컨트롤러 드라이버는 시퀀스의 각 전송 길이가 드라이버 지정 제한을 초과하지 않는지 확인해야 합니다. 예를 들어 WDK(Windows 드라이버 키트)의 SkeletonI2C 샘플 드라이버는 4K 바이트를 초과하는 전송을 지정하는 IOCTL_SPB_EXECUTE_SEQUENCE 요청에 실패하고 이 요청의 상태 코드를 STATUS_INVALID_PARAMETER 설정합니다. IOCTL_SPB_EXECUTE_SEQUENCE 요청에 대한 시퀀스 작업을 시작하기 전에 드라이버는 시퀀스의 모든 전송에 대한 매개 변수의 유효성을 검사하여 작업이 성공적으로 완료될 수 있는지 확인해야 합니다.
SpbCx는 EvtSpbControllerLock 콜백을 EvtSpbControllerIoSequence 콜백의 앞에 두지 않으며, EvtSpbControllerIoSequence 콜백의 뒤에 EvtSpbControllerUnlock 콜백을 위치시키지 않습니다.
Client-Implemented 시퀀스
SPB 컨트롤러 드라이버의 클라이언트는 일련의 간단한 읽기 및 쓰기로 I/O 전송 시퀀스를 명시적으로 수행할 수 있습니다. 클라이언트는 커널 모드 드라이버 또는 버스에 연결된 주변 장치를 제어하는 사용자 모드 드라이버일 수 있습니다. 시퀀스의 첫 번째 전송 전에 클라이언트는 시 퀀스의 전송 간에 관련이 없는 다른 버스 액세스가 발생하지 않도록 대상 디바이스에 IOCTL_SPB_LOCK_CONTROLLER 요청을 보냅니다. 다음으로 클라이언트는 시퀀스에서 전송을 수행하기 위해 IRP_MJ_READ 및 IRP_MJ_WRITE 요청을 보냅니다. 마지막으로 클라이언트는 잠금을 해제하기 위해 IOCTL_SPB_UNLOCK_CONTROLLER 요청을 보냅니다.
시퀀스의 이후 전송에 이전 전송에 대한 종속성이 있는 경우 클라이언트는 이 유형의 I/O 전송 시퀀스를 구현해야 할 수 있습니다. 예를 들어 첫 번째 읽기는 이후에 읽거나 쓸 바이트 수를 나타낼 수 있습니다. 그러나 이러한 종속성이 없는 경우 클라이언트는 시퀀스를 보다 효율적으로 수행할 수 있는 SPB 컨트롤러 드라이버에 IOCTL_SPB_EXECUTE_SEQUENCE 요청을 보내야 합니다.
클라이언트 구현 시퀀스를 시작하는 IOCTL_SPB_LOCK_CONTROLLER 요청과 시퀀스를 종료하는 IOCTL_SPB_UNLOCK_CONTROLLER 요청 사이에 클라이언트가 대상 디바이스에 보낼 수 있는 유일한 I/O 요청은 IRP_MJ_READIRP_MJ_WRITE 요청 입니다. 이 규칙을 위반하면 오류가 발생합니다.
SPB 잠금은 읽기 및 쓰기 시퀀스가 원자 버스 작업으로 수행되도록 보장하는 데만 사용되며 해당 용도로만 사용해야 합니다.
자세한 내용은 Client-Implemented 시퀀스 처리를 참조하세요.