Example #1
0
static int
dirdevopen(ScsiReq *rp)
{
	uint64_t blocks;
	uint8_t data[8+4+20];	/* 16-byte result: lba, blksize, reserved */

	memset(data, 0, sizeof data);
	if(SRstart(rp, 1) == -1 || SRrcapacity(rp, data) == -1)
		return -1;
	rp->lbsize = GETBELONG(data+4);
	blocks =     GETBELONG(data);
	if(debug)
		fprint(2, "disk: dirdevopen: 10-byte logical block size %lud, "
			"# blocks %llud\n", rp->lbsize, blocks);
	if(blocks == 0xffffffff){
		if(SRrcapacity16(rp, data) == -1)
			return -1;
		rp->lbsize = GETBELONG(data + 8);
		blocks = (int64_t)GETBELONG(data)<<32 | GETBELONG(data + 4);
		if(debug)
			fprint(2, "disk: dirdevopen: 16-byte logical block size"
				" %lud, # blocks %llud\n", rp->lbsize, blocks);
	}
	/* some newer dev's don't support 6-byte commands */
	if(blocks > Max24off && !force6bytecmds)
		rp->flags |= Frw10;
	return 0;
}
Example #2
0
int32_t
SRwrite(ScsiReq *rp, void *buf, int32_t nbytes)
{
	uint8_t cmd[10];
	int32_t n;

	if(rp->lbsize == 0 || (nbytes % rp->lbsize) || nbytes > Maxiosize){
		if(diskdebug)
			if (nbytes % rp->lbsize)
				fprint(2, "disk: i/o size %ld %% %ld != 0\n",
					nbytes, rp->lbsize);
			else
				fprint(2, "disk: i/o size %ld > %d\n",
					nbytes, Maxiosize);
		rp->status = Status_BADARG;
		return -1;
	}

	/* set up scsi write cmd */
	cmd[0] = ScmdWrite;
	if(rp->flags & Fseqdev)
		rp->cmd.count = seqdevrw(rp, cmd, nbytes);
	else
		rp->cmd.count = dirdevrw(rp, cmd, nbytes);
	rp->cmd.p = cmd;
	rp->data.p = buf;
	rp->data.count = nbytes;
	rp->data.write = 1;

	/* issue it */
	if((n = SRrequest(rp)) == -1){
		if (exabyte) {
			fprint(2, "write error\n");
			rp->status = STcheck;
			return n;
		}
		if(rp->status != Status_SD || rp->sense[2] != Sd2eom)
			return -1;
		if(rp->sense[0] & Sd0valid){
			n -= GETBELONG(rp->sense+3) * rp->lbsize;
			rp->data.count = nbytes - n;
		}
		else
			rp->data.count = nbytes;
		n = rp->data.count;
	}
	rp->offset += n / rp->lbsize;
	return n;
}
Example #3
0
File: mmc.c Project: Requaos/harvey
static int
getconfcmd(Drive *drive, uint8_t *resp, int respsz)
{
	int n;
	uint32_t datalen;
	uint8_t cmd[10];

	initcdb(cmd, sizeof cmd, Scmdgetconf);
	cmd[3] = 0;			/* start with profile list feature */
	cmd[7] = respsz >> 8;
	cmd[8] = respsz;
	n = scsi(&drive->scsi, cmd, sizeof cmd, resp, respsz, Sread);
	if (n < 0) {
		if(vflag)
			fprint(2, "get config cmd failed\n");
		return -1;
	}
	if (n < 4)
		return -1;
	datalen = GETBELONG(resp+0);
	if (datalen < 8)
		return -1;
	return datalen;
}
Example #4
0
int32_t
SRread(ScsiReq *rp, void *buf, int32_t nbytes)
{
	uint8_t cmd[10];
	int32_t n;

	if(rp->lbsize == 0 || (nbytes % rp->lbsize) || nbytes > Maxiosize){
		if(diskdebug)
			if (nbytes % rp->lbsize)
				fprint(2, "disk: i/o size %ld %% %ld != 0\n",
					nbytes, rp->lbsize);
			else
				fprint(2, "disk: i/o size %ld > %d\n",
					nbytes, Maxiosize);
		rp->status = Status_BADARG;
		return -1;
	}

	/* set up scsi read cmd */
	cmd[0] = ScmdRead;
	if(rp->flags & Fseqdev)
		rp->cmd.count = seqdevrw(rp, cmd, nbytes);
	else
		rp->cmd.count = dirdevrw(rp, cmd, nbytes);
	rp->cmd.p = cmd;
	rp->data.p = buf;
	rp->data.count = nbytes;
	rp->data.write = 0;

	/* issue it */
	n = SRrequest(rp);
	if(n != -1){			/* it worked? */
		rp->offset += n / rp->lbsize;
		return n;
	}

	/* request failed; maybe we just read a short record? */
	if (exabyte) {
		fprint(2, "read error\n");
		rp->status = STcheck;
		return n;
	}
	if(rp->status != Status_SD || !(rp->sense[0] & Sd0valid))
		return -1;
	/* compute # of bytes not read */
	n = GETBELONG(rp->sense+3) * rp->lbsize;
	if(!(rp->flags & Fseqdev))
		return -1;

	/* device is a tape or something similar */
	if (rp->sense[2] == Sd2filemark || rp->sense[2] == 0x08 ||
	    rp->sense[2] & Sd2ili && n > 0)
		rp->data.count = nbytes - n;
	else
		return -1;
	n = rp->data.count;
	if (!rp->readblock++ || debug)
		fprint(2, "SRread: tape data count %ld%s\n", n,
			(rp->sense[2] & Sd2ili? " with ILI": ""));
	rp->status = STok;
	rp->offset += n / rp->lbsize;
	return n;
}