Luben Tuikov wrote:
> In fact, I'd do
> typedef __u8 lun_t[8];
> and then define the macro
> #define LUN_TO_U64(_lun) ((unsigned long long) be64_to_cpu(*(__be64
> *)(_lun)))
Don't forget __attribute__((aligned(8))) on lun_t then. Some
architectures need it.
The macro should perhaps be called LUN_TO_ULL, as there is also an u64
type in the kernel.
> This way one could do stuff like:*
> printk(KERN_NOTICE "problem xyz with LUN:%016llx\n", LUN_TO_U64(sdev->LUN));
How about:
union scsi_lun {
__u8 lun[8];
__be64 lun64;
__be16 lun16;
};
This will also be sufficiently aligned.
[...]
> * It is in fact more correct to do, at the _transport_ layer:
>
> printk(... "problem xyz with %016llx:%016llx\n",
> sdev->target->tpid, sdev->LUN);
>
> Here, it is explicitly shown that sdev (/dev/sdXYZ) is a child of
> a target, having a tpid attribute, and the sdev has a property
> of lun_t called LUN.
>
> So, for example, for SAS, the message would print like this:
>
> problem xyz with 5000a50000f13427:0000000000000000
>
> which uniquely identifies the device and then the sysadmin
> can go to the storage farm, find it and replace it if need be.
There are two things to consider:
- Is ->target representing a Target Device? Then it could have more
than one port, each one with a different identifier. Or is it
representing a Target Port? Or is it representing a Target Device
with the twist that we instantiate as many ->target objects as the
device is showing ports to us?
- If the identifier is stored in ->target, and is an object known to
mid-layer, then we need a datatype for ->target->tpid which is
flexible enough for all flavors of TPID.
So, if tpid ends up in objects seen by mid-layer, the datatype of ->tpid
could be either
__u8 target_port_identifier[233]; /* enough for all */
or
__u8 target_port_identifier[0]; /* variable length */
or
struct scsi_target_port_identifier {
enum transport_protocol {
SCSI_TRANSPORT_UNKNOWN = 0,
SCSI_TRANSPORT_SPI,
SCSI_TRANSPORT_FCP,
SCSI_TRANSPORT_SRP,
SCSI_TRANSPORT_ISCSI,
SCSI_TRANSPORT_SBP,
SCSI_TRANSPORT_SAS,
} format;
union {
unsigned spi_tpid:4;
__u8 fcp_tpid[3]; /* or __be32 fcp_tpid:24; ? */
struct {
__be64 eui64;
__be64 extension;
} srp_tpid;
struct {
__u8 name[224];
__32 tpgt;
} iscsi_tpid;
struct {
__be64 eui64;
__be32 directory_id:24;
/* SAM calls this mistakenly "Discovery ID" */
} sbp_tpid;
__be64 sas_tpid;
} value;
};
or something else.
The former two require that print functions reside in transport layer
implementations. Note, the transport layer can easily make these print
functions available to mid-layer so that mid-layer can print TPIDs too,
without knowing what's in a TPID. I.e. transport layer hands out string
representations of TPIDs to mid-layer.
The third variant allows to put the print function into mid-layer.
Before you call it a heresy: SAM says how many bits or bytes are in the
identifiers, hence a generic SAM implementation can know how to print
them. It only doesn't know how the values get in there.
PS: Sorry that I continue to drag TPID into the discussion about LUN,
but in the end you need both to identify hardware.
--
Stefan Richter
-=====-=-=== -==- ===--
http://arcgraph.de/sr/
-
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at http://vger.kernel.org/majordomo-info.html