STORAGE_REQUEST_BLOCK構造体 (minitape.h)

STORAGE_REQUEST_BLOCKは、SCSI 要求ブロック (SRB) 構造体の拡張形式です。 構造体は、SRB 関数に関連付けられた拡張データの追加を提供します。

注意

SCSI ポート ドライバーと SCSI ミニポート ドライバー モデルは、今後変更または使用できない可能性があります。 代わりに、 **Storport ドライバー モデルと **Storport ミニポート ドライバー モデルを使用することをお勧めします。

構文

typedef struct _STORAGE_REQUEST_BLOCK {
  USHORT                               Length;
  UCHAR                                Function;
  UCHAR                                SrbStatus;
  ULONG                                ReservedUlong1;
  ULONG                                Signature;
  ULONG                                Version;
  ULONG                                SrbLength;
  ULONG                                SrbFunction;
  ULONG                                SrbFlags;
  ULONG                                ReservedUlong2;
  ULONG                                RequestTag;
  USHORT                               RequestPriority;
  USHORT                               RequestAttribute;
  ULONG                                TimeOutValue;
  ULONG                                SystemStatus;
  ULONG                                ZeroGuard1;
  ULONG                                AddressOffset;
  ULONG                                NumSrbExData;
  ULONG                                DataTransferLength;
  PVOID POINTER_ALIGN                  DataBuffer;
  PVOID POINTER_ALIGN                  ZeroGuard2;
  PVOID POINTER_ALIGN                  OriginalRequest;
  PVOID POINTER_ALIGN                  ClassContext;
  PVOID POINTER_ALIGN                  PortContext;
  PVOID POINTER_ALIGN                  MiniportContext;
  _STORAGE_REQUEST_BLOCK POINTER_ALIGN *NextSrb;
  struct                               _STORAGE_REQUEST_BLOCK;
  ULONG                                SrbExDataOffset[ANYSIZE_ARRAY];
} STORAGE_REQUEST_BLOCK, *PSTORAGE_REQUEST_BLOCK;

メンバー

Length

SCSI_REQUEST_BLOCK構造体との互換性のために SRB ヘッダーのサイズを指定します。 これは、この構造体の Signature メンバーのオフセットと等しくなります。

Function

SRB_FUNCTION_STORAGE_REQUEST_BLOCKに設定して、これが拡張 SRB であることを示します。 SCSI_REQUEST_BLOCKとは異なり、SRB 関数識別子は代わりに SrbFunction メンバーにあります。

SrbStatus

完了した要求の状態を返します。 このメンバーは、要求が完了したことをオペレーティング システム固有のドライバーに通知する前に、ミニポート ドライバーによって設定する必要があります StorPortNotificationRequestComplete します。 SrbStatus には、次のいずれかの値を指定できます。

意味
SRB_STATUS_PENDING 要求が進行中であることを示します。 オペレーティング システム固有のポート ドライバーは 、この値に SrbStatus を初期化します。
SRB_STATUS_SUCCESS 要求が正常に完了したことを示します。
SRB_STATUS_ABORTED ポート ドライバーの指示に応じて要求が中止されたことを示します。 ミニポート ドライバーは、成功したSRB_FUNCTION_ABORT_COMMAND要求の NextSrb メンバーにこの状態を設定します。
SRB_STATUS_ABORT_FAILED 要求の中止が失敗したことを示します。 指定した要求が見つからない場合は、SRB_FUNCTION_ABORT_COMMAND要求のこの状態を返します。
SRB_STATUS_ERROR SCSI バスの状態でエラーが発生して要求が完了したことを示します。
SRB_STATUS_BUSY 現在、ミニポート ドライバーまたはターゲット デバイスが要求を受け入れられなかったことを示します。 オペレーティング システム固有のポート ドライバーは、後で要求を再送信します。
SRB_STATUS_INTERNAL_ERROR Storport ドライバーがミニポート ドライバーまたはターゲット デバイスに要求を配信できなかったことを示します。 このような場合、状態は InternalStatus に記録されます。
SRB_STATUS_INVALID_REQUEST ミニポート ドライバーが指定された要求をサポートしていないことを示します。
SRB_STATUS_NO_DEVICE デバイスが応答しなかったことを示します。
SRB_STATUS_TIMEOUT 要求がタイムアウトしたことを示します。
SRB_STATUS_SELECTION_TIMEOUT SCSI デバイスの選択がタイムアウトしたことを示します。
SRB_STATUS_COMMAND_TIMEOUT ターゲットが制限時間内にコマンドを完了しなかったことを示します。
SRB_STATUS_MESSAGE_REJECTED ターゲットがメッセージを拒否したことを示します。 これは通常、SRB_FUNCTION_TERMINATE_IOのようなメッセージ型の要求に対してのみ返されます。
SRB_STATUS_BUS_RESET この要求の実行中にバスのリセットが発生したことを示します。
SRB_STATUS_PARITY_ERROR SCSI バスでパリティ エラーが発生し、再試行に失敗したことを示します。
SRB_STATUS_REQUEST_SENSE_FAILED request-sense コマンドが失敗したことを示します。 これは、ホスト バス アダプター (HBA) が自動要求検出を実行し、ミニポート ドライバーがこの HBA のPORT_CONFIGURATION_INFORMATIONAutoRequestSenseTRUE に設定した場合にのみ返されます。
SRB_STATUS_NO_HBA HBA が応答しないことを示します。
SRB_STATUS_DATA_OVERRUN データ オーバーランまたはアンダーラン エラーが発生したことを示します。 ミニポート ドライバーは、SRB の DataTransferLength メンバーを更新して、アンダーランが発生した場合に実際に転送されたデータの量を示す必要もあります。
SRB_STATUS_UNEXPECTED_BUS_FREE ターゲットが予期せず切断されたことを示します。
SRB_STATUS_PHASE_SEQUENCE_FAILURE HBA が無効なフェーズ シーケンスエラーを検出したことを示します。
SRB_STATUS_REQUEST_FLUSHED 状態の要求が停止されたことを示します。
SRB_STATUS_BAD_FUNCTION SRB 関数 コードがサポートされていないことを示します。
SRB_STATUS_INVALID_PATH_ID SRB で指定された PathId が存在しないことを示します。
SRB_STATUS_INVALID_TARGET_ID SRB の TargetID 値が無効であることを示します。
SRB_STATUS_INVALID_LUN SRB の Lun 値が無効であることを示します。
SRB_STATUS_ERROR_RECOVERY SCSI バスの状態でエラーが発生して要求が完了し、SCSI INITIATE RECOVERY メッセージが受信されたことを示します。
SRB_STATUS_AUTOSENSE_VALID SenseInfoBuffer で返される情報が有効であることを示します。
SRB_STATUS_QUEUE_FROZEN ミニポート ドライバーは、 SrbStatus メンバーをこの値に設定しないでください。 Windows ポート ドライバーは、この値を設定して、特定の周辺機器に対する要求のキューが凍結されたことをストレージ クラス ドライバーに通知できます。
SRB_STATUS_NOT_POWERED は、ターゲットの電源が入っていないために要求が失敗したことを示します。 SrbFlags でSRB_FLAGS_NO_KEEP_AWAKEが設定された要求の場合、電源が切れている LUN に送信された要求は、この状態で失敗します。
SRB_STATUS_LINK_DOWN リンクがダウンしているために要求が失敗したことを示します。
SRB_STATUS_BAD_SRB_BLOCK_LENGTH SRB の長さが無効であったため、要求が失敗したことを示します。

ReservedUlong1

予約済み。 0 に設定されます。

Signature

拡張 SRB 形式の署名。 これは SRB_SIGNATURE に設定されます。

Version

使用される構造体のバージョン。 現在のバージョンは STORAGE_REQUEST_BLOCK_VERSION_1

SrbLength

この拡張 SRB の長さ (この構造体、アドレス、および SRB 拡張データを含むバイト単位)。

SrbFunction

実行する操作を指定します。次のいずれかの値を指定できます。

