On 01/26/2018 03:15 PM, Steffen Maier wrote:
On 12/18/2017 08:48 AM, Hannes Reinecke wrote:
On 12/15/2017 07:17 PM, Steffen Maier wrote:
On 12/14/2017 11:11 AM, Hannes Reinecke wrote:
@@ -524,10 +532,16 @@ static void virtio_scsi_init_hdr(struct
virtio_device *vdev,
int target_id,
struct scsi_cmnd *sc)
{
- cmd->lun[0] = 1;
- cmd->lun[1] = target_id;
- cmd->lun[2] = (sc->device->lun >> 8) | 0x40;
- cmd->lun[3] = sc->device->lun & 0xff;
+ if (virtio_has_feature(vdev, VIRTIO_SCSI_F_NATIVE_LUN)) {
+ u64 lun = sc->device->lun << 16;
+ lun |= ((u64)1 << 8) | (u64)target_id;
+ int_to_scsilun(lun, (struct scsi_lun *)&cmd->lun);
+ } else {
+ cmd->lun[0] = 1;
+ cmd->lun[1] = target_id;
+ cmd->lun[2] = (sc->device->lun >> 8) | 0x40;
+ cmd->lun[3] = sc->device->lun & 0xff;
+ }
Above 2 patterns seem to repeat. Have helper functions (similar to
int_to_scsilun()) now that it's more than just 4 lines of filling in the
virtio lun?
Yes, can do.
Meanwhile I think I realized why I had trouble understanding what the
code does. I guess, I expected a conversion with int_to_scsilun() first,
and then we would fill in the virtio-specific parts of magic-one and
target-ID.
You do it just the other way round, which is OK.
Say we have a 4 level 64-bit LUN and represent it in hex using
placeholder hexdigits for the 4 levels like this:
0xL1L1L2L2L3L3L4L4
Its decimal SCSI LUN representation (in hex) is:
0xL4L4L3L3L2L2L1L1
Then you shift left by 16 bits (2 bytes, 1 LUN level), basically
dropping the 4th level:
0xL3L3L2L2L1L10000
The steering header is 0x01TT where TT is the target ID.
You bitwise or the virtio-specific parts into the SCSI LUN representation:
0xL3L3L2L2L1L101TT
Finally you convert it into the 64-bit LUN representation:
0x01TTL1L1L2L2L3L3
0123456789abcdef [char array indexes]
0 1 2 3 4 5 6 7
of course
So we nicely have the virtio-specific parts at those array indexes where
the virtio-scsi protocol expects them.
The usage of the other bytes is now of course different from the
original LUN encoding: It allows more than just peripheral and flat
space addressing for the 1st level; and it now also uses levels 2 and 3
which were previously always zero. The 3rd level really requires 64-bit
support in the kvm host kernel.
This also means that a 4-level LUN is not supported unless we would
create a new virtio-scsi protocol version that would transfer the target
ID in a separate field not as part of the LUN field.
Did I get that right?
A similar explanation in a kernel doc comment for the helper conversion
function(s) might be helpful.
--
Mit freundlichen Grüßen / Kind regards
Steffen Maier
Linux on z Systems Development
IBM Deutschland Research & Development GmbH
Vorsitzende des Aufsichtsrats: Martina Koederitz
Geschaeftsfuehrung: Dirk Wittkopp
Sitz der Gesellschaft: Boeblingen
Registergericht: Amtsgericht Stuttgart, HRB 243294