+ if (buf[1] & 0x2) {
+ /* Command support data - optional, not implemented */
+ BADF("optional INQUIRY command support request not implemented\n");
+ goto fail;
+ }
+ else if (buf[1] & 0x1) {
+ /* Vital product data */
+ uint8_t page_code = buf[2];
+ if (len < 4) {
+ BADF("Error: Inquiry (EVPD[%02X]) buffer size %d is "
+ "less than 4\n", page_code, len);
+ goto fail;
+ }
+
+ switch (page_code) {
+ case 0x00:
+ {
+ /* Supported page codes, mandatory */
+ DPRINTF("Inquiry EVPD[Supported pages] "
+ "buffer size %d\n", len);
+
+ r->iov.iov_len = 0;
+
+ if (bdrv_get_type_hint(s->bdrv) == BDRV_TYPE_CDROM) {
+ outbuf[r->iov.iov_len++] = 5;
+ } else {
+ outbuf[r->iov.iov_len++] = 0;
+ }
+
+ outbuf[r->iov.iov_len++] = 0x00; // this page
+ outbuf[r->iov.iov_len++] = 0x00;
+ outbuf[r->iov.iov_len++] = 3; // number of pages
+ outbuf[r->iov.iov_len++] = 0x00; // list of supported pages (this page)
+ outbuf[r->iov.iov_len++] = 0x80; // unit serial number
+ outbuf[r->iov.iov_len++] = 0x83; // device identification
+ }
+ break;
+ case 0x80:
+ {
+ int l;
+
+ /* Device serial number, optional */
+ if (len < 4) {
+ BADF("Error: EVPD[Serial number] Inquiry buffer "
+ "size %d too small, %d needed\n", len, 4);
+ goto fail;
+ }
+
+ DPRINTF("Inquiry EVPD[Serial number] buffer size %d\n", len);
+ l = MIN(len, strlen(s->drive_serial_str));
+
+ r->iov.iov_len = 0;
+
+ /* Supported page codes */
+ if (bdrv_get_type_hint(s->bdrv) == BDRV_TYPE_CDROM) {
+ outbuf[r->iov.iov_len++] = 5;
+ } else {
+ outbuf[r->iov.iov_len++] = 0;
+ }
+
+ outbuf[r->iov.iov_len++] = 0x80; // this page
+ outbuf[r->iov.iov_len++] = 0x00;
+ outbuf[r->iov.iov_len++] = l;
+ memcpy(&outbuf[r->iov.iov_len], s->drive_serial_str, l);
+ r->iov.iov_len += l;
+ }
+
+ break;
+ case 0x83:
+ {
+ /* Device identification page, mandatory */
+ int max_len = 255 - 8;
+ int id_len = strlen(bdrv_get_device_name(s->bdrv));
+ if (id_len > max_len)
+ id_len = max_len;
+
+ DPRINTF("Inquiry EVPD[Device identification] "
+ "buffer size %d\n", len);
+ r->iov.iov_len = 0;
+ if (bdrv_get_type_hint(s->bdrv) == BDRV_TYPE_CDROM) {
+ outbuf[r->iov.iov_len++] = 5;
+ } else {
+ outbuf[r->iov.iov_len++] = 0;
+ }
+
+ outbuf[r->iov.iov_len++] = 0x83; // this page
+ outbuf[r->iov.iov_len++] = 0x00;
+ outbuf[r->iov.iov_len++] = 3 + id_len;
+
+ outbuf[r->iov.iov_len++] = 0x2; // ASCII
+ outbuf[r->iov.iov_len++] = 0; // not officially assigned
+ outbuf[r->iov.iov_len++] = 0; // reserved
+ outbuf[r->iov.iov_len++] = id_len; // length of data following
+
+ memcpy(&outbuf[r->iov.iov_len],
+ bdrv_get_device_name(s->bdrv), id_len);
+ r->iov.iov_len += id_len;
+ }
+ break;
+ default:
+ BADF("Error: unsupported Inquiry (EVPD[%02X]) "
+ "buffer size %d\n", page_code, len);
+ goto fail;
+ }
+ /* done with EVPD */
+ break;