意味
SRB_FUNCTION_EXECUTE_SCSI (0x00) SCSI デバイス I/O 要求は、ターゲット論理ユニットで実行する必要があります。 NumSrbExData> 0 の場合、SrbExDataOffset で指定されたオフセット (SRBEX_DATA_SCSI_CDB16、SRBEX_DATA_SCSI_CDB32、SRBEX_DATA_SCSI_CDB_VARSRBEX_DATA_BIDIRECTIONALSRBEX_DATA_IO_INFO) に 1 つ以上の拡張要求ブロック構造が配置されます。
SRB_FUNCTION_ABORT_COMMAND (0x10) NextSrb メンバーが指す要求を取り消すには、SCSIMESS_ABORT メッセージを送信する必要があります。 これがタグ付きキュー要求の場合は、代わりにSCSIMESS_ABORT_WITH_TAGメッセージを使用する必要があります。 指定された要求が完了した場合、この要求は正常に完了する必要があります。 この関数には拡張 SRB データは必要ありません。 : この関数は、Storport によってミニポートに送信されません。
SRB_FUNCTION_RESET_DEVICE (0x16) SCSI ターゲット コントローラーは、SCSIMESS_BUS_DEVICE_RESET メッセージを使用してリセットする必要があります。 ミニポート ドライバーは、ターゲット コントローラーのアクティブな要求を完了する必要があります。 この関数には拡張 SRB データは必要ありません。
SRB_FUNCTION_RESET_LOGICAL_UNIT (0x20) 可能であれば、論理ユニットをリセットする必要があります。 HBA ミニポート ドライバーは、論理ユニットのアクティブな要求を完了する必要があります。 この関数には拡張 SRB データは必要ありません。 Storport ではこの種類のリセットがサポートされていますが、SCSI ポートではサポートされていません。
SRB_FUNCTION_RESET_BUS (0x12) SCSI バスは、SCSIMESS_BUS_DEVICE_RESET メッセージを使用してリセットする必要があります。 ミニポート ドライバーは、特定の要求がタイムアウトし、タイムアウト要求を中止する後続の要求もタイムアウトした場合にのみ、この要求を受信します。この関数には拡張 SRB データは必要ありません。
SRB_FUNCTION_TERMINATE_IO (0x14) NextSrb メンバーが指す要求を取り消すには、SCSIMESS_TERMINATE_IO_PROCESS メッセージを送信する必要があります。 指定された要求が既に完了している場合、この要求は正常に完了する必要があります。 この関数には拡張 SRB データは必要ありません。 : この関数は、Storport によってミニポートに送信されません。
SRB_FUNCTION_RELEASE_RECOVERY (0x11) SCSIMESS_RELEASE_RECOVERY メッセージをターゲット コントローラーに送信する必要があります。 この関数には拡張 SRB データは必要ありません。 : この関数は、Storport によってミニポートに送信されません。
SRB_FUNCTION_RECEIVE_EVENT (0x03) HBA は、アドレス指定されたターゲットから非同期イベント通知を受信するように準備する必要があります。 SRB DataBuffer メンバーは、データを配置する場所を示します。 : この関数は、Storport によってミニポートに送信されません。
SRB_FUNCTION_SHUTDOWN (0x07) システムがシャットダウン中です。 ミニポート ドライバーは、すべてのシステム アクティビティが実際に停止する前に、これらの通知のいくつかを受け取ることができます。 ただし、最後のシャットダウン通知は、最後の開始 I/O の後に行われます。 この関数には拡張 SRB データは必要ありません。
SRB_FUNCTION_FLUSH (0x08) ミニポート ドライバーは、ターゲット デバイスのキャッシュされたデータをフラッシュする必要があります。 この要求は、HBA のPORT_CONFIGURATION_INFORMATIONCachesDataTRUE に設定した場合にのみ、ミニポート ドライバーに送信されます。 この関数には拡張 SRB データは必要ありません。
SRB_FUNCTION_IO_CONTROL (0x02) 要求は I/O 制御要求であり、専用 HBA を持つユーザー モード アプリケーションで送信されます。 SRB DataBuffer、SRB_IO_CONTROL ヘッダーとそれに続くデータ領域を指します。 DataBuffer の値は、MapBuffers の値に関係なく、ドライバーで使用できます。 SRB 関数SrbFlagsTimeOutValueDataBuffer、および DataTransferLength メンバーのみが有効であり、ミニポート ドライバーが初期化時に SRB 拡張機能を要求した場合は 、SrbExtension メンバーと共に有効です。 ミニポート ドライバーがこの要求をサポートするようにアプリケーション専用 HBA を制御する場合、ミニポート ドライバーは要求を実行し、要求使用して StorPortNotificationNextRequest の呼び出しの通常のメカニズムを使用して、SRB が完了したときにオペレーティング システム固有のポート ドライバーに通知する必要があります。
SRB_FUNCTION_LOCK_QUEUE (0x18) 通常、電源要求の処理中に、特定の論理ユニットのポート ドライバーによってキューに入れられている要求を保持します。 SRB LengthFunctionSrbFlagsOriginalRequest の各メンバーのみが有効です。 キューがロックされている場合、SRB_FLAGS_BYPASS_LOCKED_QUEUEを含む SrbFlags ORed を持つ要求のみが処理されます。 SCSI ミニポート ドライバーは、 SRB_FUNCTION_LOCK_QUEUE 要求を処理しません。
SRB_FUNCTION_UNLOCK_QUEUE (0x19) 以前に SRB_FUNCTION_LOCK_QUEUEでロックされていた論理ユニットのポート ドライバーのキューを解放します。 ロック解除要求の SrbFlags、SRB_FLAGS_BYPASS_LOCKED_QUEUEを使用した ORed である必要があります。 SRB LengthFunctionSrbFlagsOriginalRequest の各メンバーのみが有効です。 SCSI ミニポート ドライバーは、 SRB_FUNCTION_UNLOCK_QUEUE 要求を処理しません。
SRB_FUNCTION_DUMP_POINTERS (0x26) この関数を使用した要求は、クラッシュ ダンプ データを保持するディスクを制御するために使用される Storport ミニポート ドライバーに送信されます。 要求は、クラッシュ ダンプと休止状態をサポートするためにミニポート ドライバーから必要な情報を収集します。 MINIPORT_DUMP_POINTERS構造を参照してください。 物理ミニポート ドライバーは、この関数を使用して要求を受信するには、そのHW_INITIALIZATION_DATAFeatureSupport メンバーでSTOR_FEATURE_DUMP_POINTERS フラグを設定する必要があります。
SRB_FUNCTION_FREE_DUMP_POINTERS (0x27) この関数を使用した要求は、Storport ミニポート ドライバーに送信され、SRB_FUNCTION_DUMP_POINTERSの以前の要求中に割り当てられたリソースを解放します。
SRB_FUNCTION_QUIESCE_DEVICE (0x1A) 要求は、記憶域クラスと記憶域ポート ドライバーの間でのみであり、ミニポートに送信されません。 この関数は、ポート ドライバーが未処理のすべての I/O を完了するためのクラス ドライバーによる待機として機能します。
SRB_FUNCTION_PNP (0x25) 要求は、 SRBEX_DATA_PNP 構造体として書式設定された PnP 拡張要求です。 拡張要求データへのオフセットは 、SrbExDataOffset[0] にあります。
SRB_FUNCTION_POWER (0x24) 要求は、 SRBEX_DATA_POWER 構造として書式設定された電源拡張要求です。 拡張要求データへのオフセットは 、SrbExDataOffset[0] にあります。
SRB_FUNCTION_WMI (0x17) 要求は、 SRBEX_DATA_WMI 構造体として書式設定された電源拡張要求です。 拡張要求データへのオフセットは 、SrbExDataOffset[0] にあります。

