Commit 18ee70c9 authored by Chandra Seetharaman's avatar Chandra Seetharaman Committed by James Bottomley

[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: default avatarEddie Williams <Eddie.Williams@steeleye.com>
Signed-off-by: default avatarChandra Seetharaman <sekharan@us.ibm.com>
Tested-by: default avatarEddie Williams <Eddie.Williams@steeleye.com>
Signed-off-by: default avatarJames Bottomley <James.Bottomley@HansenPartnership.com>
Signed-off-by: default avatarJames Bottomley <James.Bottomley@suse.de>
parent 21fab1d0
...@@ -451,6 +451,39 @@ int scsi_dh_activate(struct request_queue *q) ...@@ -451,6 +451,39 @@ int scsi_dh_activate(struct request_queue *q)
} }
EXPORT_SYMBOL_GPL(scsi_dh_activate); EXPORT_SYMBOL_GPL(scsi_dh_activate);
/*
* scsi_dh_set_params - set the parameters for the device as per the
* string specified in params.
* @q - Request queue that is associated with the scsi_device for
* which the parameters to be set.
* @params - parameters in the following format
* "no_of_params\0param1\0param2\0param3\0...\0"
* for example, string for 2 parameters with value 10 and 21
* is specified as "2\010\021\0".
*/
int scsi_dh_set_params(struct request_queue *q, const char *params)
{
int err = -SCSI_DH_NOSYS;
unsigned long flags;
struct scsi_device *sdev;
struct scsi_device_handler *scsi_dh = NULL;
spin_lock_irqsave(q->queue_lock, flags);
sdev = q->queuedata;
if (sdev && sdev->scsi_dh_data)
scsi_dh = sdev->scsi_dh_data->scsi_dh;
if (scsi_dh && scsi_dh->set_params && get_device(&sdev->sdev_gendev))
err = 0;
spin_unlock_irqrestore(q->queue_lock, flags);
if (err)
return err;
err = scsi_dh->set_params(sdev, params);
put_device(&sdev->sdev_gendev);
return err;
}
EXPORT_SYMBOL_GPL(scsi_dh_set_params);
/* /*
* scsi_dh_handler_exist - Return TRUE(1) if a device handler exists for * scsi_dh_handler_exist - Return TRUE(1) if a device handler exists for
* the given name. FALSE(0) otherwise. * the given name. FALSE(0) otherwise.
......
...@@ -187,6 +187,7 @@ struct scsi_device_handler { ...@@ -187,6 +187,7 @@ struct scsi_device_handler {
void (*detach)(struct scsi_device *); void (*detach)(struct scsi_device *);
int (*activate)(struct scsi_device *); int (*activate)(struct scsi_device *);
int (*prep_fn)(struct scsi_device *, struct request *); int (*prep_fn)(struct scsi_device *, struct request *);
int (*set_params)(struct scsi_device *, const char *);
}; };
struct scsi_dh_data { struct scsi_dh_data {
......
...@@ -60,6 +60,7 @@ extern int scsi_dh_activate(struct request_queue *); ...@@ -60,6 +60,7 @@ extern int scsi_dh_activate(struct request_queue *);
extern int scsi_dh_handler_exist(const char *); extern int scsi_dh_handler_exist(const char *);
extern int scsi_dh_attach(struct request_queue *, const char *); extern int scsi_dh_attach(struct request_queue *, const char *);
extern void scsi_dh_detach(struct request_queue *); extern void scsi_dh_detach(struct request_queue *);
extern int scsi_dh_set_params(struct request_queue *, const char *);
#else #else
static inline int scsi_dh_activate(struct request_queue *req) static inline int scsi_dh_activate(struct request_queue *req)
{ {
...@@ -77,4 +78,8 @@ static inline void scsi_dh_detach(struct request_queue *q) ...@@ -77,4 +78,8 @@ static inline void scsi_dh_detach(struct request_queue *q)
{ {
return; return;
} }
static inline int scsi_dh_set_params(struct request_queue *req, const char *params)
{
return -SCSI_DH_NOSYS;
}
#endif #endif
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment