Revision 1d4db89c hw/scsi-disk.c

b/hw/scsi-disk.c
9 9
 * This code is licenced under the LGPL.
10 10
 *
11 11
 * Note that this file only handles the SCSI architecture model and device
12
 * commands.  Emultion of interface/link layer protocols is handled by
13
 * the host adapter emulation.
12
 * commands.  Emulation of interface/link layer protocols is handled by
13
 * the host adapter emulator.
14 14
 */
15 15

  
16 16
//#define DEBUG_SCSI
......
362 362
        break;
363 363
    case 0x12:
364 364
        DPRINTF("Inquiry (len %d)\n", len);
365
        if (len < 36) {
366
            BADF("Inquiry buffer too small (%d)\n", len);
365
        if (buf[1] & 0x2) {
366
            /* Command support data - optional, not implemented */
367
            BADF("optional INQUIRY command support request not implemented\n");
368
            goto fail;
369
        }
370
        else if (buf[1] & 0x1) {
371
            /* Vital product data */
372
            uint8_t page_code = buf[2];
373
            if (len < 4) {
374
                BADF("Error: Inquiry (EVPD[%02X]) buffer size %d is "
375
                     "less than 4\n", page_code, len);
376
                goto fail;
377
            }
378

  
379
            switch (page_code) {
380
                case 0x00:
381
                    {
382
                        /* Supported page codes, mandatory */
383
                        DPRINTF("Inquiry EVPD[Supported pages] "
384
                                "buffer size %d\n", len);
385

  
386
                        r->buf_len = 0;
387

  
388
                        if (bdrv_get_type_hint(s->bdrv) == BDRV_TYPE_CDROM) {
389
                            outbuf[r->buf_len++] = 5;
390
                        } else {
391
                            outbuf[r->buf_len++] = 0;
392
                        }
393

  
394
                        outbuf[r->buf_len++] = 0x00; // this page
395
                        outbuf[r->buf_len++] = 0x00;
396
                        outbuf[r->buf_len++] = 3;    // number of pages
397
                        outbuf[r->buf_len++] = 0x00; // list of supported pages (this page)
398
                        outbuf[r->buf_len++] = 0x80; // unit serial number
399
                        outbuf[r->buf_len++] = 0x83; // device identification
400
                    }
401
                    break;
402
                case 0x80:
403
                    {
404
                        /* Device serial number, optional */
405
                        if (len < 4) {
406
                            BADF("Error: EVPD[Serial number] Inquiry buffer "
407
                                 "size %d too small, %d needed\n", len, 4);
408
                            goto fail;
409
                        }
410

  
411
                        DPRINTF("Inquiry EVPD[Serial number] buffer size %d\n", len);
412

  
413
                        r->buf_len = 0;
414

  
415
                        /* Supported page codes */
416
                        if (bdrv_get_type_hint(s->bdrv) == BDRV_TYPE_CDROM) {
417
                            outbuf[r->buf_len++] = 5;
418
                        } else {
419
                            outbuf[r->buf_len++] = 0;
420
                        }
421

  
422
                        outbuf[r->buf_len++] = 0x80; // this page
423
                        outbuf[r->buf_len++] = 0x00;
424
                        outbuf[r->buf_len++] = 0x01; // 1 byte data follow
425

  
426
                        outbuf[r->buf_len++] = '0';  // 1 byte data follow 
427
                    }
428

  
429
                    break;
430
                case 0x83:
431
                    {
432
                        /* Device identification page, mandatory */
433
                        int max_len = 255 - 8;
434
                        int id_len = strlen(bdrv_get_device_name(s->bdrv));
435
                        if (id_len > max_len)
436
                            id_len = max_len;
437

  
438
                        DPRINTF("Inquiry EVPD[Device identification] "
439
                                "buffer size %d\n", len);
440
                        r->buf_len = 0;
441
                        if (bdrv_get_type_hint(s->bdrv) == BDRV_TYPE_CDROM) {
442
                            outbuf[r->buf_len++] = 5;
443
                        } else {
444
                            outbuf[r->buf_len++] = 0;
445
                        }
446

  
447
                        outbuf[r->buf_len++] = 0x83; // this page
448
                        outbuf[r->buf_len++] = 0x00;
449
                        outbuf[r->buf_len++] = 3 + id_len;
450

  
451
                        outbuf[r->buf_len++] = 0x2; // ASCII
452
                        outbuf[r->buf_len++] = 0;   // not officially assigned
453
                        outbuf[r->buf_len++] = 0;   // reserved
454
                        outbuf[r->buf_len++] = id_len; // length of data following
455

  
456
                        memcpy(&outbuf[r->buf_len],
457
                               bdrv_get_device_name(s->bdrv), id_len);
458
                        r->buf_len += id_len;
459
                    }
460
                    break;
461
                default:
462
                    BADF("Error: unsupported Inquiry (EVPD[%02X]) "
463
                         "buffer size %d\n", page_code, len);
464
                    goto fail;
465
            }
466
            /* done with EVPD */
467
            break;
468
        }
469
        else {
470
            /* Standard INQUIRY data */
471
            if (buf[2] != 0) {
472
                BADF("Error: Inquiry (STANDARD) page or code "
473
                     "is non-zero [%02X]\n", buf[2]);
474
                goto fail;
475
            }
476

  
477
            /* PAGE CODE == 0 */
478
            if (len < 5) {
479
                BADF("Error: Inquiry (STANDARD) buffer size %d "
480
                     "is less than 5\n", len);
481
                goto fail;
482
            }
483

  
484
            if (len < 36) {
485
                BADF("Error: Inquiry (STANDARD) buffer size %d "
486
                     "is less than 36 (TODO: only 5 required)\n", len);
487
            }
367 488
        }
368 489
	memset(outbuf, 0, 36);
369 490
	if (bdrv_get_type_hint(s->bdrv) == BDRV_TYPE_CDROM) {

Also available in: Unified diff