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 Original line Diff line number Diff line
@@ -62,7 +62,6 @@
#define ALUA_OPTIMIZE_STPG		1
#define ALUA_OPTIMIZE_STPG		1


struct alua_dh_data {
struct alua_dh_data {
	struct scsi_dh_data	dh_data;
	int			group_id;
	int			group_id;
	int			rel_port;
	int			rel_port;
	int			tpgs;
	int			tpgs;
@@ -86,11 +85,6 @@ struct alua_dh_data {
static char print_alua_state(int);
static char print_alua_state(int);
static int alua_check_sense(struct scsi_device *, struct scsi_sense_hdr *);
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)
static int realloc_buffer(struct alua_dh_data *h, unsigned len)
{
{
	if (h->buff && h->buff != h->inq)
	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)
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;
	unsigned int optimize = 0, argc;
	const char *p = params;
	const char *p = params;
	int result = SCSI_DH_OK;
	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,
static int alua_activate(struct scsi_device *sdev,
			activate_complete fn, void *data)
			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 err = SCSI_DH_OK;
	int stpg = 0;
	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)
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;
	int ret = BLKPREP_OK;


	if (h->state == TPGS_STATE_TRANSITIONING)
	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
 * alua_bus_attach - Attach device handler
 * @sdev: device to be attached to
 * @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;
	struct alua_dh_data *h;
	int err;
	int err;


	h = kzalloc(sizeof(*h) , GFP_KERNEL);
	h = kzalloc(sizeof(*h) , GFP_KERNEL);
	if (!h)
	if (!h)
		return ERR_PTR(-ENOMEM);
		return -ENOMEM;
	h->tpgs = TPGS_MODE_UNINITIALIZED;
	h->tpgs = TPGS_MODE_UNINITIALIZED;
	h->state = TPGS_STATE_OPTIMIZED;
	h->state = TPGS_STATE_OPTIMIZED;
	h->group_id = -1;
	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)
	if (err != SCSI_DH_OK && err != SCSI_DH_DEV_OFFLINED)
		goto failed;
		goto failed;


	sdev_printk(KERN_NOTICE, sdev, "%s: Attached\n", ALUA_DH_NAME);
	sdev->handler_data = h;
	return &h->dh_data;
	return 0;
failed:
failed:
	kfree(h);
	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)
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)
	if (h->buff && h->inq != h->buff)
		kfree(h->buff);
		kfree(h->buff);
	sdev->handler_data = NULL;
	kfree(h);
	kfree(h);
}
}


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


