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

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
...@@ -62,7 +62,6 @@ ...@@ -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 { ...@@ -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) ...@@ -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 ...@@ -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, ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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);
} }
......
...@@ -72,7 +72,6 @@ static const char * lun_state[] = ...@@ -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 { ...@@ -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, ...@@ -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, ...@@ -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, ...@@ -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) ...@@ -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) ...@@ -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 = {
......
...@@ -38,7 +38,6 @@ ...@@ -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 { ...@@ -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) ...@@ -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, ...@@ -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, ...@@ -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) ...@@ -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 = {
......
...@@ -181,7 +181,6 @@ struct c2_inquiry { ...@@ -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 { \ ...@@ -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, ...@@ -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) ...@@ -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, ...@@ -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, ...@@ -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, ...@@ -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) ...@@ -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, ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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 ) ...@@ -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);
} }
......
...@@ -126,26 +126,20 @@ static struct scsi_device_handler *scsi_dh_lookup(const char *name) ...@@ -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, ...@@ -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, ...@@ -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, ...@@ -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, ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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;
......
...@@ -37,6 +37,7 @@ ...@@ -37,6 +37,7 @@
#include <scsi/scsi_transport.h> #include <scsi/scsi_transport.h>
#include <scsi/scsi_host.h> #include <scsi/scsi_host.h>
#include <scsi/scsi_ioctl.h> #include <scsi/scsi_ioctl.h>
#include <scsi/scsi_dh.h>
#include <scsi/sg.h> #include <scsi/sg.h>
#include "scsi_priv.h" #include "scsi_priv.h"
...@@ -464,11 +465,10 @@ static int scsi_check_sense(struct scsi_cmnd *scmd) ...@@ -464,11 +465,10 @@ static int scsi_check_sense(struct scsi_cmnd *scmd)
if (scsi_sense_is_deferred(&sshdr)) if (scsi_sense_is_deferred(&sshdr))
return NEEDS_RETRY; return NEEDS_RETRY;
if (sdev->scsi_dh_data && sdev->scsi_dh_data->scsi_dh && if (sdev->handler && sdev->handler->check_sense) {
sdev->scsi_dh_data->scsi_dh->check_sense) {
int rc; int rc;
rc = sdev->scsi_dh_data->scsi_dh->check_sense(sdev, &sshdr); rc = sdev->handler->check_sense(sdev, &sshdr);
if (rc != SCSI_RETURN_NOT_HANDLED) if (rc != SCSI_RETURN_NOT_HANDLED)
return rc; return rc;
/* handler does not care. Drop down to default handling */ /* handler does not care. Drop down to default handling */
......
...@@ -31,6 +31,7 @@ ...@@ -31,6 +31,7 @@
#include <scsi/scsi_driver.h> #include <scsi/scsi_driver.h>
#include <scsi/scsi_eh.h> #include <scsi/scsi_eh.h>
#include <scsi/scsi_host.h> #include <scsi/scsi_host.h>
#include <scsi/scsi_dh.h>
#include <trace/events/scsi.h> #include <trace/events/scsi.h>
...@@ -1248,9 +1249,8 @@ static int scsi_setup_fs_cmnd(struct scsi_device *sdev, struct request *req) ...@@ -1248,9 +1249,8 @@ static int scsi_setup_fs_cmnd(struct scsi_device *sdev, struct request *req)
{ {
struct scsi_cmnd *cmd = req->special; struct scsi_cmnd *cmd = req->special;
if (unlikely(sdev->scsi_dh_data && sdev->scsi_dh_data->scsi_dh if (unlikely(sdev->handler && sdev->handler->prep_fn)) {
&& sdev->scsi_dh_data->scsi_dh->prep_fn)) { int ret = sdev->handler->prep_fn(sdev, req);
int ret = sdev->scsi_dh_data->scsi_dh->prep_fn(sdev, req);
if (ret != BLKPREP_OK) if (ret != BLKPREP_OK)
return ret; return ret;
} }
......
...@@ -196,32 +196,13 @@ struct scsi_device { ...@@ -196,32 +196,13 @@ struct scsi_device {
struct execute_work ew; /* used to get process context on put */ struct execute_work ew; /* used to get process context on put */
struct work_struct requeue_work; struct work_struct requeue_work;
struct scsi_dh_data *scsi_dh_data; struct scsi_device_handler *handler;
void *handler_data;
enum scsi_device_state sdev_state; enum scsi_device_state sdev_state;
unsigned long sdev_data[0]; unsigned long sdev_data[0];
} __attribute__((aligned(sizeof(unsigned long)))); } __attribute__((aligned(sizeof(unsigned long))));
typedef void (*activate_complete)(void *, int);
struct scsi_device_handler {
/* Used by the infrastructure */
struct list_head list; /* list of scsi_device_handlers */
/* Filled by the hardware handler */
struct module *module;
const char *name;
int (*check_sense)(struct scsi_device *, struct scsi_sense_hdr *);
struct scsi_dh_data *(*attach)(struct scsi_device *);
void (*detach)(struct scsi_device *);
int (*activate)(struct scsi_device *, activate_complete, void *);
int (*prep_fn)(struct scsi_device *, struct request *);
int (*set_params)(struct scsi_device *, const char *);
};
struct scsi_dh_data {
struct scsi_device_handler *scsi_dh;
struct scsi_device *sdev;
};
#define to_scsi_device(d) \ #define to_scsi_device(d) \
container_of(d, struct scsi_device, sdev_gendev) container_of(d, struct scsi_device, sdev_gendev)
#define class_to_sdev(d) \ #define class_to_sdev(d) \
......
...@@ -55,6 +55,23 @@ enum { ...@@ -55,6 +55,23 @@ enum {
SCSI_DH_NOSYS, SCSI_DH_NOSYS,
SCSI_DH_DRIVER_MAX, SCSI_DH_DRIVER_MAX,
}; };
typedef void (*activate_complete)(void *, int);
struct scsi_device_handler {
/* Used by the infrastructure */
struct list_head list; /* list of scsi_device_handlers */
/* Filled by the hardware handler */
struct module *module;
const char *name;
int (*check_sense)(struct scsi_device *, struct scsi_sense_hdr *);
int (*attach)(struct scsi_device *);
void (*detach)(struct scsi_device *);
int (*activate)(struct scsi_device *, activate_complete, void *);
int (*prep_fn)(struct scsi_device *, struct request *);
int (*set_params)(struct scsi_device *, const char *);
};
#ifdef CONFIG_SCSI_DH #ifdef CONFIG_SCSI_DH
extern int scsi_dh_activate(struct request_queue *, activate_complete, void *); extern int scsi_dh_activate(struct request_queue *, activate_complete, void *);
extern int scsi_dh_attach(struct request_queue *, const char *); extern int scsi_dh_attach(struct request_queue *, const char *);
......
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