Commit 18ee70c9d7b2dcd312a1f8c6536841e7c0fea5ca

Authored by Chandra Seetharaman
Committed by James Bottomley
1 parent 21fab1d059

[SCSI] scsi_dh: add the interface scsi_dh_set_params()

When we moved the device handler functionality from dm layer to SCSI layer
we dropped the parameter functionality.

This path adds an interface to scsi dh layer to set device handler
parameters.

Basically, multipath layer need to create a string with all the parameters
and call scsi_dh_set_params() after it called scsi_dh_attach() on a
device.

If a device handler provides such an interface it will handle the parameters
as it expects them.

Reported-by: Eddie Williams <Eddie.Williams@steeleye.com>
Signed-off-by: Chandra Seetharaman <sekharan@us.ibm.com>
Tested-by: Eddie Williams <Eddie.Williams@steeleye.com>
Signed-off-by: James Bottomley <James.Bottomley@HansenPartnership.com>
Signed-off-by: James Bottomley <James.Bottomley@suse.de>

Showing 3 changed files with 39 additions and 0 deletions Side-by-side Diff

drivers/scsi/device_handler/scsi_dh.c
... ... @@ -452,6 +452,39 @@
452 452 EXPORT_SYMBOL_GPL(scsi_dh_activate);
453 453  
454 454 /*
  455 + * scsi_dh_set_params - set the parameters for the device as per the
  456 + * string specified in params.
  457 + * @q - Request queue that is associated with the scsi_device for
  458 + * which the parameters to be set.
  459 + * @params - parameters in the following format
  460 + * "no_of_params\0param1\0param2\0param3\0...\0"
  461 + * for example, string for 2 parameters with value 10 and 21
  462 + * is specified as "2\010\021\0".
  463 + */
  464 +int scsi_dh_set_params(struct request_queue *q, const char *params)
  465 +{
  466 + int err = -SCSI_DH_NOSYS;
  467 + unsigned long flags;
  468 + struct scsi_device *sdev;
  469 + struct scsi_device_handler *scsi_dh = NULL;
  470 +
  471 + spin_lock_irqsave(q->queue_lock, flags);
  472 + sdev = q->queuedata;
  473 + if (sdev && sdev->scsi_dh_data)
  474 + scsi_dh = sdev->scsi_dh_data->scsi_dh;
  475 + if (scsi_dh && scsi_dh->set_params && get_device(&sdev->sdev_gendev))
  476 + err = 0;
  477 + spin_unlock_irqrestore(q->queue_lock, flags);
  478 +
  479 + if (err)
  480 + return err;
  481 + err = scsi_dh->set_params(sdev, params);
  482 + put_device(&sdev->sdev_gendev);
  483 + return err;
  484 +}
  485 +EXPORT_SYMBOL_GPL(scsi_dh_set_params);
  486 +
  487 +/*
455 488 * scsi_dh_handler_exist - Return TRUE(1) if a device handler exists for
456 489 * the given name. FALSE(0) otherwise.
457 490 * @name - name of the device handler.
include/scsi/scsi_device.h
... ... @@ -187,6 +187,7 @@
187 187 void (*detach)(struct scsi_device *);
188 188 int (*activate)(struct scsi_device *);
189 189 int (*prep_fn)(struct scsi_device *, struct request *);
  190 + int (*set_params)(struct scsi_device *, const char *);
190 191 };
191 192  
192 193 struct scsi_dh_data {
include/scsi/scsi_dh.h
... ... @@ -60,6 +60,7 @@
60 60 extern int scsi_dh_handler_exist(const char *);
61 61 extern int scsi_dh_attach(struct request_queue *, const char *);
62 62 extern void scsi_dh_detach(struct request_queue *);
  63 +extern int scsi_dh_set_params(struct request_queue *, const char *);
63 64 #else
64 65 static inline int scsi_dh_activate(struct request_queue *req)
65 66 {
... ... @@ -76,6 +77,10 @@
76 77 static inline void scsi_dh_detach(struct request_queue *q)
77 78 {
78 79 return;
  80 +}
  81 +static inline int scsi_dh_set_params(struct request_queue *req, const char *params)
  82 +{
  83 + return -SCSI_DH_NOSYS;
79 84 }
80 85 #endif