SrbFlags

要求のさまざまなパラメーターとオプションを示します。 SrbFlags は読み取り専用です。 ただし、SRB_FLAGS_UNSPECIFIED_DIRECTION が設定されていて、下位 DMA アダプターのミニポート ドライバーが SRB_FLAGS_DATA_IN または SRB_FLAGS_DATA_OUTを更新する必要がある場合を除きます。 このメンバーには、これらのフラグを 1 つ以上設定できます。

フラグ 説明
SRB_FLAGS_QUEUE_ACTION_ENABLE タグ付きキュー アクションを有効にすることを示します。
SRB_FLAGS_DISABLE_AUTOSENSE 要求センス情報を返すべきではないを示します。
SRB_FLAGS_DATA_IN デバイスからシステムにデータが転送されることを示します。
SRB_FLAGS_DATA_OUT システムからデバイスにデータが転送されることを示します。
SRB_FLAGS_UNSPECIFIED_DIRECTION ASPI/CAM SCSI インターフェイスとの下位互換性のために定義されているこのフラグは、上記の両方のフラグが設定されているため、転送方向が上記のいずれかである可能性があることを示します。 このフラグが設定されている場合、ミニポート ドライバーは、SCSI バス上のターゲットのデータ フェーズを調べることによって転送方向を決定する必要があります。
SRB_FLAGS_NO_DATA_TRANSFER この要求でデータ転送がないことを示します。 これが設定されている場合、フラグ SRB_FLAGS_DATA_OUTSRB_FLAGS_DATA_INおよびSRB_FLAGS_UNSPECIFIED_DIRECTION が明確になります。
SRB_FLAGS_DISABLE_SYNCH_TRANSFER 可能であれば、この転送要求に対して非同期 I/O を実行する HBA を示します。 同期 I/O が以前にネゴシエートされた場合、転送を実行する前に、HBA は非同期 I/O に対して再ネゴシエーションする必要があります。
SRB_FLAGS_DISABLE_DISCONNECT HBA は、この要求の処理中にターゲットが SCSI バスから切断できないようにする必要があることを示します。
SRB_FLAGS_BYPASS_FROZEN_QUEUE このフラグは、ミニポート ドライバーには関係ありません。
SRB_FLAGS_NO_QUEUE_FREEZE このフラグは、ミニポート ドライバーには関係ありません。
SRB_FLAGS_IS_ACTIVE このフラグは、ミニポート ドライバーには関係ありません。
SRB_FLAGS_ALLOCATED_FROM_ZONE このフラグはミニポート ドライバーとは無関係であり、新しい Windows クラス ドライバーでは廃止されています。 Windows レガシ クラス ドライバーでは、SRB がゾーン バッファーから割り当てられたかどうかを示します。 このフラグが設定されている場合、クラス ドライバーは ExInterlockedFreeToZone を呼び出して SRB を解放する必要があります。それ以外の場合は、 ExFreePool を呼び出す必要があります。 新しいクラス ドライバーでは、ゾーン バッファーではなくルックアサイド リストを使用する必要があります。
SRB_FLAGS_SGLIST_FROM_POOL このフラグは、ミニポート ドライバーには関係ありません。 クラス ドライバーでは、これは、分散/収集リストのメモリが非ページ プールから割り当てられたことを示します。 このフラグが設定されている場合、クラス ドライバーは ExFreePool を呼び出して、SRB の完了後にメモリを解放する必要があります。
SRB_FLAGS_BYPASS_LOCKED_QUEUE このフラグは、ミニポート ドライバーには関係ありません。 ポート ドライバーでは、このフラグは、論理ユニット キューがロックされているかどうかに関係なく、要求を処理する必要があることを示します。 上位レベルのドライバーは、 SRB_FUNCTION_UNLOCK_QUEUE 要求を送信するには、このフラグを設定する必要があります。
SRB_FLAGS_NO_KEEP_AWAKE このフラグは、ミニポート ドライバーには関係ありません。 Windows クラス ドライバーは、このフラグを使用して、この要求を処理するためにデバイスの電源をオンにするのではなく、要求を失敗するようにポート ドライバーに示します。
SRB_FLAGS_FREE_SENSE_BUFFER ポートまたはミニポート ドライバーがセンス データのバッファーを割り当てたことを示します。 これにより、データを抽出した後にセンス データ バッファーを解放する必要があることをクラス ドライバーに通知します。
SRB_FLAGS_D3_PROCESSING 要求が D3 処理の一部であることを示します。 ランタイム電源制御をサポートするミニポートは、これらの要求 で StorPortPoFxActivateComponent または StorPortPoFxIdleComponent を呼び出さないでください
SRB_FLAGS_ADAPTER_CACHE_ENABLE アダプターがデータをキャッシュできることを示します。

