From 6d95a6206a2e3375746351ca8002f81dc31eb2f4 Mon Sep 17 00:00:00 2001
From: Paolo Bonzini <pbonzini@redhat.com>
Date: Wed, 22 Feb 2012 14:12:22 +0100
Subject: [PATCH 066/109] scsi: move max_lba to SCSIDevice

RH-Author: Paolo Bonzini <pbonzini@redhat.com>
Message-id: <1329919979-20948-66-git-send-email-pbonzini@redhat.com>
Patchwork-id: 37543
O-Subject: [RHEL 6.3 qemu-kvm PATCH v2 065/102] scsi: move max_lba to SCSIDevice
Bugzilla: 782029
RH-Acked-by: Laszlo Ersek <lersek@redhat.com>
RH-Acked-by: Orit Wasserman <owasserm@redhat.com>
RH-Acked-by: Gerd Hoffmann <kraxel@redhat.com>

The field is only in scsi-disk for now.  Moving it up to SCSIDevice makes
it easier to reuse the scsi-generic reqops elsewhere.

At the same time, make scsi-generic get max_lba from snooped READ CAPACITY
commands as well.

Upstream used ld*_be_p functions, which are not available to
common code in RHEL6 qemu.

Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
(cherry picked from 7877903aa0ef318017441c32605bc64650e6a326)

Conflicts:
	hw/scsi-generic.c (due to differences in patch 58)
---
 hw/scsi-disk.c    |   15 +++++++--------
 hw/scsi-generic.c |    6 ++++++
 hw/scsi.h         |    1 +
 3 files changed, 14 insertions(+), 8 deletions(-)

Signed-off-by: Michal Novotny <minovotn@redhat.com>
---
 hw/scsi-disk.c    |   15 +++++++--------
 hw/scsi-generic.c |    6 ++++++
 hw/scsi.h         |    1 +
 3 files changed, 14 insertions(+), 8 deletions(-)

