/* * 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); }
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; }
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; }
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; }
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; }
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); }