static void copysense(struct scsi_data *sd) { int len = sd->cmd[4]; memset(sd->buffer, 0, len); memcpy(sd->buffer, sd->sense, sd->sense_len > len ? len : sd->sense_len); if (sd->sense_len == 0) sd->buffer[0] = 0x70; sd->data_len = len; showsense (sd); scsi_clear_sense(sd); }
/* Read more data from scsi device into buffer. */ static void scsi_read_data(SCSIRequest *req) { SCSIGenericReq *r = DO_UPCAST(SCSIGenericReq, req, req); SCSIGenericState *s = DO_UPCAST(SCSIGenericState, qdev, r->req.dev); int ret; DPRINTF("scsi_read_data 0x%x\n", req->tag); if (r->len == -1) { scsi_command_complete(r, 0); return; } if (r->req.cmd.buf[0] == REQUEST_SENSE && s->driver_status & SG_ERR_DRIVER_SENSE) { s->senselen = MIN(r->len, s->senselen); memcpy(r->buf, s->sensebuf, s->senselen); r->io_header.driver_status = 0; r->io_header.status = 0; r->io_header.dxfer_len = s->senselen; r->len = -1; DPRINTF("Data ready tag=0x%x len=%d\n", r->req.tag, s->senselen); DPRINTF("Sense: %d %d %d %d %d %d %d %d\n", r->buf[0], r->buf[1], r->buf[2], r->buf[3], r->buf[4], r->buf[5], r->buf[6], r->buf[7]); scsi_req_data(&r->req, s->senselen); /* Clear sensebuf after REQUEST_SENSE */ scsi_clear_sense(s); return; } ret = execute_command(s->bs, r, SG_DXFER_FROM_DEV, scsi_read_complete); if (ret < 0) { scsi_command_complete(r, ret); return; } }
void scsi_emulate_cmd(struct scsi_data *sd) { sd->status = 0; if ((sd->message[0] & 0xc0) == 0x80 && (sd->message[0] & 0x1f)) { uae_u8 lun = sd->message[0] & 0x1f; if (lun > 7) lun = 7; sd->cmd[1] &= ~(7 << 5); sd->cmd[1] |= lun << 5; } //write_log (_T("CMD=%02x\n"), sd->cmd[0]); if (sd->device_type == UAEDEV_CD && sd->cd_emu_unit >= 0) { if (sd->cmd[0] == 0x03) { /* REQUEST SENSE */ scsi_cd_emulate(sd->cd_emu_unit, sd->cmd, 0, 0, 0, 0, 0, 0, 0, sd->atapi); /* ack request sense */ copysense(sd); } else { scsi_clear_sense(sd); sd->status = scsi_cd_emulate(sd->cd_emu_unit, sd->cmd, sd->cmd_len, sd->buffer, &sd->data_len, sd->reply, &sd->reply_len, sd->sense, &sd->sense_len, sd->atapi); copyreply(sd); } } else if (sd->device_type == UAEDEV_HDF && sd->nativescsiunit < 0) { if (sd->cmd[0] == 0x03) { /* REQUEST SENSE */ copysense(sd); } else { scsi_clear_sense(sd); sd->status = scsi_hd_emulate(&sd->hfd->hfd, sd->hfd, sd->cmd, sd->cmd_len, sd->buffer, &sd->data_len, sd->reply, &sd->reply_len, sd->sense, &sd->sense_len); copyreply(sd); } } else if (sd->device_type == UAEDEV_TAPE && sd->nativescsiunit < 0) { if (sd->cmd[0] == 0x03) { /* REQUEST SENSE */ scsi_tape_emulate(sd->tape, sd->cmd, 0, 0, 0, sd->reply, &sd->reply_len, sd->sense, &sd->sense_len); /* get request sense extra bits */ copysense(sd); } else { scsi_clear_sense(sd); sd->status = scsi_tape_emulate(sd->tape, sd->cmd, sd->cmd_len, sd->buffer, &sd->data_len, sd->reply, &sd->reply_len, sd->sense, &sd->sense_len); copyreply(sd); } } else if (sd->nativescsiunit >= 0) { struct amigascsi as; memset(sd->sense, 0, 256); memset(&as, 0, sizeof as); memcpy (&as.cmd, sd->cmd, sd->cmd_len); as.flags = 2 | 1; if (sd->direction > 0) as.flags &= ~1; as.sense_len = 32; as.cmd_len = sd->cmd_len; as.data = sd->buffer; as.len = sd->direction < 0 ? DEVICE_SCSI_BUFSIZE : sd->data_len; sys_command_scsi_direct_native(sd->nativescsiunit, -1, &as); sd->status = as.status; sd->data_len = as.len; if (sd->status) { sd->direction = 0; sd->data_len = 0; memcpy(sd->sense, as.sensedata, as.sense_len); } } sd->offset = 0; }