Revision a9dd6843 hw/scsi-generic.c
b/hw/scsi-generic.c | ||
---|---|---|
44 | 44 |
#include <scsi/sg.h> |
45 | 45 |
#include <scsi/scsi.h> |
46 | 46 |
|
47 |
#define REWIND 0x01 |
|
48 |
#define REPORT_DENSITY_SUPPORT 0x44 |
|
47 | 49 |
#define LOAD_UNLOAD 0xa6 |
48 | 50 |
#define SET_CD_SPEED 0xbb |
49 | 51 |
#define BLANK 0xa1 |
50 | 52 |
|
51 | 53 |
#define SCSI_CMD_BUF_SIZE 16 |
52 |
#define SCSI_SENSE_BUF_SIZE 32
|
|
54 |
#define SCSI_SENSE_BUF_SIZE 96
|
|
53 | 55 |
|
54 | 56 |
#define SG_ERR_DRIVER_TIMEOUT 0x06 |
55 | 57 |
#define SG_ERR_DRIVER_SENSE 0x08 |
... | ... | |
75 | 77 |
{ |
76 | 78 |
SCSIRequest *requests; |
77 | 79 |
BlockDriverState *bdrv; |
80 |
int type; |
|
78 | 81 |
int blocksize; |
79 | 82 |
int lun; |
80 | 83 |
scsi_completionfn completion; |
... | ... | |
163 | 166 |
} else if ((s->driver_status & SG_ERR_DRIVER_SENSE) == 0) |
164 | 167 |
sense = NO_SENSE; |
165 | 168 |
else |
166 |
sense = s->sensebuf[2] & 0x0f;
|
|
169 |
sense = s->sensebuf[2]; |
|
167 | 170 |
} |
168 | 171 |
|
169 | 172 |
DPRINTF("Command complete 0x%p tag=0x%x sense=%d\n", r, r->tag, sense); |
... | ... | |
273 | 276 |
|
274 | 277 |
if (r->cmd[0] == REQUEST_SENSE && s->driver_status & SG_ERR_DRIVER_SENSE) |
275 | 278 |
{ |
276 |
memcpy(r->buf, s->sensebuf, 16); |
|
279 |
int len = MIN(r->len, SCSI_SENSE_BUF_SIZE); |
|
280 |
memcpy(r->buf, s->sensebuf, len); |
|
277 | 281 |
r->io_header.driver_status = 0; |
278 | 282 |
r->len = -1; |
279 |
s->completion(s->opaque, SCSI_REASON_DATA, r->tag, 16); |
|
283 |
DPRINTF("Sense: %d %d %d %d %d %d %d %d\n", |
|
284 |
r->buf[0], r->buf[1], r->buf[2], r->buf[3], |
|
285 |
r->buf[4], r->buf[5], r->buf[6], r->buf[7]); |
|
286 |
s->completion(s->opaque, SCSI_REASON_DATA, r->tag, len); |
|
280 | 287 |
return; |
281 | 288 |
} |
282 | 289 |
|
... | ... | |
434 | 441 |
return 0; |
435 | 442 |
} |
436 | 443 |
|
444 |
static int scsi_stream_length(uint8_t *cmd, int blocksize, int *cmdlen, uint32_t *len) |
|
445 |
{ |
|
446 |
switch(cmd[0]) { |
|
447 |
/* stream commands */ |
|
448 |
case READ_6: |
|
449 |
case READ_REVERSE: |
|
450 |
case RECOVER_BUFFERED_DATA: |
|
451 |
case WRITE_6: |
|
452 |
*cmdlen = 6; |
|
453 |
*len = cmd[4] | (cmd[3] << 8) | (cmd[2] << 16); |
|
454 |
if (cmd[1] & 0x01) /* fixed */ |
|
455 |
*len *= blocksize; |
|
456 |
break; |
|
457 |
case REWIND: |
|
458 |
case START_STOP: |
|
459 |
*cmdlen = 6; |
|
460 |
*len = 0; |
|
461 |
cmd[1] = 0x01; /* force IMMED, otherwise qemu waits end of command */ |
|
462 |
break; |
|
463 |
/* generic commands */ |
|
464 |
default: |
|
465 |
return scsi_length(cmd, blocksize, cmdlen, len); |
|
466 |
} |
|
467 |
return 0; |
|
468 |
} |
|
469 |
|
|
437 | 470 |
static int is_write(int command) |
438 | 471 |
{ |
439 | 472 |
switch (command) { |
... | ... | |
495 | 528 |
return 0; |
496 | 529 |
} |
497 | 530 |
|
498 |
if (scsi_length(cmd, s->blocksize, &cmdlen, &len) == -1) { |
|
499 |
BADF("Unsupported command length, command %x\n", cmd[0]); |
|
500 |
return 0; |
|
531 |
if (s->type == TYPE_TAPE) { |
|
532 |
if (scsi_stream_length(cmd, s->blocksize, &cmdlen, &len) == -1) { |
|
533 |
BADF("Unsupported command length, command %x\n", cmd[0]); |
|
534 |
return 0; |
|
535 |
} |
|
536 |
} else { |
|
537 |
if (scsi_length(cmd, s->blocksize, &cmdlen, &len) == -1) { |
|
538 |
BADF("Unsupported command length, command %x\n", cmd[0]); |
|
539 |
return 0; |
|
540 |
} |
|
501 | 541 |
} |
502 | 542 |
|
503 | 543 |
DPRINTF("Command: lun=%d tag=0x%x data=0x%02x len %d\n", lun, tag, |
... | ... | |
633 | 673 |
s->completion = completion; |
634 | 674 |
s->opaque = opaque; |
635 | 675 |
s->lun = scsiid.lun; |
676 |
s->type = scsiid.scsi_type; |
|
636 | 677 |
s->blocksize = get_blocksize(s->bdrv); |
637 | 678 |
s->driver_status = 0; |
638 | 679 |
memset(s->sensebuf, 0, sizeof(s->sensebuf)); |
639 | 680 |
/* removable media returns 0 if not present */ |
640 |
if (s->blocksize <= 0) |
|
641 |
s->blocksize = 2048; |
|
681 |
if (s->blocksize <= 0) { |
|
682 |
if (s->type == TYPE_ROM || s->type == TYPE_WORM) |
|
683 |
s->blocksize = 2048; |
|
684 |
else |
|
685 |
s->blocksize = 512; |
|
686 |
} |
|
642 | 687 |
|
643 | 688 |
/* define function to manage device */ |
644 | 689 |
|
Also available in: Unified diff