diff --git a/hw/scsi-disk.c b/hw/scsi-disk.c
index 9188196..4d35851 100644
--- a/hw/scsi-disk.c
+++ b/hw/scsi-disk.c
@@ -65,7 +65,6 @@ struct SCSIDiskState
 {
     SCSIDevice qdev;
     uint32_t removable;
-    uint64_t max_lba;
     bool media_changed;
     bool media_event;
     bool eject_request;
@@ -1219,7 +1218,7 @@ static int scsi_disk_emulate_command(SCSIDiskReq *r)
         /* Returned value is the address of the last sector.  */
         nb_sectors--;
         /* Remember the new size for read/write sanity checking. */
-        s->max_lba = nb_sectors;
+        s->qdev.max_lba = nb_sectors;
         /* Clip to 2TB, instead of returning capacity modulo 2TB. */
         if (nb_sectors > UINT32_MAX) {
             nb_sectors = UINT32_MAX;
@@ -1274,7 +1273,7 @@ static int scsi_disk_emulate_command(SCSIDiskReq *r)
             /* Returned value is the address of the last sector.  */
             nb_sectors--;
             /* Remember the new size for read/write sanity checking. */
-            s->max_lba = nb_sectors;
+            s->qdev.max_lba = nb_sectors;
             outbuf[0] = (nb_sectors >> 56) & 0xff;
             outbuf[1] = (nb_sectors >> 48) & 0xff;
             outbuf[2] = (nb_sectors >> 40) & 0xff;
@@ -1392,7 +1391,7 @@ static int32_t scsi_send_command(SCSIRequest *req, uint8_t *buf)
     case READ_16:
         len = r->req.cmd.xfer / s->qdev.blocksize;
         DPRINTF("Read (sector %" PRId64 ", count %d)\n", r->req.cmd.lba, len);
-        if (r->req.cmd.lba > s->max_lba) {
+        if (r->req.cmd.lba > s->qdev.max_lba) {
             goto illegal_lba;
         }
         r->sector = r->req.cmd.lba * (s->qdev.blocksize / 512);
@@ -1409,7 +1408,7 @@ static int32_t scsi_send_command(SCSIRequest *req, uint8_t *buf)
         DPRINTF("Write %s(sector %" PRId64 ", count %d)\n",
                 (command & 0xe) == 0xe ? "And Verify " : "",
                 r->req.cmd.lba, len);
-        if (r->req.cmd.lba > s->max_lba) {
+        if (r->req.cmd.lba > s->qdev.max_lba) {
             goto illegal_lba;
         }
         r->sector = r->req.cmd.lba * (s->qdev.blocksize / 512);
@@ -1435,7 +1434,7 @@ static int32_t scsi_send_command(SCSIRequest *req, uint8_t *buf)
     case SEEK_10:
         DPRINTF("Seek(%d) (sector %" PRId64 ")\n", command == SEEK_6 ? 6 : 10,
                 r->req.cmd.lba);
-        if (r->req.cmd.lba > s->max_lba) {
+        if (r->req.cmd.lba > s->qdev.max_lba) {
             goto illegal_lba;
         }
         break;
@@ -1445,7 +1444,7 @@ static int32_t scsi_send_command(SCSIRequest *req, uint8_t *buf)
         DPRINTF("WRITE SAME(16) (sector %" PRId64 ", count %d)\n",
                 r->req.cmd.lba, len);
 
-        if (r->req.cmd.lba > s->max_lba) {
+        if (r->req.cmd.lba > s->qdev.max_lba) {
             goto illegal_lba;
         }
 
@@ -1504,7 +1503,7 @@ static void scsi_disk_reset(DeviceState *dev)
     if (nb_sectors) {
         nb_sectors--;
     }
-    s->max_lba = nb_sectors;
+    s->qdev.max_lba = nb_sectors;
 }
 
 static void scsi_destroy(SCSIDevice *dev)
diff --git a/hw/scsi-generic.c b/hw/scsi-generic.c
index 2a3fc82..c303b2d 100644
--- a/hw/scsi-generic.c
+++ b/hw/scsi-generic.c
@@ -175,10 +175,16 @@ static void scsi_read_complete(void * opaque, int ret)
         if (r->req.cmd.buf[0] == READ_CAPACITY_10) {
             s->blocksize = (r->buf[4] << 24) | (r->buf[5] << 16) |
                            (r->buf[6] << 8) | r->buf[7];
+            s->max_lba = ((uint64_t) r->buf[0] << 24) | ((uint64_t) r->buf[1] << 16) |
+                         ((uint64_t) r->buf[2] << 8) | (uint64_t) r->buf[3];
         } else if (r->req.cmd.buf[0] == SERVICE_ACTION_IN_16 &&
                    (r->req.cmd.buf[1] & 31) == SAI_READ_CAPACITY_16) {
             s->blocksize = (r->buf[8] << 24) | (r->buf[9] << 16) |
                            (r->buf[10] << 8) | r->buf[11];
+            s->max_lba = ((uint64_t) r->buf[0] << 56) | ((uint64_t) r->buf[1] << 48) |
+                         ((uint64_t) r->buf[2] << 40) | ((uint64_t) r->buf[3] << 32) | 
+                         ((uint64_t) r->buf[4] << 24) | ((uint64_t) r->buf[5] << 16) |
+                         ((uint64_t) r->buf[6] << 8) | (uint64_t) r->buf[7];
         }
         s->conf.bs->buffer_alignment = s->blocksize;
 
diff --git a/hw/scsi.h b/hw/scsi.h
index 5c5d069..52b5315 100644
--- a/hw/scsi.h
+++ b/hw/scsi.h
@@ -72,6 +72,7 @@ struct SCSIDevice
     uint32_t lun;
     int blocksize;
     int type;
+    uint64_t max_lba;
 };
 
 /* cdrom.c */
-- 
1.7.7.6

