[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <yq1tuek347m.fsf@ca-mkp.ca.oracle.com>
Date: Mon, 03 Jan 2022 16:28:35 -0500
From: "Martin K. Petersen" <martin.petersen@...cle.com>
To: "Maciej W. Rozycki" <macro@...am.me.uk>
Cc: Douglas Gilbert <dgilbert@...erlog.com>,
Khalid Aziz <khalid@...ehiking.org>,
"James E.J. Bottomley" <jejb@...ux.ibm.com>,
"Martin K. Petersen" <martin.petersen@...cle.com>,
Christoph Hellwig <hch@....de>, Nix <nix@...eri.org.uk>,
linux-scsi@...r.kernel.org, linux-kernel@...r.kernel.org
Subject: Re: [PATCH v3 3/3] scsi: Set allocation length to 255 for ATA
Information VPD page
Maciej,
> So I do have all the reasons to conclude this value has indeed been
> arbitrarily chosen, don't I?
The SAT spec defines the contents of the first part of the page. The
trailing 512 bytes are defined in the ATA spec.
> If you insist that the value of 64 stay, then please come up with a
> suitable macro name to define along with SCSI_VPD_PG_LEN that reflects
> the meaning of 64 in this context and I'll be happy to update 3/3
> accordingly, but please explain why the value of 64 is any better than
> 255 here and the inconsistency with the buffer size justified.
Can please you try the following patch?
--
Martin K. Petersen Oracle Linux Engineering
Subject: [PATCH] scsi: core: Request VPD page header before fetching full page
We currently default to 255 bytes when fetching for VPD pages during
discovery. However, we have had a few devices that are known to wedge if
the requested buffer exceeds a certain size. See commit af73623f5f10
("[SCSI] sd: Reduce buffer size for vpd request") which works around one
example of this problem in the SCSI disk driver.
With commit d188b0675b21 ("scsi: core: Add sysfs attributes for VPD pages
0h and 89h") we now risk triggering the same issue in the generic midlayer
code.
The problem with the ATA VPD page in particular is that the SCSI portion of
the page is trailed by 512 bytes of verbatim ATA Identify Device
information. However, not all controllers actually provide the additional
512 bytes and will lock up if one asks for more than the 64 bytes
containing the SCSI protocol fields.
Instead of picking a new, somewhat arbitrary, number of bytes for the
default VPD buffer size, first fetch the 4-byte header for each page. The
header contains the size of the page as far as the device is concerned. Use
this reported size to allocate the permanent VPD buffer and then proceed to
fetch the full page up to a 1K limit.
Signed-off-by: Martin K. Petersen <martin.petersen@...cle.com>
Fixes: d188b0675b21 ("scsi: core: Add sysfs attributes for VPD pages 0h and 89h")
diff --git a/drivers/scsi/scsi.c b/drivers/scsi/scsi.c
index 211aace69c22..d45c4d7526d5 100644
--- a/drivers/scsi/scsi.c
+++ b/drivers/scsi/scsi.c
@@ -384,7 +384,13 @@ EXPORT_SYMBOL_GPL(scsi_get_vpd_page);
static struct scsi_vpd *scsi_get_vpd_buf(struct scsi_device *sdev, u8 page)
{
struct scsi_vpd *vpd_buf;
- int vpd_len = SCSI_VPD_PG_LEN, result;
+ int vpd_len, result;
+ unsigned char vpd_header[SCSI_VPD_HEADER_SIZE];
+
+ result = scsi_vpd_inquiry(sdev, vpd_header, page, SCSI_VPD_HEADER_SIZE);
+ if (result < SCSI_VPD_HEADER_SIZE || result > SCSI_VPD_MAX_SIZE)
+ return NULL;
+ vpd_len = result;
retry_pg:
vpd_buf = kmalloc(sizeof(*vpd_buf) + vpd_len, GFP_KERNEL);
diff --git a/include/scsi/scsi_device.h b/include/scsi/scsi_device.h
index d1c6fc83b1e3..6d6c44e8da08 100644
--- a/include/scsi/scsi_device.h
+++ b/include/scsi/scsi_device.h
@@ -100,6 +100,11 @@ struct scsi_vpd {
unsigned char data[];
};
+enum scsi_vpd_parameters {
+ SCSI_VPD_HEADER_SIZE = 4,
+ SCSI_VPD_MAX_SIZE = 1024,
+};
+
struct scsi_device {
struct Scsi_Host *host;
struct request_queue *request_queue;
@@ -141,7 +146,6 @@ struct scsi_device {
const char * model; /* ... after scan; point to static string */
const char * rev; /* ... "nullnullnullnull" before scan */
-#define SCSI_VPD_PG_LEN 255
struct scsi_vpd __rcu *vpd_pg0;
struct scsi_vpd __rcu *vpd_pg83;
struct scsi_vpd __rcu *vpd_pg80;
Powered by blists - more mailing lists