struct clariion_dh_data {
struct clariion_dh_data {
	struct scsi_dh_data dh_data;
	/*
	/*
	 * Flags:
	 * Flags:
	 *  CLARIION_SHORT_TRESPASS
	 *  CLARIION_SHORT_TRESPASS
@@ -114,13 +113,6 @@ struct clariion_dh_data {
	int current_sp;
	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.
 * 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)
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;
	int ret = BLKPREP_OK;


	if (h->lun_state != CLARIION_LUN_OWNED) {
	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,
static int clariion_activate(struct scsi_device *sdev,
				activate_complete fn, void *data)
				activate_complete fn, void *data)
{
{
	struct clariion_dh_data *csdev = get_clariion_data(sdev);
	struct clariion_dh_data *csdev = sdev->handler_data;
	int result;
	int result;


	result = clariion_send_inquiry(sdev, csdev);
	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)
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;
	unsigned int hr = 0, st = 0, argc;
	const char *p = params;
	const char *p = params;
	int result = SCSI_DH_OK;
	int result = SCSI_DH_OK;
@@ -622,14 +614,14 @@ static int clariion_set_params(struct scsi_device *sdev, const char *params)
	return result;
	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;
	struct clariion_dh_data *h;
	int err;
	int err;


	h = kzalloc(sizeof(*h) , GFP_KERNEL);
	h = kzalloc(sizeof(*h) , GFP_KERNEL);
	if (!h)
	if (!h)
		return ERR_PTR(-ENOMEM);
		return -ENOMEM;
	h->lun_state = CLARIION_LUN_UNINITIALIZED;
	h->lun_state = CLARIION_LUN_UNINITIALIZED;
	h->default_sp = CLARIION_UNBOUND_LU;
	h->default_sp = CLARIION_UNBOUND_LU;
	h->current_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',
		    CLARIION_NAME, h->current_sp + 'A',
		    h->port, lun_state[h->lun_state],
		    h->port, lun_state[h->lun_state],
		    h->default_sp + 'A');
		    h->default_sp + 'A');
	return &h->dh_data;

	sdev->handler_data = h;
	return 0;


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


static void clariion_bus_detach(struct scsi_device *sdev)
static void clariion_bus_detach(struct scsi_device *sdev)
{
{
	struct clariion_dh_data *h = get_clariion_data(sdev);
	kfree(sdev->handler_data);

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


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


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


static int hp_sw_start_stop(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
 * tur_done - Handle TEST UNIT READY return status
 * @sdev: sdev the command has been sent to
 * @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)
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;
	int ret = BLKPREP_OK;


	if (h->path_state != HP_SW_PATH_ACTIVE) {
	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)
				activate_complete fn, void *data)
{
{
	int ret = SCSI_DH_OK;
	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);
	ret = hp_sw_tur(sdev, h);


@@ -311,14 +305,14 @@ static int hp_sw_activate(struct scsi_device *sdev,
	return 0;
	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;
	struct hp_sw_dh_data *h;
	int ret;
	int ret;


	h = kzalloc(sizeof(*h), GFP_KERNEL);
	h = kzalloc(sizeof(*h), GFP_KERNEL);
	if (!h)
	if (!h)
		return ERR_PTR(-ENOMEM);
		return -ENOMEM;
	h->path_state = HP_SW_PATH_UNINITIALIZED;
	h->path_state = HP_SW_PATH_UNINITIALIZED;
	h->retries = HP_SW_RETRIES;
	h->retries = HP_SW_RETRIES;
	h->sdev = sdev;
	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",
	sdev_printk(KERN_INFO, sdev, "%s: attached to %s path\n",
		    HP_SW_NAME, h->path_state == HP_SW_PATH_ACTIVE?
		    HP_SW_NAME, h->path_state == HP_SW_PATH_ACTIVE?
		    "active":"passive");
		    "active":"passive");
	return &h->dh_data;

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


static void hp_sw_bus_detach( struct scsi_device *sdev )
static void hp_sw_bus_detach( struct scsi_device *sdev )
{
{
	struct hp_sw_dh_data *h = get_hp_sw_data(sdev);
	kfree(sdev->handler_data);

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


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


struct rdac_dh_data {
struct rdac_dh_data {
	struct scsi_dh_data	dh_data;
	struct rdac_controller	*ctlr;
	struct rdac_controller	*ctlr;
#define UNINITIALIZED_LUN	(1 << 8)
#define UNINITIALIZED_LUN	(1 << 8)
	unsigned		lun;
	unsigned		lun;
@@ -260,11 +259,6 @@ do { \
		sdev_printk(KERN_INFO, sdev, RDAC_NAME ": " f "\n", ## arg); \
		sdev_printk(KERN_INFO, sdev, RDAC_NAME ": " f "\n", ## arg); \
} while (0);
} 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,
static struct request *get_rdac_req(struct scsi_device *sdev,
			void *buffer, unsigned buflen, int rw)
			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;
	struct scsi_sense_hdr sense_hdr;
	int err = SCSI_DH_IO, ret;
	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);
	ret = scsi_normalize_sense(sensebuf, SCSI_SENSE_BUFFERSIZE, &sense_hdr);
	if (!ret)
	if (!ret)
@@ -589,7 +583,7 @@ static void send_mode_select(struct work_struct *work)
		container_of(work, struct rdac_controller, ms_work);
		container_of(work, struct rdac_controller, ms_work);
	struct request *rq;
	struct request *rq;
	struct scsi_device *sdev = ctlr->ms_sdev;
	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;
	struct request_queue *q = sdev->request_queue;
	int err, retry_cnt = RDAC_RETRY_COUNT;
	int err, retry_cnt = RDAC_RETRY_COUNT;
	struct rdac_queue_data *tmp, *qdata;
	struct rdac_queue_data *tmp, *qdata;
@@ -648,7 +642,7 @@ static int queue_mode_select(struct scsi_device *sdev,
	if (!qdata)
	if (!qdata)
		return SCSI_DH_RETRY;
		return SCSI_DH_RETRY;


	qdata->h = get_rdac_data(sdev);
	qdata->h = sdev->handler_data;
	qdata->callback_fn = fn;
	qdata->callback_fn = fn;
	qdata->callback_data = data;
	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,
static int rdac_activate(struct scsi_device *sdev,
			activate_complete fn, void *data)
			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 err = SCSI_DH_OK;
	int act = 0;
	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)
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;
	int ret = BLKPREP_OK;


	if (h->state != RDAC_STATE_ACTIVE) {
	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,
static int rdac_check_sense(struct scsi_device *sdev,
				struct scsi_sense_hdr *sense_hdr)
				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, "
	RDAC_LOG(RDAC_LOG_SENSE, sdev, "array %s, ctlr %d, "
			"I/O returned with sense %02x/%02x/%02x",
			"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;
	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;
	struct rdac_dh_data *h;
	int err;
	int err;
@@ -787,7 +781,7 @@ static struct scsi_dh_data *rdac_bus_attach(struct scsi_device *sdev)


	h = kzalloc(sizeof(*h) , GFP_KERNEL);
	h = kzalloc(sizeof(*h) , GFP_KERNEL);
	if (!h)
	if (!h)
		return ERR_PTR(-ENOMEM);
		return -ENOMEM;
	h->lun = UNINITIALIZED_LUN;
	h->lun = UNINITIALIZED_LUN;
	h->state = RDAC_STATE_ACTIVE;
	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],
		    RDAC_NAME, h->lun, mode[(int)h->mode],
		    lun_state[(int)h->lun_state]);
		    lun_state[(int)h->lun_state]);


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


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


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


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


+28 −47
Original line number Original line 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,
static int scsi_dh_handler_attach(struct scsi_device *sdev,
				  struct scsi_device_handler *scsi_dh)
				  struct scsi_device_handler *scsi_dh)
{
{
	struct scsi_dh_data *d;
	int error;


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


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

	d->scsi_dh = scsi_dh;
	d->sdev = sdev;


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


/*
/*
@@ -154,17 +148,9 @@ static int scsi_dh_handler_attach(struct scsi_device *sdev,
 */
 */
static void scsi_dh_handler_detach(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;
	sdev->handler->detach(sdev);
	struct scsi_device_handler *scsi_dh = scsi_dh_data->scsi_dh;
	sdev_printk(KERN_NOTICE, sdev, "%s: Detached\n", sdev->handler->name);

	module_put(sdev->handler->module);
	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);
}
}


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


	if (!sdev->scsi_dh_data) {
	if (!sdev->handler) {
		/*
		/*
		 * Attach to a device handler
		 * Attach to a device handler
		 */
		 */
@@ -191,7 +177,6 @@ store_dh_state(struct device *dev, struct device_attribute *attr,
			return err;
			return err;
		err = scsi_dh_handler_attach(sdev, scsi_dh);
		err = scsi_dh_handler_attach(sdev, scsi_dh);
	} else {
	} else {
		scsi_dh = sdev->scsi_dh_data->scsi_dh;
		if (!strncmp(buf, "detach", 6)) {
		if (!strncmp(buf, "detach", 6)) {
			/*
			/*
			 * Detach from a device handler
			 * Detach from a device handler
@@ -202,8 +187,8 @@ store_dh_state(struct device *dev, struct device_attribute *attr,
			/*
			/*
			 * Activate a device handler
			 * Activate a device handler
			 */
			 */
			if (scsi_dh->activate)
			if (sdev->handler->activate)
				err = scsi_dh->activate(sdev, NULL, NULL);
				err = sdev->handler->activate(sdev, NULL, NULL);
			else
			else
				err = 0;
				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);
	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, "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 =
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)
void scsi_dh_remove_device(struct scsi_device *sdev)
{
{
	if (sdev->scsi_dh_data)
	if (sdev->handler)
		scsi_dh_handler_detach(sdev);
		scsi_dh_handler_detach(sdev);
	device_remove_file(&sdev->sdev_gendev, &scsi_dh_state_attr);
	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;
	int err = 0;
	unsigned long flags;
	unsigned long flags;
	struct scsi_device *sdev;
	struct scsi_device *sdev;
	struct scsi_device_handler *scsi_dh = NULL;
	struct device *dev = NULL;
	struct device *dev = NULL;


	spin_lock_irqsave(q->queue_lock, flags);
	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;
		return err;
	}
	}


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


	if (scsi_dh->activate)
	if (sdev->handler->activate)
		err = scsi_dh->activate(sdev, fn, data);
		err = sdev->handler->activate(sdev, fn, data);
out:
out:
	put_device(dev);
	put_device(dev);
	return err;
	return err;
@@ -369,19 +351,18 @@ int scsi_dh_set_params(struct request_queue *q, const char *params)
	int err = -SCSI_DH_NOSYS;
	int err = -SCSI_DH_NOSYS;
	unsigned long flags;
	unsigned long flags;
	struct scsi_device *sdev;
	struct scsi_device *sdev;
	struct scsi_device_handler *scsi_dh = NULL;


	spin_lock_irqsave(q->queue_lock, flags);
	spin_lock_irqsave(q->queue_lock, flags);
	sdev = q->queuedata;
	sdev = q->queuedata;
	if (sdev && sdev->scsi_dh_data)
	if (sdev->handler &&
		scsi_dh = sdev->scsi_dh_data->scsi_dh;
	    sdev->handler->set_params &&
	if (scsi_dh && scsi_dh->set_params && get_device(&sdev->sdev_gendev))
	    get_device(&sdev->sdev_gendev))
		err = 0;
		err = 0;
	spin_unlock_irqrestore(q->queue_lock, flags);
	spin_unlock_irqrestore(q->queue_lock, flags);


	if (err)
	if (err)
		return err;
		return err;
	err = scsi_dh->set_params(sdev, params);
	err = sdev->handler->set_params(sdev, params);
	put_device(&sdev->sdev_gendev);
	put_device(&sdev->sdev_gendev);
	return err;
	return err;
}
}
@@ -413,8 +394,8 @@ int scsi_dh_attach(struct request_queue *q, const char *name)
	if (err)
	if (err)
		return err;
		return err;


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


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


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