#include "defines.h"
#include "ascsi.h"
#include "await.h"
#include <scsi.h>

int S_Retry(unlong scsiid,int ret,int *retry)
// SCSIコマンドのエラー発生時にリトライを行うかどうかを判定する
// ret   : 直前に発行したSCSIコマンドのリターン値；!=0のこと
// retry : 現在までのリトライ回数；初期値は０のこと
// リターン値：!=0:エラーでリトライ中断 , 0=リトライする
{
unchar buff[8];	// CheckCondition発生時のデータ読み取り用
	if ( ++(*retry) < SCSIRETRYMaxCount ) {
		switch (ret &0b111110) { // リトライ出来るか？
			case 0b000010: // CheckCondition
				// CheckConditionが帰ってきた時はRequestSenseを発行しなければならない
				if (S_REQUEST( sizeof(buff) ,scsiid, buff )<0) break;
						// ReqestSenseが出来ない時はしょうがない
				switch (buff[2]&0x0f) { // センスキー
					case 2: /* Not Ready */
				//	case 3: /* Medium Error */
				//	case 4: /* Hardware Error */
					case 6: /* Unit Attention */
						break; // リトライへ
					default: // 対処出来ないので即終了
						return(ret);
				}
			case 0b011000: // Reservation Conflict
				// 他のイニシエーターが確保している
			case 0b001000: // Busy
				secwait(1); // １秒待ってからリトライ
				ret=0; // リトライするのでとりあえずエラー無し
				break;
			// 他のコードの時(-1/-2等)はリトライ不可
		}
	} // 一定回数リトライしてもだめなときはエラー(ret!=0);
	return(ret);
}
