Beispiel #1
0
int
scsicmd(Scsi *s, uchar *cmd, int ccount, void *data, int dcount, int io)
{
	return _scsicmd(s, cmd, ccount, data, dcount, io, 1);
}
Beispiel #2
0
int
scsi(Scsi *s, uchar *cmd, int ccount, void *v, int dcount, int io)
{
	uchar req[6], sense[255], *data;
	int tries, code, key, n;
	char *p;

	data = v;
	SET(key); SET(code);
	qlock(&s->lk);
	for(tries=0; tries<2; tries++) {
		n = _scsicmd(s, cmd, ccount, data, dcount, io, 0);
		if(n >= 0) {
			qunlock(&s->lk);
			return n;
		}

		/*
		 * request sense
		 */
		memset(req, 0, sizeof(req));
		req[0] = 0x03;
		req[4] = sizeof(sense);
		memset(sense, 0xFF, sizeof(sense));
		if((n=_scsicmd(s, req, sizeof(req), sense, sizeof(sense), Sread, 0)) < 14)
			if(scsiverbose)
				fprint(2, "reqsense scsicmd %d: %r\n", n);
	
		if(_scsiready(s, 0) < 0)
			if(scsiverbose)
				fprint(2, "unit not ready\n");
	
		key = sense[2];
		code = sense[12];
		if(code == 0x17 || code == 0x18) {	/* recovered errors */
			qunlock(&s->lk);
			return dcount;
		}
		if(code == 0x28 && cmd[0] == 0x43) {	/* get info and media changed */
			s->nchange++;
			s->changetime = time(0);
			continue;
		}
	}

	/* drive not ready, or medium not present */
	if(cmd[0] == 0x43 && key == 2 && (code == 0x3a || code == 0x04)) {
		s->changetime = 0;
		qunlock(&s->lk);
		return -1;
	}
	qunlock(&s->lk);

	if(cmd[0] == 0x43 && key == 5 && code == 0x24)	/* blank media */
		return -1;

	p = scsierror(code, sense[13]);

	werrstr("cmd #%.2ux: %s", cmd[0], p);

	if(scsiverbose)
		fprint(2, "scsi cmd #%.2ux: %.2ux %.2ux %.2ux: %s\n", cmd[0], key, code, sense[13], p);

/*	if(key == 0) */
/*		return dcount; */
	return -1;
}
Beispiel #3
0
int
scsi(Scsi *s, uchar *cmd, int ccount, void *v, int dcount, int io)
{
	uchar req[6], sense[255], *data;
	int tries, code, key, n;
	char *p;

	data = v;
	SET(key, code);
	qlock(s);
	for(tries=0; tries<2; tries++) {
		n = _scsicmd(s, cmd, ccount, data, dcount, io, 0);
		if(n >= 0) {
			qunlock(s);
			return n;
		}

		/*
		 * request sense
		 */
		memset(req, 0, sizeof(req));
		req[0] = Reqsense;
		req[4] = sizeof(sense);
		memset(sense, 0xFF, sizeof(sense));
		if((n=_scsicmd(s, req, sizeof(req), sense, sizeof(sense), Sread, 0)) < 14)
			if(scsiverbose)
				fprint(2, "reqsense scsicmd %d: %r\n", n);
	
		if(_scsiready(s, 0) < 0)
			if(scsiverbose)
				fprint(2, "unit not ready\n");
	
		key = sense[2] & 0xf;
		code = sense[12];			/* asc */
		if(code == Recovnoecc || code == Recovecc) { /* recovered errors */
			qunlock(s);
			return dcount;
		}

		/* retry various odd cases */
		if(code == Newmedium && cmd[0] == Readtoc) {
			/* read toc and media changed */
			s->nchange++;
			s->changetime = time(0);
		} else if((cmd[0] == Write10 || cmd[0] == Writever10) &&
		    key == Sensenotrdy &&
		    code == Lunnotrdy && sense[13] == 0x08) {
			/* long write in progress, per mmc-6 */
			tries = 0;
			sleep(1);
		}
	}

	/* drive not ready, or medium not present */
	if(cmd[0] == Readtoc && key == Sensenotrdy &&
	    (code == Nomedium || code == Lunnotrdy)) {
		s->changetime = 0;
		qunlock(s);
		return -1;
	}
	qunlock(s);

	if(cmd[0] == Readtoc && key == Sensebadreq && code == Badcdb)
		return -1;			/* blank media */

	p = scsierror(code, sense[13]);

	werrstr("cmd #%.2ux: %s", cmd[0], p);

	if(scsiverbose)
		fprint(2, "scsi cmd #%.2ux: %.2ux %.2ux %.2ux: %s\n",
			cmd[0], key, code, sense[13], p);

//	if(key == Sensenone)
//		return dcount;
	return -1;
}