static int ibmvio_inquiry(int host_no, struct scsi_cmd *cmd) { uint8_t *data, *scb = cmd->scb; unsigned char key = ILLEGAL_REQUEST; uint16_t asc = ASC_INVALID_FIELD_IN_CDB; uint32_t len; if (((scb[1] & 0x3) == 0x3) || (!(scb[1] & 0x3) && scb[2])) goto sense; dprintf("%x %x\n", scb[1], scb[2]); if (scb[1] & 0x3) return spc_inquiry(host_no, cmd); data = scsi_get_in_buffer(cmd); len = __ibmvio_inquiry(host_no, cmd, data); len = min_t(int, len, scb[4]); scsi_set_in_resid_by_actual(cmd, len); if (cmd->dev->lun != cmd->dev_id) data[0] = TYPE_NO_LUN; return SAM_STAT_GOOD; sense: scsi_set_in_resid_by_actual(cmd, 0); sense_data_build(cmd, key, asc); return SAM_STAT_CHECK_CONDITION; }
static int resp_var_read(struct scsi_cmd *cmd, uint8_t *buf, uint32_t length, int *transferred) { struct ssc_info *ssc = dtype_priv(cmd->dev); struct blk_header_info *h = &ssc->c_blk; int ret = 0, result = SAM_STAT_GOOD; length = min(length, get_unaligned_be24(&cmd->scb[2])); *transferred = 0; if (length != h->blk_sz) { uint8_t info[4]; int val = length - h->blk_sz; put_unaligned_be32(val, info); if (h->blk_type == BLK_EOD) sense_data_build(cmd, 0x40 | BLANK_CHECK, NO_ADDITIONAL_SENSE); else ssc_sense_data_build(cmd, NO_SENSE | 0x20, NO_ADDITIONAL_SENSE, info, sizeof(info)); if (length > h->blk_sz) scsi_set_in_resid_by_actual(cmd, length - h->blk_sz); else scsi_set_in_resid_by_actual(cmd, 0); length = min(length, h->blk_sz); result = SAM_STAT_CHECK_CONDITION; if (!length) goto out; } ret = pread64(cmd->dev->fd, buf, length, h->curr + SSC_BLK_HDR_SIZE); if (ret != length) { sense_data_build(cmd, MEDIUM_ERROR, ASC_READ_ERROR); result = SAM_STAT_CHECK_CONDITION; goto out; } *transferred = length; ret = skip_next_header(cmd->dev); if (ret) { sense_data_build(cmd, MEDIUM_ERROR, ASC_MEDIUM_FORMAT_CORRUPT); result = SAM_STAT_CHECK_CONDITION; } out: return result; }
static int ssc_rw(int host_no, struct scsi_cmd *cmd) { int ret; unsigned char key = ILLEGAL_REQUEST; uint16_t asc = ASC_LUN_NOT_SUPPORTED; ret = device_reserved(cmd); if (ret) return SAM_STAT_RESERVATION_CONFLICT; cmd->scsi_cmd_done = target_cmd_io_done; ret = cmd->dev->bst->bs_cmd_submit(cmd); if (ret) { key = HARDWARE_ERROR; asc = ASC_INTERNAL_TGT_FAILURE; } else { set_cmd_mmapio(cmd); return SAM_STAT_GOOD; } cmd->offset = 0; scsi_set_in_resid_by_actual(cmd, 0); scsi_set_out_resid_by_actual(cmd, 0); sense_data_build(cmd, key, asc); return SAM_STAT_CHECK_CONDITION; }