static ndmp9_error scsi_fail_with_sense_code(struct ndm_session *sess, ndmp9_execute_cdb_reply *reply, int status, int sense_key, int asq) { unsigned char ext_sense[] = { 0x72, /* current errors */ sense_key & SCSI_SENSE_SENSE_KEY_MASK, (asq >> 8) & 0xff, (asq ) & 0xff, 0, 0, 0, 0 }; ndmalogf(sess, 0, 3, "sending failure; status=0x%02x sense_key=0x%02x asq=0x%04x", status, sense_key, asq); reply->status = status; reply->ext_sense.ext_sense_len = sizeof(ext_sense); reply->ext_sense.ext_sense_val = NDMOS_API_MALLOC(sizeof(ext_sense)); NDMOS_API_BCOPY(ext_sense, reply->ext_sense.ext_sense_val, sizeof(ext_sense)); return NDMP9_NO_ERR; }
static ndmp9_error execute_cdb_inquiry (struct ndm_session *sess, ndmp9_execute_cdb_request *request, ndmp9_execute_cdb_reply *reply) { unsigned char *cdb = (unsigned char *)request->cdb.cdb_val; char *response; int response_len; char *p; /* N.B.: only page code 0 is supported */ if (request->cdb.cdb_len != 6 || request->data_dir != NDMP9_SCSI_DATA_DIR_IN || cdb[1] & 0x01 || cdb[2] != 0 || request->datain_len < 96 || ((cdb[3] << 8) + cdb[4]) < 96) return scsi_fail_with_sense_code(sess, reply, SCSI_STATUS_CHECK_CONDITION, SCSI_SENSE_KEY_ILLEGAL_REQUEST, ASQ_INVALID_FIELD_IN_CDB); response_len = 96; p = response = NDMOS_API_MALLOC(response_len); NDMOS_API_BZERO(response, response_len); *(p++) = 0x08; /* media changer */ *(p++) = 0; /* RMB=0 */ *(p++) = 6; /* VERSION=SPC-4 */ *(p++) = 2; /* !NORMACA, !HISUP, RESPONSE DATA FORMAT = 2 */ *(p++) = 92; /* remaining bytes */ *(p++) = 0; /* lots of flags, all 0 */ *(p++) = 0; /* lots of flags, all 0 */ *(p++) = 0; /* lots of flags, all 0 */ NDMOS_API_BCOPY("NDMJOB ", p, 8); p += 8; NDMOS_API_BCOPY("FakeRobot ", p, 16); p += 16; NDMOS_API_BCOPY("1.0 ", p, 4); p += 4; /* remainder is zero */ reply->datain.datain_len = response_len; reply->datain.datain_val = response; return NDMP9_NO_ERR; }
void * ndmfhh_save_item (struct ndmfhheap *fhh, void *item, unsigned size) { void * p; p = ndmfhh_add_item (fhh, size); if (p) { NDMOS_API_BCOPY (item, p, size); } return p; }
int wrap_reco_receive (struct wrap_ccb *wccb) { char * iobuf_end = &wccb->iobuf[wccb->n_iobuf]; char * have_end = wccb->have + wccb->have_length; unsigned n_read = iobuf_end - have_end; int rc; if (wccb->error) return wccb->error; if (wccb->have_length == 0) { wccb->have = wccb->iobuf; have_end = wccb->have + wccb->have_length; } if (n_read < 512 && wccb->have != wccb->iobuf) { /* Not much room at have_end. Front of iobuf available. */ /* Compress */ NDMOS_API_BCOPY (wccb->have, wccb->iobuf, wccb->have_length); wccb->have = wccb->iobuf; have_end = wccb->have + wccb->have_length; n_read = iobuf_end - have_end; } if (n_read > wccb->reading_length) n_read = wccb->reading_length; if (n_read == 0) { /* Hmmm. */ abort (); return -1; } rc = read (wccb->data_conn_fd, have_end, n_read); if (rc > 0) { wccb->have_length += rc; wccb->reading_offset += rc; wccb->reading_length -= rc; } else { /* EOF or error */ if (rc == 0) { strcpy (wccb->errmsg, "EOF on data connection"); wrap_set_error (wccb, -1); } else { sprintf (wccb->errmsg, "errno %d on data connection", errno); wrap_set_errno (wccb); } } return wccb->error; }