ReservedUlong2

予約済み。 0 に設定されます。

RequestTag

オペレーティング システム固有のポート ドライバーによって割り当てられたキュー タグ値を格納します。 このメンバーがタグ付きキューに使用されている場合、HBA は論理ユニット (LU) への要求の内部キューをサポートし、ミニポート ドライバーは、この HBA のPORT_CONFIGURATION_INFORMATIONで TaggedQueueingTRUE に設定します。

RequestPriority

SRB の優先度の割り当て。

RequestAttribute

SRB_FLAGS_QUEUE_ACTION_ENABLE フラグが設定されたときに使用されるタグ付きキュー メッセージを示します。 値には、SRB_SIMPLE_TAG_REQUEST、SRB_HEAD_OF_QUEUE_TAG_REQUEST、またはSRB_ORDERED_QUEUE_TAG_REQUESTのいずれかを指定できます。

TimeOutValue

オペレーティング システム固有のポート ドライバーがタイムアウトと見なす前に要求を実行できる間隔を秒単位で示します。ミニポート ドライバーは、ポート ドライバーが既に行うため、要求を時刻に必要ありません。

SystemStatus

要求をミニポート ドライバーに配信できない場合に、完了した要求の状態を報告するために、 SrbStatus ではなく Storport ドライバーによって使用されます。 このような場合、 SrbStatusSRB_STATUS_INTERNAL_ERROR に設定されます。 このメンバーは、Storport とクラス ドライバー間の通信にのみ使用され、ミニポート ドライバーでは使用しないでください。

