SCSI ターゲットデバイスは自己識別しないため、ターゲットドライバが probe (9E) ルーチンを備えている必要があります。このルーチンは、予期される種類のデバイスが存在していて、応答しているかどうかを判定する必要があります。
probe (9E) ルーチンの一般的な構造とリターンコードは、ほかのデバイスドライバの構造およびリターンコードと同じです。SCSI ターゲットドライバは、probe(9E) エントリポイントでscsi_probe(9F) ルーチンを使用する必要があります。scsi_probe(9F) はデバイスに SCSI 照会コマンドを送信し、結果を示すコードを返します。SCSI 照会コマンドが成功すると、scsi_probe (9F) はscsi_inquiry(9S) 構造体を割り当てて、構造体にデバイスの照会データを格納します。scsi_probe(9F) から復帰すると、scsi_device(9S) 構造体の sd_inq フィールドが、このscsi_inquiry(9S) 構造体を指します。
probe(9E) はステートレスである必要があるため、ターゲットドライバは、scsi_probe(9F) が失敗した場合でも、probe(9E) が復帰する前にscsi_unprobe(9F) を呼び出す必要があります。
Example 17–1 に、一般的な probe(9E) ルーチンを示します。この例のルーチンは、dev_info 構造体の非公開フィールドからscsi_device(9S) 構造体を取得しています。また、メッセージ内に出力するためのデバイスの SCSI ターゲットと論理ユニット番号を取得しています。 probe(9E) ルーチンは次に scsi_probe(9F) を呼び出して、予期されるデバイス (この場合はプリンタ) が存在することを検証しています。
成功すると、 scsi_probe(9F) はscsi_inquiry(9S) 構造体内にあるデバイスの SCSI 照会データを、scsi_device(9S) 構造体の sd_inq フィールドに追加します。ドライバはその後、デバイスの種類がプリンタであるかどうかを判定できます。この情報は inq_dtype フィールドで報告されます。デバイスがプリンタである場合、scsi_log(9F) がscsi_dname(9F) を使用してデバイスの種類を文字列に変換し、その種類を報告します。
使用例 17-1 SCSI ターゲットドライバの probe (9E) ルーチンstatic int
xxprobe(dev_info_t *dip)
{
struct scsi_device *sdp;
int rval, target, lun;
/*
* Get a pointer to the scsi_device(9S) structure
*/
sdp = (struct scsi_device *)ddi_get_driver_private(dip);
target = sdp->sd_address.a_target;
lun = sdp->sd_address.a_lun;
/*
* Call scsi_probe(9F) to send the Inquiry command. It will
* fill in the sd_inq field of the scsi_device structure.
*/
switch (scsi_probe(sdp, NULL_FUNC)) {
case SCSIPROBE_FAILURE:
case SCSIPROBE_NORESP:
case SCSIPROBE_NOMEM:
/*
* In these cases, device might be powered off,
* in which case we might be able to successfully
* probe it at some future time - referred to
* as `deferred attach'.
*/
rval = DDI_PROBE_PARTIAL;
break;
case SCSIPROBE_NONCCS:
default:
/*
* Device isn't of the type we can deal with,
* and/or it will never be usable.
*/
rval = DDI_PROBE_FAILURE;
break;
case SCSIPROBE_EXISTS:
/*
* There is a device at the target/lun address. Check
* inq_dtype to make sure that it is the right device
* type. See scsi_inquiry(9S)for possible device types.
*/
switch (sdp->sd_inq->inq_dtype) {
case DTYPE_PRINTER:
scsi_log(sdp, "xx", SCSI_DEBUG,
"found %s device at target%d, lun%d\n",
scsi_dname((int)sdp->sd_inq->inq_dtype),
target, lun);
rval = DDI_PROBE_SUCCESS;
break;
case DTYPE_NOTPRESENT:
default:
rval = DDI_PROBE_FAILURE;
break;
}
}
scsi_unprobe(sdp);
return (rval);
}
probe(9E) ルーチンをより詳細に記述すると、 scsi_inquiry(9S) をチェックして、そのデバイスが特定のドライバで予期されている種類であることを確認できます。