scsi-disk: add some optional scsi commands
I use a legacy OS which depends on some optional SCSI commands. In fact this implementation does nothing special, but provides minimum support for the following commands: REZERO UNIT WRITE AND VERIFY(10) WRITE AND VERIFY(12) WRITE AND VERIFY(16) MODE SELECT(6) MODE SELECT(10) SEEK(6) SEEK(10) Signed-off-by: Bernhard Kohl <bernhard.kohl@nsn.com> Signed-off-by: Kevin Wolf <kwolf@redhat.com>
This commit is contained in:
		
							parent
							
								
									79d1d33113
								
							
						
					
					
						commit
						ebef0bbb1a
					
				@ -892,6 +892,12 @@ static int scsi_disk_emulate_command(SCSIRequest *req, uint8_t *outbuf)
 | 
				
			|||||||
        break;
 | 
					        break;
 | 
				
			||||||
    case VERIFY:
 | 
					    case VERIFY:
 | 
				
			||||||
        break;
 | 
					        break;
 | 
				
			||||||
 | 
					    case REZERO_UNIT:
 | 
				
			||||||
 | 
					        DPRINTF("Rezero Unit\n");
 | 
				
			||||||
 | 
					        if (!bdrv_is_inserted(s->bs)) {
 | 
				
			||||||
 | 
					            goto not_ready;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        break;
 | 
				
			||||||
    default:
 | 
					    default:
 | 
				
			||||||
        goto illegal_request;
 | 
					        goto illegal_request;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
@ -1011,6 +1017,7 @@ static int32_t scsi_send_command(SCSIDevice *d, uint32_t tag,
 | 
				
			|||||||
    case SERVICE_ACTION_IN:
 | 
					    case SERVICE_ACTION_IN:
 | 
				
			||||||
    case REPORT_LUNS:
 | 
					    case REPORT_LUNS:
 | 
				
			||||||
    case VERIFY:
 | 
					    case VERIFY:
 | 
				
			||||||
 | 
					    case REZERO_UNIT:
 | 
				
			||||||
        rc = scsi_disk_emulate_command(&r->req, outbuf);
 | 
					        rc = scsi_disk_emulate_command(&r->req, outbuf);
 | 
				
			||||||
        if (rc > 0) {
 | 
					        if (rc > 0) {
 | 
				
			||||||
            r->iov.iov_len = rc;
 | 
					            r->iov.iov_len = rc;
 | 
				
			||||||
@ -1034,13 +1041,40 @@ static int32_t scsi_send_command(SCSIDevice *d, uint32_t tag,
 | 
				
			|||||||
    case WRITE_10:
 | 
					    case WRITE_10:
 | 
				
			||||||
    case WRITE_12:
 | 
					    case WRITE_12:
 | 
				
			||||||
    case WRITE_16:
 | 
					    case WRITE_16:
 | 
				
			||||||
        DPRINTF("Write (sector %" PRId64 ", count %d)\n", lba, len);
 | 
					    case WRITE_VERIFY:
 | 
				
			||||||
 | 
					    case WRITE_VERIFY_12:
 | 
				
			||||||
 | 
					    case WRITE_VERIFY_16:
 | 
				
			||||||
 | 
					        DPRINTF("Write %s(sector %" PRId64 ", count %d)\n",
 | 
				
			||||||
 | 
					                (command & 0xe) == 0xe ? "And Verify " : "", lba, len);
 | 
				
			||||||
        if (lba > s->max_lba)
 | 
					        if (lba > s->max_lba)
 | 
				
			||||||
            goto illegal_lba;
 | 
					            goto illegal_lba;
 | 
				
			||||||
        r->sector = lba * s->cluster_size;
 | 
					        r->sector = lba * s->cluster_size;
 | 
				
			||||||
        r->sector_count = len * s->cluster_size;
 | 
					        r->sector_count = len * s->cluster_size;
 | 
				
			||||||
        is_write = 1;
 | 
					        is_write = 1;
 | 
				
			||||||
        break;
 | 
					        break;
 | 
				
			||||||
 | 
					    case MODE_SELECT:
 | 
				
			||||||
 | 
					        DPRINTF("Mode Select(6) (len %d)\n", len);
 | 
				
			||||||
 | 
					        /* We don't support mode parameter changes.
 | 
				
			||||||
 | 
					           Allow the mode parameter header + block descriptors only. */
 | 
				
			||||||
 | 
					        if (len > 12) {
 | 
				
			||||||
 | 
					            goto fail;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        break;
 | 
				
			||||||
 | 
					    case MODE_SELECT_10:
 | 
				
			||||||
 | 
					        DPRINTF("Mode Select(10) (len %d)\n", len);
 | 
				
			||||||
 | 
					        /* We don't support mode parameter changes.
 | 
				
			||||||
 | 
					           Allow the mode parameter header + block descriptors only. */
 | 
				
			||||||
 | 
					        if (len > 16) {
 | 
				
			||||||
 | 
					            goto fail;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        break;
 | 
				
			||||||
 | 
					    case SEEK_6:
 | 
				
			||||||
 | 
					    case SEEK_10:
 | 
				
			||||||
 | 
					        DPRINTF("Seek(%d) (sector %" PRId64 ")\n", command == SEEK_6 ? 6 : 10, lba);
 | 
				
			||||||
 | 
					        if (lba > s->max_lba) {
 | 
				
			||||||
 | 
					            goto illegal_lba;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        break;
 | 
				
			||||||
    default:
 | 
					    default:
 | 
				
			||||||
	DPRINTF("Unknown SCSI command (%2.2x)\n", buf[0]);
 | 
						DPRINTF("Unknown SCSI command (%2.2x)\n", buf[0]);
 | 
				
			||||||
    fail:
 | 
					    fail:
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user