Beispiel #1
0
/*
 * issue the SCSI command via scsi(2).  lun must already be in cmd[1].
 */
static int
doscsi(Target* tp, int rw, uchar* cmd, int cbytes, void* data, int* dbytes)
{
	int lun, db = 0;
	uchar reqcmd[6], reqdata[Nsense], dummy[1];
	Scsi *sc;

	sc = tp->sc;
	if (sc == nil)
		panic("doscsi: nil tp->sc");
	lun = cmd[1] >> 5;	/* save lun in case we need it for reqsense */

	/* cope with zero arguments */
	if (dbytes != nil)
		db = *dbytes;
	if (data == nil)
		data = dummy;

	if (scsi(sc, cmd, cbytes, data, db, rw) >= 0)
		return STok;

	/* cmd failed, get whatever sense data we can */
	memset(reqcmd, 0, sizeof reqcmd);
	reqcmd[0] = CMDreqsense;
	reqcmd[1] = lun<<5;
	reqcmd[4] = Nsense;
	memset(reqdata, 0, sizeof reqdata);
	if (scsicmd(sc, reqcmd, sizeof reqcmd, reqdata, sizeof reqdata,
	    Sread) < 0)
		return STharderr;

	/* translate sense data to ST* codes */
	return sense2stcode(reqdata);
}
Beispiel #2
0
static int
GetHandyStoreSize(scsi_device *device, struct sHandyStoreDescr *h)
{
	char		cdb       [] = {0xD5, 0x00,
		0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00};

	int		cc;
	static unsigned char sector[512];
	ssize_t		ssector = sizeof(sector);


	h->isValid = 0;
	cc = scsicmd(device, cdb, sizeof(cdb), SCSI_DIR_IN, sector, &ssector);
	if (h != NULL) {
		h->LastHandyBlockAddress = ntohl(*(uint32_t *) (sector + 0));
		h->BlockLength = ntohl(*(uint32_t *) (sector + 4));
		h->reserved1 = ntohs(*(uint16_t *) (sector + 8));
		h->MaximumTransferLength = ntohs(*(uint16_t *) (sector + 10));
		h->isValid = 1;
	}
	//hexdump(sector, ssector, NULL);

	return cc;
}
Beispiel #3
0
static int
ReadHandyStore(scsi_device *device, int page, unsigned char *sector, ssize_t * ssector)
{
	char		cdb       [] = {0xD8, 0x00,
		0x00, 0x00, 0x00, 0x0F,
	0x00, 0x00, 0x01, 0x00};

	int		cc;


	*(uint32_t *) (cdb + 2) = htonl(page);

	cc = scsicmd(device, cdb, sizeof(cdb), SCSI_DIR_IN, sector, ssector);

	return cc;
}
Beispiel #4
0
static int
WriteHandyStore(scsi_device *device, int page, unsigned char *sector, ssize_t ssector)
{
	char	cdb	[] = {0xDA, 0x00,
		0x00, 0x00, 0x00, 0x0F,
	0x00, 0x00, 0x01, 0x00};

	int	cc;


	*(uint32_t *) (cdb + 2) = htonl(page);
	*(uint16_t *) (cdb + 7) = htons(ssector/512);

	cc = scsicmd(device, cdb, sizeof(cdb), SCSI_DIR_OUT, sector, &ssector);

	return cc;
}
Beispiel #5
0
static int
GetEncryptionStatus(scsi_device *device, struct sEncryptionStatus *e)
{
	char		cdb       [] = {0xC0, 0x45,
		0x00, 0x00, 0x00, 0x00,
		0x00,
		0x00, 0x30,
	0x00};

	int		cc;
	static unsigned char sector[512];
	ssize_t		ssector = sizeof(sector);


	e->isValid = 0;
	cc = scsicmd(device, cdb, sizeof(cdb), SCSI_DIR_IN, sector, &ssector);
	if (cc != 0)
		return cc;

	if (sector[0] != 0x45) {
		warnx("Wrong encryption status signature %X", (int)sector[0]);
		return 1;
	}
	if (e != NULL) {
		e->Signature = sector[0];
		e->reserved1[0] = sector[1];
		e->reserved1[1] = sector[2];
		e->SecurityState = sector[3];
		e->CurrentCipherID = sector[4];
		e->reserved2 = sector[5];
		e->PasswordLength = ntohs(*(uint16_t *) (sector + 6));
		memcpy(e->KeyResetEnabler, sector + 8, 4);
		memcpy(e->reserved3, sector + 12, 3);
		e->NumberOfCiphers = sector[15];
		memset(e->CipherList, 0, sizeof(e->CipherList));
		memcpy(e->CipherList, sector + 16, max(e->NumberOfCiphers, sizeof(e->CipherList)));
		e->isValid = 1;
	}
	//hexdump(sector, ssector, NULL);

	return cc;
}
Beispiel #6
0
static int inquiry (SCSI *scgp, void *bp, int cnt)
{
    struct scg_cmd *scmd = scgp->scmd;

    memset(bp, cnt, '\0');
    memset((caddr_t)scmd, sizeof(*scmd), '\0');
    scmd->addr = bp;
    scmd->size = cnt;
    scmd->flags = SCG_RECV_DATA|SCG_DISRE_ENA;
    scmd->cdb_len = SC_G0_CDBLEN;
    scmd->sense_len = CCS_SENSE_LEN;
    scmd->target = scgp->target;
    scmd->cdb.g0_cdb.cmd = SC_INQUIRY;
    scmd->cdb.g0_cdb.lun = scgp->lun;
    scmd->cdb.g0_cdb.count = cnt;

    scgp->cmdname = "inquiry";

    if (scsicmd(scgp) < 0)
	return (-1);
    return (0);
}