Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit ee14c674 authored by Christoph Hellwig's avatar Christoph Hellwig Committed by James Bottomley
Browse files

scsi_dh: kill struct scsi_dh_data



Add a ->handler and a ->handler_data field to struct scsi_device and kill
this indirection.  Also move struct scsi_device_handler to scsi_dh.h so that
changes to it don't require rebuilding every SCSI LLDD.

Signed-off-by: default avatarChristoph Hellwig <hch@lst.de>
Reviewed-by: default avatarMartin K. Petersen <martin.petersen@oracle.com>
Reviewed-by: default avatarHannes Reinecke <hare@suse.de>
Signed-off-by: default avatarJames Bottomley <JBottomley@Odin.com>
parent d95dbff2
Loading
Loading
Loading
Loading
+10 −15
Original line number Diff line number Diff line
@@ -62,7 +62,6 @@
#define ALUA_OPTIMIZE_STPG		1

struct alua_dh_data {
	struct scsi_dh_data	dh_data;
	int			group_id;
	int			rel_port;
	int			tpgs;
@@ -86,11 +85,6 @@ struct alua_dh_data {
static char print_alua_state(int);
static int alua_check_sense(struct scsi_device *, struct scsi_sense_hdr *);

static inline struct alua_dh_data *get_alua_data(struct scsi_device *sdev)
{
	return container_of(sdev->scsi_dh_data, struct alua_dh_data, dh_data);
}

static int realloc_buffer(struct alua_dh_data *h, unsigned len)
{
	if (h->buff && h->buff != h->inq)
@@ -708,7 +702,7 @@ static int alua_initialize(struct scsi_device *sdev, struct alua_dh_data *h)
 */
static int alua_set_params(struct scsi_device *sdev, const char *params)
{
	struct alua_dh_data *h = get_alua_data(sdev);
	struct alua_dh_data *h = sdev->handler_data;
	unsigned int optimize = 0, argc;
	const char *p = params;
	int result = SCSI_DH_OK;
@@ -746,7 +740,7 @@ MODULE_PARM_DESC(optimize_stpg, "Allow use of a non-optimized path, rather than
static int alua_activate(struct scsi_device *sdev,
			activate_complete fn, void *data)
{
	struct alua_dh_data *h = get_alua_data(sdev);
	struct alua_dh_data *h = sdev->handler_data;
	int err = SCSI_DH_OK;
	int stpg = 0;

@@ -804,7 +798,7 @@ static int alua_activate(struct scsi_device *sdev,
 */
static int alua_prep_fn(struct scsi_device *sdev, struct request *req)
{
	struct alua_dh_data *h = get_alua_data(sdev);
	struct alua_dh_data *h = sdev->handler_data;
	int ret = BLKPREP_OK;

	if (h->state == TPGS_STATE_TRANSITIONING)
@@ -823,14 +817,14 @@ static int alua_prep_fn(struct scsi_device *sdev, struct request *req)
 * alua_bus_attach - Attach device handler
 * @sdev: device to be attached to
 */
static struct scsi_dh_data *alua_bus_attach(struct scsi_device *sdev)
static int alua_bus_attach(struct scsi_device *sdev)
{
	struct alua_dh_data *h;
	int err;

	h = kzalloc(sizeof(*h) , GFP_KERNEL);
	if (!h)
		return ERR_PTR(-ENOMEM);
		return -ENOMEM;
	h->tpgs = TPGS_MODE_UNINITIALIZED;
	h->state = TPGS_STATE_OPTIMIZED;
	h->group_id = -1;
@@ -843,11 +837,11 @@ static struct scsi_dh_data *alua_bus_attach(struct scsi_device *sdev)
	if (err != SCSI_DH_OK && err != SCSI_DH_DEV_OFFLINED)
		goto failed;

	sdev_printk(KERN_NOTICE, sdev, "%s: Attached\n", ALUA_DH_NAME);
	return &h->dh_data;
	sdev->handler_data = h;
	return 0;
failed:
	kfree(h);
	return ERR_PTR(-EINVAL);
	return -EINVAL;
}

/*
@@ -856,10 +850,11 @@ static struct scsi_dh_data *alua_bus_attach(struct scsi_device *sdev)
 */
static void alua_bus_detach(struct scsi_device *sdev)
{
	struct alua_dh_data *h = get_alua_data(sdev);
	struct alua_dh_data *h = sdev->handler_data;

	if (h->buff && h->inq != h->buff)
		kfree(h->buff);
	sdev->handler_data = NULL;
	kfree(h);
}

+11 −18
Original line number Diff line number Diff line
@@ -72,7 +72,6 @@ static const char * lun_state[] =
};

struct clariion_dh_data {
	struct scsi_dh_data dh_data;
	/*
	 * Flags:
	 *  CLARIION_SHORT_TRESPASS
@@ -114,13 +113,6 @@ struct clariion_dh_data {
	int current_sp;
};

static inline struct clariion_dh_data
			*get_clariion_data(struct scsi_device *sdev)
{
	return container_of(sdev->scsi_dh_data, struct clariion_dh_data,
			dh_data);
}

/*
 * Parse MODE_SELECT cmd reply.
 */
@@ -450,7 +442,7 @@ static int clariion_check_sense(struct scsi_device *sdev,

static int clariion_prep_fn(struct scsi_device *sdev, struct request *req)
{
	struct clariion_dh_data *h = get_clariion_data(sdev);
	struct clariion_dh_data *h = sdev->handler_data;
	int ret = BLKPREP_OK;

	if (h->lun_state != CLARIION_LUN_OWNED) {
@@ -533,7 +525,7 @@ static int clariion_send_inquiry(struct scsi_device *sdev,
static int clariion_activate(struct scsi_device *sdev,
				activate_complete fn, void *data)
{
	struct clariion_dh_data *csdev = get_clariion_data(sdev);
	struct clariion_dh_data *csdev = sdev->handler_data;
	int result;

	result = clariion_send_inquiry(sdev, csdev);
@@ -574,7 +566,7 @@ static int clariion_activate(struct scsi_device *sdev,
 */
static int clariion_set_params(struct scsi_device *sdev, const char *params)
{
	struct clariion_dh_data *csdev = get_clariion_data(sdev);
	struct clariion_dh_data *csdev = sdev->handler_data;
	unsigned int hr = 0, st = 0, argc;
	const char *p = params;
	int result = SCSI_DH_OK;
@@ -622,14 +614,14 @@ static int clariion_set_params(struct scsi_device *sdev, const char *params)
	return result;
}

static struct scsi_dh_data *clariion_bus_attach(struct scsi_device *sdev)
static int clariion_bus_attach(struct scsi_device *sdev)
{
	struct clariion_dh_data *h;
	int err;

	h = kzalloc(sizeof(*h) , GFP_KERNEL);
	if (!h)
		return ERR_PTR(-ENOMEM);
		return -ENOMEM;
	h->lun_state = CLARIION_LUN_UNINITIALIZED;
	h->default_sp = CLARIION_UNBOUND_LU;
	h->current_sp = CLARIION_UNBOUND_LU;
@@ -647,18 +639,19 @@ static struct scsi_dh_data *clariion_bus_attach(struct scsi_device *sdev)
		    CLARIION_NAME, h->current_sp + 'A',
		    h->port, lun_state[h->lun_state],
		    h->default_sp + 'A');
	return &h->dh_data;

	sdev->handler_data = h;
	return 0;

failed:
	kfree(h);
	return ERR_PTR(-EINVAL);
	return -EINVAL;
}

static void clariion_bus_detach(struct scsi_device *sdev)
{
	struct clariion_dh_data *h = get_clariion_data(sdev);

	kfree(h);
	kfree(sdev->handler_data);
	sdev->handler_data = NULL;
}

static struct scsi_device_handler clariion_dh = {
+10 −15
Original line number Diff line number Diff line
@@ -38,7 +38,6 @@
#define HP_SW_PATH_PASSIVE		1

struct hp_sw_dh_data {
	struct scsi_dh_data dh_data;
	unsigned char sense[SCSI_SENSE_BUFFERSIZE];
	int path_state;
	int retries;
@@ -50,11 +49,6 @@ struct hp_sw_dh_data {

static int hp_sw_start_stop(struct hp_sw_dh_data *);

static inline struct hp_sw_dh_data *get_hp_sw_data(struct scsi_device *sdev)
{
	return container_of(sdev->scsi_dh_data, struct hp_sw_dh_data, dh_data);
}

/*
 * tur_done - Handle TEST UNIT READY return status
 * @sdev: sdev the command has been sent to
@@ -267,7 +261,7 @@ static int hp_sw_start_stop(struct hp_sw_dh_data *h)

static int hp_sw_prep_fn(struct scsi_device *sdev, struct request *req)
{
	struct hp_sw_dh_data *h = get_hp_sw_data(sdev);
	struct hp_sw_dh_data *h = sdev->handler_data;
	int ret = BLKPREP_OK;

	if (h->path_state != HP_SW_PATH_ACTIVE) {
@@ -292,7 +286,7 @@ static int hp_sw_activate(struct scsi_device *sdev,
				activate_complete fn, void *data)
{
	int ret = SCSI_DH_OK;
	struct hp_sw_dh_data *h = get_hp_sw_data(sdev);
	struct hp_sw_dh_data *h = sdev->handler_data;

	ret = hp_sw_tur(sdev, h);

@@ -311,14 +305,14 @@ static int hp_sw_activate(struct scsi_device *sdev,
	return 0;
}

static struct scsi_dh_data *hp_sw_bus_attach(struct scsi_device *sdev)
static int hp_sw_bus_attach(struct scsi_device *sdev)
{
	struct hp_sw_dh_data *h;
	int ret;

	h = kzalloc(sizeof(*h), GFP_KERNEL);
	if (!h)
		return ERR_PTR(-ENOMEM);
		return -ENOMEM;
	h->path_state = HP_SW_PATH_UNINITIALIZED;
	h->retries = HP_SW_RETRIES;
	h->sdev = sdev;
@@ -330,17 +324,18 @@ static struct scsi_dh_data *hp_sw_bus_attach(struct scsi_device *sdev)
	sdev_printk(KERN_INFO, sdev, "%s: attached to %s path\n",
		    HP_SW_NAME, h->path_state == HP_SW_PATH_ACTIVE?
		    "active":"passive");
	return &h->dh_data;

	sdev->handler_data = h;
	return 0;
failed:
	kfree(h);
	return ERR_PTR(-EINVAL);
	return -EINVAL;
}

static void hp_sw_bus_detach( struct scsi_device *sdev )
{
	struct hp_sw_dh_data *h = get_hp_sw_data(sdev);

	kfree(h);
	kfree(sdev->handler_data);
	sdev->handler_data = NULL;
}

static struct scsi_device_handler hp_sw_dh = {
+13 −17
Original line number Diff line number Diff line
@@ -181,7 +181,6 @@ struct c2_inquiry {
};

struct rdac_dh_data {
	struct scsi_dh_data	dh_data;
	struct rdac_controller	*ctlr;
#define UNINITIALIZED_LUN	(1 << 8)
	unsigned		lun;
@@ -260,11 +259,6 @@ do { \
		sdev_printk(KERN_INFO, sdev, RDAC_NAME ": " f "\n", ## arg); \
} while (0);

static inline struct rdac_dh_data *get_rdac_data(struct scsi_device *sdev)
{
	return container_of(sdev->scsi_dh_data, struct rdac_dh_data, dh_data);
}

static struct request *get_rdac_req(struct scsi_device *sdev,
			void *buffer, unsigned buflen, int rw)
{
@@ -544,7 +538,7 @@ static int mode_select_handle_sense(struct scsi_device *sdev,
{
	struct scsi_sense_hdr sense_hdr;
	int err = SCSI_DH_IO, ret;
	struct rdac_dh_data *h = get_rdac_data(sdev);
	struct rdac_dh_data *h = sdev->handler_data;

	ret = scsi_normalize_sense(sensebuf, SCSI_SENSE_BUFFERSIZE, &sense_hdr);
	if (!ret)
@@ -589,7 +583,7 @@ static void send_mode_select(struct work_struct *work)
		container_of(work, struct rdac_controller, ms_work);
	struct request *rq;
	struct scsi_device *sdev = ctlr->ms_sdev;
	struct rdac_dh_data *h = get_rdac_data(sdev);
	struct rdac_dh_data *h = sdev->handler_data;
	struct request_queue *q = sdev->request_queue;
	int err, retry_cnt = RDAC_RETRY_COUNT;
	struct rdac_queue_data *tmp, *qdata;
@@ -648,7 +642,7 @@ static int queue_mode_select(struct scsi_device *sdev,
	if (!qdata)
		return SCSI_DH_RETRY;

	qdata->h = get_rdac_data(sdev);
	qdata->h = sdev->handler_data;
	qdata->callback_fn = fn;
	qdata->callback_data = data;

@@ -667,7 +661,7 @@ static int queue_mode_select(struct scsi_device *sdev,
static int rdac_activate(struct scsi_device *sdev,
			activate_complete fn, void *data)
{
	struct rdac_dh_data *h = get_rdac_data(sdev);
	struct rdac_dh_data *h = sdev->handler_data;
	int err = SCSI_DH_OK;
	int act = 0;

@@ -702,7 +696,7 @@ static int rdac_activate(struct scsi_device *sdev,

static int rdac_prep_fn(struct scsi_device *sdev, struct request *req)
{
	struct rdac_dh_data *h = get_rdac_data(sdev);
	struct rdac_dh_data *h = sdev->handler_data;
	int ret = BLKPREP_OK;

	if (h->state != RDAC_STATE_ACTIVE) {
@@ -716,7 +710,7 @@ static int rdac_prep_fn(struct scsi_device *sdev, struct request *req)
static int rdac_check_sense(struct scsi_device *sdev,
				struct scsi_sense_hdr *sense_hdr)
{
	struct rdac_dh_data *h = get_rdac_data(sdev);
	struct rdac_dh_data *h = sdev->handler_data;

	RDAC_LOG(RDAC_LOG_SENSE, sdev, "array %s, ctlr %d, "
			"I/O returned with sense %02x/%02x/%02x",
@@ -778,7 +772,7 @@ static int rdac_check_sense(struct scsi_device *sdev,
	return SCSI_RETURN_NOT_HANDLED;
}

static struct scsi_dh_data *rdac_bus_attach(struct scsi_device *sdev)
static int rdac_bus_attach(struct scsi_device *sdev)
{
	struct rdac_dh_data *h;
	int err;
@@ -787,7 +781,7 @@ static struct scsi_dh_data *rdac_bus_attach(struct scsi_device *sdev)

	h = kzalloc(sizeof(*h) , GFP_KERNEL);
	if (!h)
		return ERR_PTR(-ENOMEM);
		return -ENOMEM;
	h->lun = UNINITIALIZED_LUN;
	h->state = RDAC_STATE_ACTIVE;

@@ -812,7 +806,8 @@ static struct scsi_dh_data *rdac_bus_attach(struct scsi_device *sdev)
		    RDAC_NAME, h->lun, mode[(int)h->mode],
		    lun_state[(int)h->lun_state]);

	return &h->dh_data;
	sdev->handler_data = h;
	return 0;

clean_ctlr:
	spin_lock(&list_lock);
@@ -821,12 +816,12 @@ static struct scsi_dh_data *rdac_bus_attach(struct scsi_device *sdev)

failed:
	kfree(h);
	return ERR_PTR(-EINVAL);
	return -EINVAL;
}

static void rdac_bus_detach( struct scsi_device *sdev )
{
	struct rdac_dh_data *h = get_rdac_data(sdev);
	struct rdac_dh_data *h = sdev->handler_data;

	if (h->ctlr && h->ctlr->ms_queued)
		flush_workqueue(kmpath_rdacd);
@@ -835,6 +830,7 @@ static void rdac_bus_detach( struct scsi_device *sdev )
	if (h->ctlr)
		kref_put(&h->ctlr->kref, release_controller);
	spin_unlock(&list_lock);
	sdev->handler_data = NULL;
	kfree(h);
}

+28 −47
Original line number Diff line number Diff line
@@ -126,26 +126,20 @@ static struct scsi_device_handler *scsi_dh_lookup(const char *name)
static int scsi_dh_handler_attach(struct scsi_device *sdev,
				  struct scsi_device_handler *scsi_dh)
{
	struct scsi_dh_data *d;
	int error;

	if (!try_module_get(scsi_dh->module))
		return -EINVAL;

	d = scsi_dh->attach(sdev);
	if (IS_ERR(d)) {
		sdev_printk(KERN_ERR, sdev, "%s: Attach failed (%ld)\n",
			    scsi_dh->name, PTR_ERR(d));
	error = scsi_dh->attach(sdev);
	if (error) {
		sdev_printk(KERN_ERR, sdev, "%s: Attach failed (%d)\n",
			    scsi_dh->name, error);
		module_put(scsi_dh->module);
		return PTR_ERR(d);
	}

	d->scsi_dh = scsi_dh;
	d->sdev = sdev;
	} else
		sdev->handler = scsi_dh;

	spin_lock_irq(sdev->request_queue->queue_lock);
	sdev->scsi_dh_data = d;
	spin_unlock_irq(sdev->request_queue->queue_lock);
	return 0;
	return error;
}

/*
@@ -154,17 +148,9 @@ static int scsi_dh_handler_attach(struct scsi_device *sdev,
 */
static void scsi_dh_handler_detach(struct scsi_device *sdev)
{
	struct scsi_dh_data *scsi_dh_data = sdev->scsi_dh_data;
	struct scsi_device_handler *scsi_dh = scsi_dh_data->scsi_dh;

	scsi_dh->detach(sdev);

	spin_lock_irq(sdev->request_queue->queue_lock);
	sdev->scsi_dh_data = NULL;
	spin_unlock_irq(sdev->request_queue->queue_lock);

	sdev_printk(KERN_NOTICE, sdev, "%s: Detached\n", scsi_dh->name);
	module_put(scsi_dh->module);
	sdev->handler->detach(sdev);
	sdev_printk(KERN_NOTICE, sdev, "%s: Detached\n", sdev->handler->name);
	module_put(sdev->handler->module);
}

/*
@@ -182,7 +168,7 @@ store_dh_state(struct device *dev, struct device_attribute *attr,
	    sdev->sdev_state == SDEV_DEL)
		return -ENODEV;

	if (!sdev->scsi_dh_data) {
	if (!sdev->handler) {
		/*
		 * Attach to a device handler
		 */
@@ -191,7 +177,6 @@ store_dh_state(struct device *dev, struct device_attribute *attr,
			return err;
		err = scsi_dh_handler_attach(sdev, scsi_dh);
	} else {
		scsi_dh = sdev->scsi_dh_data->scsi_dh;
		if (!strncmp(buf, "detach", 6)) {
			/*
			 * Detach from a device handler
@@ -202,8 +187,8 @@ store_dh_state(struct device *dev, struct device_attribute *attr,
			/*
			 * Activate a device handler
			 */
			if (scsi_dh->activate)
				err = scsi_dh->activate(sdev, NULL, NULL);
			if (sdev->handler->activate)
				err = sdev->handler->activate(sdev, NULL, NULL);
			else
				err = 0;
		}
@@ -217,10 +202,10 @@ show_dh_state(struct device *dev, struct device_attribute *attr, char *buf)
{
	struct scsi_device *sdev = to_scsi_device(dev);

	if (!sdev->scsi_dh_data)
	if (!sdev->handler)
		return snprintf(buf, 20, "detached\n");

	return snprintf(buf, 20, "%s\n", sdev->scsi_dh_data->scsi_dh->name);
	return snprintf(buf, 20, "%s\n", sdev->handler->name);
}

static struct device_attribute scsi_dh_state_attr =
@@ -247,7 +232,7 @@ int scsi_dh_add_device(struct scsi_device *sdev)

void scsi_dh_remove_device(struct scsi_device *sdev)
{
	if (sdev->scsi_dh_data)
	if (sdev->handler)
		scsi_dh_handler_detach(sdev);
	device_remove_file(&sdev->sdev_gendev, &scsi_dh_state_attr);
}
@@ -316,7 +301,6 @@ int scsi_dh_activate(struct request_queue *q, activate_complete fn, void *data)
	int err = 0;
	unsigned long flags;
	struct scsi_device *sdev;
	struct scsi_device_handler *scsi_dh = NULL;
	struct device *dev = NULL;

	spin_lock_irqsave(q->queue_lock, flags);
@@ -329,10 +313,8 @@ int scsi_dh_activate(struct request_queue *q, activate_complete fn, void *data)
		return err;
	}

	if (sdev->scsi_dh_data)
		scsi_dh = sdev->scsi_dh_data->scsi_dh;
	dev = get_device(&sdev->sdev_gendev);
	if (!scsi_dh || !dev ||
	if (!sdev->handler || !dev ||
	    sdev->sdev_state == SDEV_CANCEL ||
	    sdev->sdev_state == SDEV_DEL)
		err = SCSI_DH_NOSYS;
@@ -346,8 +328,8 @@ int scsi_dh_activate(struct request_queue *q, activate_complete fn, void *data)
		goto out;
	}

	if (scsi_dh->activate)
		err = scsi_dh->activate(sdev, fn, data);
	if (sdev->handler->activate)
		err = sdev->handler->activate(sdev, fn, data);
out:
	put_device(dev);
	return err;
@@ -369,19 +351,18 @@ 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))
	if (sdev->handler &&
	    sdev->handler->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);
	err = sdev->handler->set_params(sdev, params);
	put_device(&sdev->sdev_gendev);
	return err;
}
@@ -413,8 +394,8 @@ int scsi_dh_attach(struct request_queue *q, const char *name)
	if (err)
		return err;

	if (sdev->scsi_dh_data) {
		if (sdev->scsi_dh_data->scsi_dh != scsi_dh)
	if (sdev->handler) {
		if (sdev->handler != scsi_dh)
			err = -EBUSY;
		goto out_put_device;
	}
@@ -451,8 +432,8 @@ const char *scsi_dh_attached_handler_name(struct request_queue *q, gfp_t gfp)
	if (!sdev)
		return NULL;

	if (sdev->scsi_dh_data)
		handler_name = kstrdup(sdev->scsi_dh_data->scsi_dh->name, gfp);
	if (sdev->handler)
		handler_name = kstrdup(sdev->handler->name, gfp);

	put_device(&sdev->sdev_gendev);
	return handler_name;
Loading