Revision ea3bd56f hw/scsi-disk.c
b/hw/scsi-disk.c | ||
---|---|---|
424 | 424 |
outbuf[buflen++] = 0x80; // unit serial number |
425 | 425 |
outbuf[buflen++] = 0x83; // device identification |
426 | 426 |
if (bdrv_get_type_hint(s->bs) != BDRV_TYPE_CDROM) { |
427 |
outbuf[buflen++] = 0xb0; // block device characteristics |
|
427 |
outbuf[buflen++] = 0xb0; // block limits |
|
428 |
outbuf[buflen++] = 0xb2; // thin provisioning |
|
428 | 429 |
} |
429 | 430 |
outbuf[pages] = buflen - pages - 1; // number of pages |
430 | 431 |
break; |
... | ... | |
466 | 467 |
buflen += id_len; |
467 | 468 |
break; |
468 | 469 |
} |
469 |
case 0xb0: /* block device characteristics */
|
|
470 |
case 0xb0: /* block limits */
|
|
470 | 471 |
{ |
472 |
unsigned int unmap_sectors = |
|
473 |
s->qdev.conf.discard_granularity / s->qdev.blocksize; |
|
471 | 474 |
unsigned int min_io_size = |
472 | 475 |
s->qdev.conf.min_io_size / s->qdev.blocksize; |
473 | 476 |
unsigned int opt_io_size = |
... | ... | |
492 | 495 |
outbuf[13] = (opt_io_size >> 16) & 0xff; |
493 | 496 |
outbuf[14] = (opt_io_size >> 8) & 0xff; |
494 | 497 |
outbuf[15] = opt_io_size & 0xff; |
498 |
|
|
499 |
/* optimal unmap granularity */ |
|
500 |
outbuf[28] = (unmap_sectors >> 24) & 0xff; |
|
501 |
outbuf[29] = (unmap_sectors >> 16) & 0xff; |
|
502 |
outbuf[30] = (unmap_sectors >> 8) & 0xff; |
|
503 |
outbuf[31] = unmap_sectors & 0xff; |
|
504 |
break; |
|
505 |
} |
|
506 |
case 0xb2: /* thin provisioning */ |
|
507 |
{ |
|
508 |
outbuf[3] = buflen = 8; |
|
509 |
outbuf[4] = 0; |
|
510 |
outbuf[5] = 0x40; /* write same with unmap supported */ |
|
511 |
outbuf[6] = 0; |
|
512 |
outbuf[7] = 0; |
|
495 | 513 |
break; |
496 | 514 |
} |
497 | 515 |
default: |
... | ... | |
959 | 977 |
outbuf[11] = 0; |
960 | 978 |
outbuf[12] = 0; |
961 | 979 |
outbuf[13] = get_physical_block_exp(&s->qdev.conf); |
980 |
|
|
981 |
/* set TPE bit if the format supports discard */ |
|
982 |
if (s->qdev.conf.discard_granularity) { |
|
983 |
outbuf[14] = 0x80; |
|
984 |
} |
|
985 |
|
|
962 | 986 |
/* Protection, exponent and lowest lba field left blank. */ |
963 | 987 |
buflen = req->cmd.xfer; |
964 | 988 |
break; |
... | ... | |
1123 | 1147 |
goto illegal_lba; |
1124 | 1148 |
} |
1125 | 1149 |
break; |
1150 |
case WRITE_SAME_16: |
|
1151 |
len = r->req.cmd.xfer / d->blocksize; |
|
1152 |
|
|
1153 |
DPRINTF("WRITE SAME(16) (sector %" PRId64 ", count %d)\n", |
|
1154 |
r->req.cmd.lba, len); |
|
1155 |
|
|
1156 |
if (r->req.cmd.lba > s->max_lba) { |
|
1157 |
goto illegal_lba; |
|
1158 |
} |
|
1159 |
|
|
1160 |
/* |
|
1161 |
* We only support WRITE SAME with the unmap bit set for now. |
|
1162 |
*/ |
|
1163 |
if (!(buf[1] & 0x8)) { |
|
1164 |
goto fail; |
|
1165 |
} |
|
1166 |
|
|
1167 |
rc = bdrv_discard(s->bs, r->req.cmd.lba * s->cluster_size, |
|
1168 |
len * s->cluster_size); |
|
1169 |
if (rc < 0) { |
|
1170 |
/* XXX: better error code ?*/ |
|
1171 |
goto fail; |
|
1172 |
} |
|
1173 |
|
|
1174 |
break; |
|
1126 | 1175 |
default: |
1127 | 1176 |
DPRINTF("Unknown SCSI command (%2.2x)\n", buf[0]); |
1128 | 1177 |
fail: |
Also available in: Unified diff