ZeroGuard1

この構造を SCSI_REQUEST_BLOCKと解釈するドライバーから保護する保護領域。 0 に設定されます。

AddressOffset

この構造体の先頭からのストレージ要求アドレスのオフセット。 このオフセットは、要求のアドレスを含む STOR_ADDRESS 構造体を検索します。

NumSrbExData

この要求の拡張 SRB データ ブロックの数。

DataTransferLength

データ バッファーのサイズをバイト単位で示します。 アンダーランが発生した場合、ミニポート ドライバーは、実際に転送されたバイト数にこのメンバーを更新する必要があります。

DataBuffer

データ バッファーをポイントします。 ミニポート ドライバーは、ミニポート ドライバーが HBA のPORT_CONFIGURATION_INFORMATIONMapBuffersTRUE に設定しない限り、データ ポインターとしてこの値を使用しないでください。 ただし、SRB_FUNCTION_IO_CONTROL要求の場合、ミニポート ドライバーは MapBuffers の値に関係なく、この値をデータ ポインターとして使用できます。

ZeroGuard2

この構造を SCSI_REQUEST_BLOCKと解釈するドライバーから保護する保護領域。 0 に設定されます。

OriginalRequest

この要求の IRP を指します。 このメンバーは、ミニポート ドライバーには関係ありません。

ClassContext

この要求のクラス ドライバー コンテキスト データを指します。 このメンバーは、ミニポート ドライバーには関係ありません。

PortContext

この要求のポート ドライバー コンテキスト データを指します。 このメンバーは、ミニポート ドライバーには関係ありません。

MiniportContext

Srb 拡張機能をポイントします。 HW_INITIALIZATION_DATASrbExtensionSize を 0 に設定した場合、ミニポート ドライバーはこのメンバーを使用しないでください。 MiniportContext のメモリはオペレーティング システム固有のポート ドライバーによって初期化されず、ミニポート ドライバーによって決定されたデータに HBA から直接アクセスできます。 対応する物理アドレスは、MiniportContext ポインターを使用して StorportGetPhysicalAddress を呼び出すことによって取得できます。

NextSrb

この要求が適用される STORAGE_REQUEST_BLOCK を示します。 SRB_FUNCTION_ABORT_COMMANDなど、2 つ目の SRB を使用するのは、要求のごく一部のみです。

_STORAGE_REQUEST_BLOCK

SrbExDataOffset[ANYSIZE_ARRAY]

SRB の拡張データ ブロックの位置を指定するオフセットの配列。 NumSrbExData = 0 の場合、この配列は空です。

注釈

Windows 8以降、拡張 SRB 型は、STORAGE_REQUEST_BLOCK構造体を使用してサポートされます。 STORAGE_REQUEST_BLOCK は SRB 関数を拡張し、SRB 関数の拡張データ ブロックを要求に追加できるようにします。 SCSI_REQUEST_BLOCK構造体を使用した SRB 要求のサポートは引き続き行われます。

NumSrbExData> 0 の場合、SRB 拡張データ ブロックのオフセットは SrbExDataOffset 配列にあります。 各オフセットは、この構造体の先頭を基準とし、拡張データ ブロックを含む SRBEX_DATA 構造体を指します。

SRB のターゲット デバイス アドレスは、AddressOffset によって示されるSTOR_ADDRESS構造にあります。

要件

要件
サポートされている最小のクライアント Windows 8
Header minitape.h (Storport.h、Srb.h、Minitape.h を含む)

こちらもご覧ください

SCSI_REQUEST_BLOCK