Message ID | 20240214182535.2533977-1-martin.petersen@oracle.com (mailing list archive) |
---|---|
State | Superseded |
Headers | show |
Series | scsi: core: Consult supported VPD page list prior to fetching page | expand |
On 2/14/24 10:25, Martin K. Petersen wrote: > + for (unsigned int i = SCSI_VPD_HEADER_SIZE ; i < result ; i++) { > + if (vpd[i] == page) > + goto found; > + } Can this loop be changed into a memchr() call? > diff --git a/include/scsi/scsi_device.h b/include/scsi/scsi_device.h > index cb019c80763b..6673885565e3 100644 > --- a/include/scsi/scsi_device.h > +++ b/include/scsi/scsi_device.h > @@ -102,6 +102,7 @@ struct scsi_vpd { > > enum scsi_vpd_parameters { > SCSI_VPD_HEADER_SIZE = 4, > + SCSI_VPD_LIST_SIZE = 36, > }; > > struct scsi_device { Since these constants are only used inside drivers/scsi/scsi.c, how about moving these constants into the drivers/scsi/scsi.c file? Thanks, Bart.
Hi Bart! > On 2/14/24 10:25, Martin K. Petersen wrote: >> + for (unsigned int i = SCSI_VPD_HEADER_SIZE ; i < result ; i++) { >> + if (vpd[i] == page) >> + goto found; >> + } > > Can this loop be changed into a memchr() call? Would you prefer the following? /* Look for page number in the returned list of supported VPDs */ result -= SCSI_VPD_HEADER_SIZE; if (!memchr(&vpd[SCSI_VPD_HEADER_SIZE], page, result)) return 0; I find that the idiomatic for loop is easy to understand whereas the memchr() requires a bit of squinting. But I don't really have a strong preference. I do like that the memchr() gets rid of the goto. >> diff --git a/include/scsi/scsi_device.h b/include/scsi/scsi_device.h >> index cb019c80763b..6673885565e3 100644 >> --- a/include/scsi/scsi_device.h >> +++ b/include/scsi/scsi_device.h >> @@ -102,6 +102,7 @@ struct scsi_vpd { >> enum scsi_vpd_parameters { >> SCSI_VPD_HEADER_SIZE = 4, >> + SCSI_VPD_LIST_SIZE = 36, >> }; >> struct scsi_device { > > Since these constants are only used inside drivers/scsi/scsi.c, how about > moving these constants into the drivers/scsi/scsi.c file? Sure!
On 2/14/24 12:20, Martin K. Petersen wrote: >> On 2/14/24 10:25, Martin K. Petersen wrote: >>> + for (unsigned int i = SCSI_VPD_HEADER_SIZE ; i < result ; i++) { >>> + if (vpd[i] == page) >>> + goto found; >>> + } >> >> Can this loop be changed into a memchr() call? > > Would you prefer the following? > > /* Look for page number in the returned list of supported VPDs */ > result -= SCSI_VPD_HEADER_SIZE; > if (!memchr(&vpd[SCSI_VPD_HEADER_SIZE], page, result)) > return 0; > > I find that the idiomatic for loop is easy to understand whereas the > memchr() requires a bit of squinting. But I don't really have a strong > preference. I do like that the memchr() gets rid of the goto. Although I slightly prefer the memchr() variant, I'm also fine with keeping the for-loop. Thanks, Bart.
diff --git a/drivers/scsi/scsi.c b/drivers/scsi/scsi.c index 76d369343c7a..5ef5fcf022ed 100644 --- a/drivers/scsi/scsi.c +++ b/drivers/scsi/scsi.c @@ -330,19 +330,36 @@ static int scsi_vpd_inquiry(struct scsi_device *sdev, unsigned char *buffer, static int scsi_get_vpd_size(struct scsi_device *sdev, u8 page) { - unsigned char vpd_header[SCSI_VPD_HEADER_SIZE] __aligned(4); + unsigned char vpd[SCSI_VPD_LIST_SIZE] __aligned(4); int result; if (sdev->no_vpd_size) return SCSI_DEFAULT_VPD_LEN; + /* + * Fetch the supported pages VPD and validate that the requested page + * number is present. + */ + if (page != 0) { + result = scsi_vpd_inquiry(sdev, vpd, 0, sizeof(vpd)); + if (result < SCSI_VPD_HEADER_SIZE) + return 0; + + for (unsigned int i = SCSI_VPD_HEADER_SIZE ; i < result ; i++) { + if (vpd[i] == page) + goto found; + } + + return 0; + } +found: /* * Fetch the VPD page header to find out how big the page * is. This is done to prevent problems on legacy devices * which can not handle allocation lengths as large as * potentially requested by the caller. */ - result = scsi_vpd_inquiry(sdev, vpd_header, page, sizeof(vpd_header)); + result = scsi_vpd_inquiry(sdev, vpd, page, SCSI_VPD_HEADER_SIZE); if (result < 0) return 0; diff --git a/include/scsi/scsi_device.h b/include/scsi/scsi_device.h index cb019c80763b..6673885565e3 100644 --- a/include/scsi/scsi_device.h +++ b/include/scsi/scsi_device.h @@ -102,6 +102,7 @@ struct scsi_vpd { enum scsi_vpd_parameters { SCSI_VPD_HEADER_SIZE = 4, + SCSI_VPD_LIST_SIZE = 36, }; struct scsi_device {