@@ -564,6 +564,7 @@ static int scsi_dev_info_list_add_str(char *dev_list)
* @sdev: &scsi_device to get flags for
* @vendor: vendor name
* @model: model name
+ * @flags: (output) device specific flags
*
* Description:
* Search the global scsi_dev_info_list (specified by list zero)
@@ -571,12 +572,11 @@ static int scsi_dev_info_list_add_str(char *dev_list)
* matching flags value, else return the host or global default
* settings. Called during scan time.
**/
-int scsi_get_device_flags(struct scsi_device *sdev,
- const unsigned char *vendor,
- const unsigned char *model)
+int scsi_get_device_flags(struct scsi_device *sdev, const unsigned char *vendor,
+ const unsigned char *model, unsigned int *flags)
{
return scsi_get_device_flags_keyed(sdev, vendor, model,
- SCSI_DEVINFO_GLOBAL);
+ SCSI_DEVINFO_GLOBAL, flags);
}
@@ -586,6 +586,7 @@ int scsi_get_device_flags(struct scsi_device *sdev,
* @vendor: vendor name
* @model: model name
* @key: list to look up
+ * @flags: (output) device specific flags
*
* Description:
* Search the scsi_dev_info_list specified by @key for an entry
@@ -596,28 +597,30 @@ int scsi_get_device_flags(struct scsi_device *sdev,
int scsi_get_device_flags_keyed(struct scsi_device *sdev,
const unsigned char *vendor,
const unsigned char *model,
- int key)
+ int key, unsigned int *flags)
{
struct scsi_dev_info_list *devinfo;
int err;
devinfo = scsi_dev_info_list_find(vendor, model, key);
- if (!IS_ERR(devinfo))
- return devinfo->flags;
+ if (!IS_ERR(devinfo)) {
+ *flags = devinfo->flags;
+ return 0;
+ }
err = PTR_ERR(devinfo);
if (err != -ENOENT)
return err;
/* nothing found, return nothing */
- if (key != SCSI_DEVINFO_GLOBAL)
+ if (key != SCSI_DEVINFO_GLOBAL) {
+ *flags = 0;
return 0;
+ }
/* except for the global list, where we have an exception */
- if (sdev->sdev_bflags)
- return sdev->sdev_bflags;
-
- return scsi_default_dev_flags;
+ *flags = sdev->sdev_bflags ? : scsi_default_dev_flags;
+ return 0;
}
EXPORT_SYMBOL(scsi_get_device_flags_keyed);
@@ -52,10 +52,12 @@ enum {
extern int scsi_get_device_flags(struct scsi_device *sdev,
const unsigned char *vendor,
- const unsigned char *model);
+ const unsigned char *model,
+ unsigned int *flags);
extern int scsi_get_device_flags_keyed(struct scsi_device *sdev,
const unsigned char *vendor,
- const unsigned char *model, int key);
+ const unsigned char *model, int key,
+ unsigned int *flags);
extern int scsi_dev_info_list_add_keyed(int compatible, char *vendor,
char *model, char *strflags,
int flags, int key);
@@ -650,8 +650,8 @@ static int scsi_probe_lun(struct scsi_device *sdev, unsigned char *inq_result,
* corresponding bit fields in scsi_device, so bflags
* need not be passed as an argument.
*/
- *bflags = scsi_get_device_flags(sdev, &inq_result[8],
- &inq_result[16]);
+ scsi_get_device_flags(sdev, &inq_result[8], &inq_result[16],
+ bflags);
/* When the first pass succeeds we gain information about
* what larger transfer lengths might work. */
@@ -1074,10 +1074,11 @@ static int scsi_probe_and_add_lun(struct scsi_target *starget,
else
scsi_device_put(sdev);
- if (bflagsp)
- *bflagsp = scsi_get_device_flags(sdev,
- sdev->vendor,
- sdev->model);
+ if (bflagsp) {
+ *bflagsp = 0;
+ scsi_get_device_flags(sdev, sdev->vendor,
+ sdev->model, bflagsp);
+ }
return SCSI_SCAN_LUN_PRESENT;
}
scsi_device_put(sdev);
@@ -221,9 +221,10 @@ static int spi_device_configure(struct transport_container *tc,
{
struct scsi_device *sdev = to_scsi_device(dev);
struct scsi_target *starget = sdev->sdev_target;
- unsigned bflags = scsi_get_device_flags_keyed(sdev, &sdev->inquiry[8],
- &sdev->inquiry[16],
- SCSI_DEVINFO_SPI);
+ unsigned int bflags = 0;
+
+ scsi_get_device_flags_keyed(sdev, &sdev->inquiry[8], &sdev->inquiry[16],
+ SCSI_DEVINFO_SPI, &bflags);
/* Populate the target capability fields with the values
* gleaned from the device inquiry */
Since commit 28a0bc4120d3 ("scsi: sd: Implement blacklist option for WRITE SAME w/ UNMAP") bit 31 is a valid device information flag. Separate device information flags and return codes such that it becomes possible to check whether or not scsi_get_device_flags_keyed(). succeeded. This patch also avoids that error codes returned by scsi_get_device_flags_keyed() are interpret as device flags. Signed-off-by: Bart Van Assche <bart.vanassche@wdc.com> Cc: Christoph Hellwig <hch@lst.de> Cc: Hannes Reinecke <hare@suse.com> Cc: Johannes Thumshirn <jthumshirn@suse.de> --- drivers/scsi/scsi_devinfo.c | 27 +++++++++++++++------------ drivers/scsi/scsi_priv.h | 6 ++++-- drivers/scsi/scsi_scan.c | 13 +++++++------ drivers/scsi/scsi_transport_spi.c | 7 ++++--- 4 files changed, 30 insertions(+), 23 deletions(-)