FAQ Search Today's Posts Mark Forums Read
» Video Reviews

» Linux Archive

Linux-archive is a website aiming to archive linux email lists and to make them easily accessible for linux users/developers.


» Sponsor

» Partners

» Sponsor

Go Back   Linux Archive > Redhat > Device-mapper Development

 
 
LinkBack Thread Tools
 
Old 05-15-2008, 02:50 AM
Chandra Seetharaman
 
Default scsi_dh: Update RDAC device handler

On Wed, 2008-05-14 at 16:43 +0200, Hannes Reinecke wrote:
> This patch updates the RDAC device handler to
> refuse to attach to devices not supporting the
> RDAC vpd pages.
>
> Signed-off-by: Hannes Reinecke <hare@suse.de>
> ---
> drivers/scsi/device_handler/scsi_dh_rdac.c | 84 +++++++++++++++++----------
> 1 files changed, 53 insertions(+), 31 deletions(-)
>
> diff --git a/drivers/scsi/device_handler/scsi_dh_rdac.c b/drivers/scsi/device_handler/scsi_dh_rdac.c
> index e61cde6..dd9f515 100644
> --- a/drivers/scsi/device_handler/scsi_dh_rdac.c
> +++ b/drivers/scsi/device_handler/scsi_dh_rdac.c
> @@ -173,6 +173,11 @@ struct rdac_dh_data {
> #define RDAC_STATE_ACTIVE 0
> #define RDAC_STATE_PASSIVE 1
> unsigned char state;
> +
> +#define RDAC_LUN_UNOWNED 0
> +#define RDAC_LUN_OWNED 1
> +#define RDAC_LUN_AVT 2
> + char lun_state;
> unsigned char sense[SCSI_SENSE_BUFFERSIZE];
> union {
> struct c2_inquiry c2;
> @@ -214,7 +219,7 @@ static struct request *get_rdac_req(struct scsi_device *sdev,
> return NULL;
> }
>
> - memset(&rq->cmd, 0, BLK_MAX_CDB);
> + memset(rq->cmd, 0, BLK_MAX_CDB);
> rq->sense = h->sense;
> memset(rq->sense, 0, SCSI_SENSE_BUFFERSIZE);
> rq->sense_len = 0;
> @@ -354,14 +359,16 @@ static int get_lun(struct scsi_device *sdev)
> err = submit_inquiry(sdev, 0xC8, sizeof(struct c8_inquiry));
> if (err == SCSI_DH_OK) {
> inqp = &h->inq.c8;
> - h->lun = inqp->lun[7]; /* currently it uses only one byte */
> + if (inqp->page_code != 0xc8)
> + return SCSI_DH_NOSYS;
> + if (inqp->page_id[0] != 'e' || inqp->page_id[1] != 'd' ||
> + inqp->page_id[2] != 'i' || inqp->page_id[3] != 'd')
> + return SCSI_DH_NOSYS;
> + h->lun = scsilun_to_int((struct scsi_lun *)inqp->lun);
> }
> return err;
> }
>
> -#define RDAC_OWNED 0
> -#define RDAC_UNOWNED 1
> -#define RDAC_FAILED 2
> static int check_ownership(struct scsi_device *sdev)
> {
> int err;
> @@ -370,17 +377,23 @@ static int check_ownership(struct scsi_device *sdev)
>
> err = submit_inquiry(sdev, 0xC9, sizeof(struct c9_inquiry));
> if (err == SCSI_DH_OK) {
> - err = RDAC_UNOWNED;
> inqp = &h->inq.c9;
> /*
> * If in AVT mode or if the path already owns the LUN,
> * return RDAC_OWNED;
> */

With the code change below the comment above is incorrect, please
remove.
> - if (((inqp->avte_cvp >> 7) == 0x1) ||
> - ((inqp->avte_cvp & 0x1) != 0))
> - err = RDAC_OWNED;
> - } else
> - err = RDAC_FAILED;
> + if ((inqp->avte_cvp >> 7) == 0x1) {
> + /* LUN in AVT mode */
> + sdev_printk(KERN_NOTICE, sdev,
> + "%s: AVT mode detected
",
> + RDAC_NAME);
> + h->lun_state = RDAC_LUN_AVT;
> + } else if ((inqp->avte_cvp & 0x1) != 0) {
> + /* LUN was owned by the controller */
> + h->lun_state = RDAC_LUN_OWNED;
> + }
> + }
> +
> return err;
> }
>
> @@ -478,24 +491,9 @@ static int rdac_activate(struct scsi_device *sdev)
> struct rdac_dh_data *h = get_rdac_data(sdev);
> int err = SCSI_DH_OK;
>
> - if (h->lun == UNINITIALIZED_LUN) {
> - err = get_lun(sdev);
> - if (err != SCSI_DH_OK)
> - goto done;
> - }
> -
> err = check_ownership(sdev);
> - switch (err) {
> - case RDAC_UNOWNED:
> - break;
> - case RDAC_OWNED:
> - err = SCSI_DH_OK;
> - goto done;
> - case RDAC_FAILED:
> - default:
> - err = SCSI_DH_IO;

What does this change yield ? (under check_ownership)

> + if (err != SCSI_DH_OK)
> goto done;
> - }
>
> if (!h->ctlr) {
> err = initialize_controller(sdev);
> @@ -508,8 +506,9 @@ static int rdac_activate(struct scsi_device *sdev)
> if (err != SCSI_DH_OK)
> goto done;
> }
> -
> - err = send_mode_select(sdev);
> + if (h->lun_state != RDAC_LUN_AVT &&
> + !(h->lun_state & RDAC_LUN_OWNED))

This can be simplified by (h->lun_state == RDAC_LUN_UNOWNED) ?
> + err = send_mode_select(sdev);
> done:
> return err;
> }
> @@ -606,6 +605,7 @@ static int rdac_bus_attach(struct scsi_device *sdev)
> struct scsi_dh_data *scsi_dh_data;
> struct rdac_dh_data *h;
> unsigned long flags;
> + int err;
>
> scsi_dh_data = kzalloc(sizeof(struct scsi_device_handler *)
> + sizeof(*h) , GFP_KERNEL);
> @@ -622,11 +622,33 @@ static int rdac_bus_attach(struct scsi_device *sdev)
> spin_lock_irqsave(sdev->request_queue->queue_lock, flags);
> sdev->scsi_dh_data = scsi_dh_data;
> spin_unlock_irqrestore(sdev->request_queue->queue_lock, flags);

need an initialization for lun_state.

> +
> + err = get_lun(sdev);
> + if (err != SCSI_DH_OK)
> + goto failed;
> +
> + err = check_ownership(sdev);
> + if (err != SCSI_DH_OK)
> + goto failed;
> +
> + sdev_printk(KERN_NOTICE, sdev,
> + "%s: LUN %d (state %d)
",
> + RDAC_NAME, h->lun, h->lun_state);

instead of printing lun_state as %d it would be more readable it is a
string.

> +
> try_module_get(THIS_MODULE);
>
> - sdev_printk(KERN_NOTICE, sdev, "Attached %s
", RDAC_NAME);
> + sdev_printk(KERN_NOTICE, sdev, "%s: Attached
", RDAC_NAME);
>
> return 0;
> +
> +failed:
> + spin_lock_irqsave(sdev->request_queue->queue_lock, flags);
> + sdev->scsi_dh_data = NULL;
> + spin_unlock_irqrestore(sdev->request_queue->queue_lock, flags);
> + kfree(scsi_dh_data);
> + sdev_printk(KERN_ERR, sdev, "%s: not attached
",
> + RDAC_NAME);
> + return -EINVAL;
> }
>
> static void rdac_bus_detach( struct scsi_device *sdev )
> @@ -645,7 +667,7 @@ static void rdac_bus_detach( struct scsi_device *sdev )
> kref_put(&h->ctlr->kref, release_controller);
> kfree(scsi_dh_data);
> module_put(THIS_MODULE);
> - sdev_printk(KERN_NOTICE, sdev, "Detached %s
", RDAC_NAME);
> + sdev_printk(KERN_NOTICE, sdev, "%s: Detached
", RDAC_NAME);
> }
>
> static int __init rdac_init(void)

--
dm-devel mailing list
dm-devel@redhat.com
https://www.redhat.com/mailman/listinfo/dm-devel
 
Old 05-15-2008, 09:02 AM
Hannes Reinecke
 
Default scsi_dh: Update RDAC device handler

Hi Chandra,

Chandra Seetharaman wrote:

On Wed, 2008-05-14 at 16:43 +0200, Hannes Reinecke wrote:

This patch updates the RDAC device handler to
refuse to attach to devices not supporting the
RDAC vpd pages.

Signed-off-by: Hannes Reinecke <hare@suse.de>
---
drivers/scsi/device_handler/scsi_dh_rdac.c | 84 +++++++++++++++++----------
1 files changed, 53 insertions(+), 31 deletions(-)

diff --git a/drivers/scsi/device_handler/scsi_dh_rdac.c b/drivers/scsi/device_handler/scsi_dh_rdac.c
index e61cde6..dd9f515 100644
--- a/drivers/scsi/device_handler/scsi_dh_rdac.c
+++ b/drivers/scsi/device_handler/scsi_dh_rdac.c

[ .. ]

/*
* If in AVT mode or if the path already owns the LUN,
* return RDAC_OWNED;
*/


With the code change below the comment above is incorrect, please
remove.

OK.


@@ -478,24 +491,9 @@ static int rdac_activate(struct scsi_device *sdev)
struct rdac_dh_data *h = get_rdac_data(sdev);
int err = SCSI_DH_OK;

- if (h->lun == UNINITIALIZED_LUN) {
- err = get_lun(sdev);
- if (err != SCSI_DH_OK)
- goto done;
- }
-
err = check_ownership(sdev);
- switch (err) {
- case RDAC_UNOWNED:
- break;
- case RDAC_OWNED:
- err = SCSI_DH_OK;
- goto done;
- case RDAC_FAILED:
- default:
- err = SCSI_DH_IO;


What does this change yield ? (under check_ownership)


We're now setting the lun state explicitly, so there's
no need to return different error codes.


+ if (err != SCSI_DH_OK)
goto done;
- }

if (!h->ctlr) {
err = initialize_controller(sdev);
@@ -508,8 +506,9 @@ static int rdac_activate(struct scsi_device *sdev)
if (err != SCSI_DH_OK)
goto done;
}
-
- err = send_mode_select(sdev);
+ if (h->lun_state != RDAC_LUN_AVT &&
+ !(h->lun_state & RDAC_LUN_OWNED))


This can be simplified by (h->lun_state == RDAC_LUN_UNOWNED) ?


Indeed,


+ err = send_mode_select(sdev);
done:
return err;
}
@@ -606,6 +605,7 @@ static int rdac_bus_attach(struct scsi_device *sdev)
struct scsi_dh_data *scsi_dh_data;
struct rdac_dh_data *h;
unsigned long flags;
+ int err;

scsi_dh_data = kzalloc(sizeof(struct scsi_device_handler *)
+ sizeof(*h) , GFP_KERNEL);
@@ -622,11 +622,33 @@ static int rdac_bus_attach(struct scsi_device *sdev)
spin_lock_irqsave(sdev->request_queue->queue_lock, flags);
sdev->scsi_dh_data = scsi_dh_data;
spin_unlock_irqrestore(sdev->request_queue->queue_lock, flags);


need an initialization for lun_state.


No. lun_state is initialized to '0', ie RDAC_LUN_UNOWNED.
I don't think we need a separate 'uninitialized' state here.


+
+ err = get_lun(sdev);
+ if (err != SCSI_DH_OK)
+ goto failed;
+
+ err = check_ownership(sdev);
+ if (err != SCSI_DH_OK)
+ goto failed;
+
+ sdev_printk(KERN_NOTICE, sdev,
+ "%s: LUN %d (state %d)
",
+ RDAC_NAME, h->lun, h->lun_state);


instead of printing lun_state as %d it would be more readable it is a
string.


Ok.

Cheers,

Hannes
--
Dr. Hannes Reinecke zSeries & Storage
hare@suse.de +49 911 74053 688
SUSE LINUX Products GmbH, Maxfeldstr. 5, 90409 Nürnberg
GF: Markus Rex, HRB 16746 (AG Nürnberg)

--
dm-devel mailing list
dm-devel@redhat.com
https://www.redhat.com/mailman/listinfo/dm-devel
 
Old 05-16-2008, 06:40 PM
Chandra Seetharaman
 
Default scsi_dh: Update RDAC device handler

On Thu, 2008-05-15 at 11:02 +0200, Hannes Reinecke wrote:
<snip>

> >> @@ -478,24 +491,9 @@ static int rdac_activate(struct scsi_device *sdev)
> >> struct rdac_dh_data *h = get_rdac_data(sdev);
> >> int err = SCSI_DH_OK;
> >>
> >> - if (h->lun == UNINITIALIZED_LUN) {
> >> - err = get_lun(sdev);
> >> - if (err != SCSI_DH_OK)
> >> - goto done;
> >> - }
> >> -
> >> err = check_ownership(sdev);
> >> - switch (err) {
> >> - case RDAC_UNOWNED:
> >> - break;
> >> - case RDAC_OWNED:
> >> - err = SCSI_DH_OK;
> >> - goto done;
> >> - case RDAC_FAILED:
> >> - default:
> >> - err = SCSI_DH_IO;
> >
> > What does this change yield ? (under check_ownership)
> >
> We're now setting the lun state explicitly, so there's
> no need to return different error codes.

That is my question. what did we gain by the addition of lun_state ?


--
dm-devel mailing list
dm-devel@redhat.com
https://www.redhat.com/mailman/listinfo/dm-devel
 
Old 05-20-2008, 02:05 PM
 
Default scsi_dh: Update RDAC device handler

This patch updates the RDAC device handler to
refuse to attach to devices not supporting the
RDAC vpd pages.

Signed-off-by: Hannes Reinecke <hare@suse.de>
---
drivers/scsi/device_handler/scsi_dh_rdac.c | 158 ++++++++++++++++------------
1 files changed, 91 insertions(+), 67 deletions(-)

diff --git a/drivers/scsi/device_handler/scsi_dh_rdac.c b/drivers/scsi/device_handler/scsi_dh_rdac.c
index e61cde6..e11e522 100644
--- a/drivers/scsi/device_handler/scsi_dh_rdac.c
+++ b/drivers/scsi/device_handler/scsi_dh_rdac.c
@@ -173,6 +173,11 @@ struct rdac_dh_data {
#define RDAC_STATE_ACTIVE 0
#define RDAC_STATE_PASSIVE 1
unsigned char state;
+
+#define RDAC_LUN_UNOWNED 0
+#define RDAC_LUN_OWNED 1
+#define RDAC_LUN_AVT 2
+ char lun_state;
unsigned char sense[SCSI_SENSE_BUFFERSIZE];
union {
struct c2_inquiry c2;
@@ -182,6 +187,13 @@ struct rdac_dh_data {
} inq;
};

+static const char *lun_state[] =
+{
+ "unowned",
+ "owned",
+ "owned (AVT mode)",
+};
+
static LIST_HEAD(ctlr_list);
static DEFINE_SPINLOCK(list_lock);

@@ -197,7 +209,6 @@ static struct request *get_rdac_req(struct scsi_device *sdev,
{
struct request *rq;
struct request_queue *q = sdev->request_queue;
- struct rdac_dh_data *h = get_rdac_data(sdev);

rq = blk_get_request(q, rw, GFP_KERNEL);

@@ -214,10 +225,7 @@ static struct request *get_rdac_req(struct scsi_device *sdev,
return NULL;
}

- memset(&rq->cmd, 0, BLK_MAX_CDB);
- rq->sense = h->sense;
- memset(rq->sense, 0, SCSI_SENSE_BUFFERSIZE);
- rq->sense_len = 0;
+ memset(rq->cmd, 0, BLK_MAX_CDB);

rq->cmd_type = REQ_TYPE_BLOCK_PC;
rq->cmd_flags |= REQ_FAILFAST | REQ_NOMERGE;
@@ -227,12 +235,12 @@ static struct request *get_rdac_req(struct scsi_device *sdev,
return rq;
}

-static struct request *rdac_failover_get(struct scsi_device *sdev)
+static struct request *rdac_failover_get(struct scsi_device *sdev,
+ struct rdac_dh_data *h)
{
struct request *rq;
struct rdac_mode_common *common;
unsigned data_size;
- struct rdac_dh_data *h = get_rdac_data(sdev);

if (h->ctlr->use_ms10) {
struct rdac_pg_expanded *rdac_pg;
@@ -277,6 +285,10 @@ static struct request *rdac_failover_get(struct scsi_device *sdev)
}
rq->cmd_len = COMMAND_SIZE(rq->cmd[0]);

+ rq->sense = h->sense;
+ memset(rq->sense, 0, SCSI_SENSE_BUFFERSIZE);
+ rq->sense_len = 0;
+
return rq;
}

@@ -321,11 +333,10 @@ done:
}

static int submit_inquiry(struct scsi_device *sdev, int page_code,
- unsigned int len)
+ unsigned int len, struct rdac_dh_data *h)
{
struct request *rq;
struct request_queue *q = sdev->request_queue;
- struct rdac_dh_data *h = get_rdac_data(sdev);
int err = SCSI_DH_RES_TEMP_UNAVAIL;

rq = get_rdac_req(sdev, &h->inq, len, READ);
@@ -338,59 +349,68 @@ static int submit_inquiry(struct scsi_device *sdev, int page_code,
rq->cmd[2] = page_code;
rq->cmd[4] = len;
rq->cmd_len = COMMAND_SIZE(INQUIRY);
+
+ rq->sense = h->sense;
+ memset(rq->sense, 0, SCSI_SENSE_BUFFERSIZE);
+ rq->sense_len = 0;
+
err = blk_execute_rq(q, NULL, rq, 1);
if (err == -EIO)
err = SCSI_DH_IO;
+
+ blk_put_request(rq);
done:
return err;
}

-static int get_lun(struct scsi_device *sdev)
+static int get_lun(struct scsi_device *sdev, struct rdac_dh_data *h)
{
int err;
struct c8_inquiry *inqp;
- struct rdac_dh_data *h = get_rdac_data(sdev);

- err = submit_inquiry(sdev, 0xC8, sizeof(struct c8_inquiry));
+ err = submit_inquiry(sdev, 0xC8, sizeof(struct c8_inquiry), h);
if (err == SCSI_DH_OK) {
inqp = &h->inq.c8;
- h->lun = inqp->lun[7]; /* currently it uses only one byte */
+ if (inqp->page_code != 0xc8)
+ return SCSI_DH_NOSYS;
+ if (inqp->page_id[0] != 'e' || inqp->page_id[1] != 'd' ||
+ inqp->page_id[2] != 'i' || inqp->page_id[3] != 'd')
+ return SCSI_DH_NOSYS;
+ h->lun = scsilun_to_int((struct scsi_lun *)inqp->lun);
}
return err;
}

-#define RDAC_OWNED 0
-#define RDAC_UNOWNED 1
-#define RDAC_FAILED 2
-static int check_ownership(struct scsi_device *sdev)
+static int check_ownership(struct scsi_device *sdev, struct rdac_dh_data *h)
{
int err;
struct c9_inquiry *inqp;
- struct rdac_dh_data *h = get_rdac_data(sdev);

- err = submit_inquiry(sdev, 0xC9, sizeof(struct c9_inquiry));
+ err = submit_inquiry(sdev, 0xC9, sizeof(struct c9_inquiry), h);
if (err == SCSI_DH_OK) {
- err = RDAC_UNOWNED;
inqp = &h->inq.c9;
- /*
- * If in AVT mode or if the path already owns the LUN,
- * return RDAC_OWNED;
- */
- if (((inqp->avte_cvp >> 7) == 0x1) ||
- ((inqp->avte_cvp & 0x1) != 0))
- err = RDAC_OWNED;
- } else
- err = RDAC_FAILED;
+ if ((inqp->avte_cvp >> 7) == 0x1) {
+ /* LUN in AVT mode */
+ sdev_printk(KERN_NOTICE, sdev,
+ "%s: AVT mode detected
",
+ RDAC_NAME);
+ h->lun_state = RDAC_LUN_AVT;
+ } else if ((inqp->avte_cvp & 0x1) != 0) {
+ /* LUN was owned by the controller */
+ h->lun_state = RDAC_LUN_OWNED;
+ }
+ }
+
return err;
}

-static int initialize_controller(struct scsi_device *sdev)
+static int initialize_controller(struct scsi_device *sdev,
+ struct rdac_dh_data *h)
{
int err;
struct c4_inquiry *inqp;
- struct rdac_dh_data *h = get_rdac_data(sdev);

- err = submit_inquiry(sdev, 0xC4, sizeof(struct c4_inquiry));
+ err = submit_inquiry(sdev, 0xC4, sizeof(struct c4_inquiry), h);
if (err == SCSI_DH_OK) {
inqp = &h->inq.c4;
h->ctlr = get_controller(inqp->subsys_id, inqp->slot_id);
@@ -400,13 +420,12 @@ static int initialize_controller(struct scsi_device *sdev)
return err;
}

-static int set_mode_select(struct scsi_device *sdev)
+static int set_mode_select(struct scsi_device *sdev, struct rdac_dh_data *h)
{
int err;
struct c2_inquiry *inqp;
- struct rdac_dh_data *h = get_rdac_data(sdev);

- err = submit_inquiry(sdev, 0xC2, sizeof(struct c2_inquiry));
+ err = submit_inquiry(sdev, 0xC2, sizeof(struct c2_inquiry), h);
if (err == SCSI_DH_OK) {
inqp = &h->inq.c2;
/*
@@ -421,13 +440,13 @@ static int set_mode_select(struct scsi_device *sdev)
return err;
}

-static int mode_select_handle_sense(struct scsi_device *sdev)
+static int mode_select_handle_sense(struct scsi_device *sdev,
+ unsigned char *sensebuf)
{
struct scsi_sense_hdr sense_hdr;
- struct rdac_dh_data *h = get_rdac_data(sdev);
int sense, err = SCSI_DH_IO, ret;

- ret = scsi_normalize_sense(h->sense, SCSI_SENSE_BUFFERSIZE, &sense_hdr);
+ ret = scsi_normalize_sense(sensebuf, SCSI_SENSE_BUFFERSIZE, &sense_hdr);
if (!ret)
goto done;

@@ -451,14 +470,13 @@ done:
return err;
}

-static int send_mode_select(struct scsi_device *sdev)
+static int send_mode_select(struct scsi_device *sdev, struct rdac_dh_data *h)
{
struct request *rq;
struct request_queue *q = sdev->request_queue;
- struct rdac_dh_data *h = get_rdac_data(sdev);
int err = SCSI_DH_RES_TEMP_UNAVAIL;

- rq = rdac_failover_get(sdev);
+ rq = rdac_failover_get(sdev, h);
if (!rq)
goto done;

@@ -466,9 +484,11 @@ static int send_mode_select(struct scsi_device *sdev)

err = blk_execute_rq(q, NULL, rq, 1);
if (err != SCSI_DH_OK)
- err = mode_select_handle_sense(sdev);
+ err = mode_select_handle_sense(sdev, h->sense);
if (err == SCSI_DH_OK)
h->state = RDAC_STATE_ACTIVE;
+
+ blk_put_request(rq);
done:
return err;
}
@@ -478,38 +498,23 @@ static int rdac_activate(struct scsi_device *sdev)
struct rdac_dh_data *h = get_rdac_data(sdev);
int err = SCSI_DH_OK;

- if (h->lun == UNINITIALIZED_LUN) {
- err = get_lun(sdev);
- if (err != SCSI_DH_OK)
- goto done;
- }
-
- err = check_ownership(sdev);
- switch (err) {
- case RDAC_UNOWNED:
- break;
- case RDAC_OWNED:
- err = SCSI_DH_OK;
- goto done;
- case RDAC_FAILED:
- default:
- err = SCSI_DH_IO;
+ err = check_ownership(sdev, h);
+ if (err != SCSI_DH_OK)
goto done;
- }

if (!h->ctlr) {
- err = initialize_controller(sdev);
+ err = initialize_controller(sdev, h);
if (err != SCSI_DH_OK)
goto done;
}

if (h->ctlr->use_ms10 == -1) {
- err = set_mode_select(sdev);
+ err = set_mode_select(sdev, h);
if (err != SCSI_DH_OK)
goto done;
}
-
- err = send_mode_select(sdev);
+ if (h->lun_state == RDAC_LUN_UNOWNED)
+ err = send_mode_select(sdev, h);
done:
return err;
}
@@ -606,11 +611,12 @@ static int rdac_bus_attach(struct scsi_device *sdev)
struct scsi_dh_data *scsi_dh_data;
struct rdac_dh_data *h;
unsigned long flags;
+ int err;

scsi_dh_data = kzalloc(sizeof(struct scsi_device_handler *)
+ sizeof(*h) , GFP_KERNEL);
if (!scsi_dh_data) {
- sdev_printk(KERN_ERR, sdev, "Attach failed %s.
",
+ sdev_printk(KERN_ERR, sdev, "%s: Attach failed
",
RDAC_NAME);
return 0;
}
@@ -619,14 +625,32 @@ static int rdac_bus_attach(struct scsi_device *sdev)
h = (struct rdac_dh_data *) scsi_dh_data->buf;
h->lun = UNINITIALIZED_LUN;
h->state = RDAC_STATE_ACTIVE;
+
+ err = get_lun(sdev, h);
+ if (err != SCSI_DH_OK)
+ goto failed;
+
+ err = check_ownership(sdev, h);
+ if (err != SCSI_DH_OK)
+ goto failed;
+
spin_lock_irqsave(sdev->request_queue->queue_lock, flags);
sdev->scsi_dh_data = scsi_dh_data;
spin_unlock_irqrestore(sdev->request_queue->queue_lock, flags);
- try_module_get(THIS_MODULE);

- sdev_printk(KERN_NOTICE, sdev, "Attached %s
", RDAC_NAME);
+ sdev_printk(KERN_NOTICE, sdev,
+ "%s: LUN %d (%s)
",
+ RDAC_NAME, h->lun, lun_state[(int)h->lun_state]);
+
+ try_module_get(THIS_MODULE);

return 0;
+
+failed:
+ kfree(scsi_dh_data);
+ sdev_printk(KERN_ERR, sdev, "%s: not attached
",
+ RDAC_NAME);
+ return -EINVAL;
}

static void rdac_bus_detach( struct scsi_device *sdev )
@@ -645,7 +669,7 @@ static void rdac_bus_detach( struct scsi_device *sdev )
kref_put(&h->ctlr->kref, release_controller);
kfree(scsi_dh_data);
module_put(THIS_MODULE);
- sdev_printk(KERN_NOTICE, sdev, "Detached %s
", RDAC_NAME);
+ sdev_printk(KERN_NOTICE, sdev, "%s: Detached
", RDAC_NAME);
}

static int __init rdac_init(void)
--
1.5.2.4

--
dm-devel mailing list
dm-devel@redhat.com
https://www.redhat.com/mailman/listinfo/dm-devel
 
Old 05-23-2008, 02:08 AM
Chandra Seetharaman
 
Default scsi_dh: Update RDAC device handler

Looks good to me.

On Tue, 2008-05-20 at 16:05 +0200, Hannes Reinecke wrote:
> This patch updates the RDAC device handler to
> refuse to attach to devices not supporting the
> RDAC vpd pages.
>
> Signed-off-by: Hannes Reinecke <hare@suse.de>
> ---
> drivers/scsi/device_handler/scsi_dh_rdac.c | 158 ++++++++++++++++------------
> 1 files changed, 91 insertions(+), 67 deletions(-)
>
> diff --git a/drivers/scsi/device_handler/scsi_dh_rdac.c b/drivers/scsi/device_handler/scsi_dh_rdac.c
> index e61cde6..e11e522 100644
> --- a/drivers/scsi/device_handler/scsi_dh_rdac.c
> +++ b/drivers/scsi/device_handler/scsi_dh_rdac.c
> @@ -173,6 +173,11 @@ struct rdac_dh_data {
> #define RDAC_STATE_ACTIVE 0
> #define RDAC_STATE_PASSIVE 1
> unsigned char state;
> +
> +#define RDAC_LUN_UNOWNED 0
> +#define RDAC_LUN_OWNED 1
> +#define RDAC_LUN_AVT 2
> + char lun_state;
> unsigned char sense[SCSI_SENSE_BUFFERSIZE];
> union {
> struct c2_inquiry c2;
> @@ -182,6 +187,13 @@ struct rdac_dh_data {
> } inq;
> };
>
> +static const char *lun_state[] =
> +{
> + "unowned",
> + "owned",
> + "owned (AVT mode)",
> +};
> +
> static LIST_HEAD(ctlr_list);
> static DEFINE_SPINLOCK(list_lock);
>
> @@ -197,7 +209,6 @@ static struct request *get_rdac_req(struct scsi_device *sdev,
> {
> struct request *rq;
> struct request_queue *q = sdev->request_queue;
> - struct rdac_dh_data *h = get_rdac_data(sdev);
>
> rq = blk_get_request(q, rw, GFP_KERNEL);
>
> @@ -214,10 +225,7 @@ static struct request *get_rdac_req(struct scsi_device *sdev,
> return NULL;
> }
>
> - memset(&rq->cmd, 0, BLK_MAX_CDB);
> - rq->sense = h->sense;
> - memset(rq->sense, 0, SCSI_SENSE_BUFFERSIZE);
> - rq->sense_len = 0;
> + memset(rq->cmd, 0, BLK_MAX_CDB);
>
> rq->cmd_type = REQ_TYPE_BLOCK_PC;
> rq->cmd_flags |= REQ_FAILFAST | REQ_NOMERGE;
> @@ -227,12 +235,12 @@ static struct request *get_rdac_req(struct scsi_device *sdev,
> return rq;
> }
>
> -static struct request *rdac_failover_get(struct scsi_device *sdev)
> +static struct request *rdac_failover_get(struct scsi_device *sdev,
> + struct rdac_dh_data *h)
> {
> struct request *rq;
> struct rdac_mode_common *common;
> unsigned data_size;
> - struct rdac_dh_data *h = get_rdac_data(sdev);
>
> if (h->ctlr->use_ms10) {
> struct rdac_pg_expanded *rdac_pg;
> @@ -277,6 +285,10 @@ static struct request *rdac_failover_get(struct scsi_device *sdev)
> }
> rq->cmd_len = COMMAND_SIZE(rq->cmd[0]);
>
> + rq->sense = h->sense;
> + memset(rq->sense, 0, SCSI_SENSE_BUFFERSIZE);
> + rq->sense_len = 0;
> +
> return rq;
> }
>
> @@ -321,11 +333,10 @@ done:
> }
>
> static int submit_inquiry(struct scsi_device *sdev, int page_code,
> - unsigned int len)
> + unsigned int len, struct rdac_dh_data *h)
> {
> struct request *rq;
> struct request_queue *q = sdev->request_queue;
> - struct rdac_dh_data *h = get_rdac_data(sdev);
> int err = SCSI_DH_RES_TEMP_UNAVAIL;
>
> rq = get_rdac_req(sdev, &h->inq, len, READ);
> @@ -338,59 +349,68 @@ static int submit_inquiry(struct scsi_device *sdev, int page_code,
> rq->cmd[2] = page_code;
> rq->cmd[4] = len;
> rq->cmd_len = COMMAND_SIZE(INQUIRY);
> +
> + rq->sense = h->sense;
> + memset(rq->sense, 0, SCSI_SENSE_BUFFERSIZE);
> + rq->sense_len = 0;
> +
> err = blk_execute_rq(q, NULL, rq, 1);
> if (err == -EIO)
> err = SCSI_DH_IO;
> +
> + blk_put_request(rq);
> done:
> return err;
> }
>
> -static int get_lun(struct scsi_device *sdev)
> +static int get_lun(struct scsi_device *sdev, struct rdac_dh_data *h)
> {
> int err;
> struct c8_inquiry *inqp;
> - struct rdac_dh_data *h = get_rdac_data(sdev);
>
> - err = submit_inquiry(sdev, 0xC8, sizeof(struct c8_inquiry));
> + err = submit_inquiry(sdev, 0xC8, sizeof(struct c8_inquiry), h);
> if (err == SCSI_DH_OK) {
> inqp = &h->inq.c8;
> - h->lun = inqp->lun[7]; /* currently it uses only one byte */
> + if (inqp->page_code != 0xc8)
> + return SCSI_DH_NOSYS;
> + if (inqp->page_id[0] != 'e' || inqp->page_id[1] != 'd' ||
> + inqp->page_id[2] != 'i' || inqp->page_id[3] != 'd')
> + return SCSI_DH_NOSYS;
> + h->lun = scsilun_to_int((struct scsi_lun *)inqp->lun);
> }
> return err;
> }
>
> -#define RDAC_OWNED 0
> -#define RDAC_UNOWNED 1
> -#define RDAC_FAILED 2
> -static int check_ownership(struct scsi_device *sdev)
> +static int check_ownership(struct scsi_device *sdev, struct rdac_dh_data *h)
> {
> int err;
> struct c9_inquiry *inqp;
> - struct rdac_dh_data *h = get_rdac_data(sdev);
>
> - err = submit_inquiry(sdev, 0xC9, sizeof(struct c9_inquiry));
> + err = submit_inquiry(sdev, 0xC9, sizeof(struct c9_inquiry), h);
> if (err == SCSI_DH_OK) {
> - err = RDAC_UNOWNED;
> inqp = &h->inq.c9;
> - /*
> - * If in AVT mode or if the path already owns the LUN,
> - * return RDAC_OWNED;
> - */
> - if (((inqp->avte_cvp >> 7) == 0x1) ||
> - ((inqp->avte_cvp & 0x1) != 0))
> - err = RDAC_OWNED;
> - } else
> - err = RDAC_FAILED;
> + if ((inqp->avte_cvp >> 7) == 0x1) {
> + /* LUN in AVT mode */
> + sdev_printk(KERN_NOTICE, sdev,
> + "%s: AVT mode detected
",
> + RDAC_NAME);
> + h->lun_state = RDAC_LUN_AVT;
> + } else if ((inqp->avte_cvp & 0x1) != 0) {
> + /* LUN was owned by the controller */
> + h->lun_state = RDAC_LUN_OWNED;
> + }
> + }
> +
> return err;
> }
>
> -static int initialize_controller(struct scsi_device *sdev)
> +static int initialize_controller(struct scsi_device *sdev,
> + struct rdac_dh_data *h)
> {
> int err;
> struct c4_inquiry *inqp;
> - struct rdac_dh_data *h = get_rdac_data(sdev);
>
> - err = submit_inquiry(sdev, 0xC4, sizeof(struct c4_inquiry));
> + err = submit_inquiry(sdev, 0xC4, sizeof(struct c4_inquiry), h);
> if (err == SCSI_DH_OK) {
> inqp = &h->inq.c4;
> h->ctlr = get_controller(inqp->subsys_id, inqp->slot_id);
> @@ -400,13 +420,12 @@ static int initialize_controller(struct scsi_device *sdev)
> return err;
> }
>
> -static int set_mode_select(struct scsi_device *sdev)
> +static int set_mode_select(struct scsi_device *sdev, struct rdac_dh_data *h)
> {
> int err;
> struct c2_inquiry *inqp;
> - struct rdac_dh_data *h = get_rdac_data(sdev);
>
> - err = submit_inquiry(sdev, 0xC2, sizeof(struct c2_inquiry));
> + err = submit_inquiry(sdev, 0xC2, sizeof(struct c2_inquiry), h);
> if (err == SCSI_DH_OK) {
> inqp = &h->inq.c2;
> /*
> @@ -421,13 +440,13 @@ static int set_mode_select(struct scsi_device *sdev)
> return err;
> }
>
> -static int mode_select_handle_sense(struct scsi_device *sdev)
> +static int mode_select_handle_sense(struct scsi_device *sdev,
> + unsigned char *sensebuf)
> {
> struct scsi_sense_hdr sense_hdr;
> - struct rdac_dh_data *h = get_rdac_data(sdev);
> int sense, err = SCSI_DH_IO, ret;
>
> - ret = scsi_normalize_sense(h->sense, SCSI_SENSE_BUFFERSIZE, &sense_hdr);
> + ret = scsi_normalize_sense(sensebuf, SCSI_SENSE_BUFFERSIZE, &sense_hdr);
> if (!ret)
> goto done;
>
> @@ -451,14 +470,13 @@ done:
> return err;
> }
>
> -static int send_mode_select(struct scsi_device *sdev)
> +static int send_mode_select(struct scsi_device *sdev, struct rdac_dh_data *h)
> {
> struct request *rq;
> struct request_queue *q = sdev->request_queue;
> - struct rdac_dh_data *h = get_rdac_data(sdev);
> int err = SCSI_DH_RES_TEMP_UNAVAIL;
>
> - rq = rdac_failover_get(sdev);
> + rq = rdac_failover_get(sdev, h);
> if (!rq)
> goto done;
>
> @@ -466,9 +484,11 @@ static int send_mode_select(struct scsi_device *sdev)
>
> err = blk_execute_rq(q, NULL, rq, 1);
> if (err != SCSI_DH_OK)
> - err = mode_select_handle_sense(sdev);
> + err = mode_select_handle_sense(sdev, h->sense);
> if (err == SCSI_DH_OK)
> h->state = RDAC_STATE_ACTIVE;
> +
> + blk_put_request(rq);
> done:
> return err;
> }
> @@ -478,38 +498,23 @@ static int rdac_activate(struct scsi_device *sdev)
> struct rdac_dh_data *h = get_rdac_data(sdev);
> int err = SCSI_DH_OK;
>
> - if (h->lun == UNINITIALIZED_LUN) {
> - err = get_lun(sdev);
> - if (err != SCSI_DH_OK)
> - goto done;
> - }
> -
> - err = check_ownership(sdev);
> - switch (err) {
> - case RDAC_UNOWNED:
> - break;
> - case RDAC_OWNED:
> - err = SCSI_DH_OK;
> - goto done;
> - case RDAC_FAILED:
> - default:
> - err = SCSI_DH_IO;
> + err = check_ownership(sdev, h);
> + if (err != SCSI_DH_OK)
> goto done;
> - }
>
> if (!h->ctlr) {
> - err = initialize_controller(sdev);
> + err = initialize_controller(sdev, h);
> if (err != SCSI_DH_OK)
> goto done;
> }
>
> if (h->ctlr->use_ms10 == -1) {
> - err = set_mode_select(sdev);
> + err = set_mode_select(sdev, h);
> if (err != SCSI_DH_OK)
> goto done;
> }
> -
> - err = send_mode_select(sdev);
> + if (h->lun_state == RDAC_LUN_UNOWNED)
> + err = send_mode_select(sdev, h);
> done:
> return err;
> }
> @@ -606,11 +611,12 @@ static int rdac_bus_attach(struct scsi_device *sdev)
> struct scsi_dh_data *scsi_dh_data;
> struct rdac_dh_data *h;
> unsigned long flags;
> + int err;
>
> scsi_dh_data = kzalloc(sizeof(struct scsi_device_handler *)
> + sizeof(*h) , GFP_KERNEL);
> if (!scsi_dh_data) {
> - sdev_printk(KERN_ERR, sdev, "Attach failed %s.
",
> + sdev_printk(KERN_ERR, sdev, "%s: Attach failed
",
> RDAC_NAME);
> return 0;
> }
> @@ -619,14 +625,32 @@ static int rdac_bus_attach(struct scsi_device *sdev)
> h = (struct rdac_dh_data *) scsi_dh_data->buf;
> h->lun = UNINITIALIZED_LUN;
> h->state = RDAC_STATE_ACTIVE;
> +
> + err = get_lun(sdev, h);
> + if (err != SCSI_DH_OK)
> + goto failed;
> +
> + err = check_ownership(sdev, h);
> + if (err != SCSI_DH_OK)
> + goto failed;
> +
> spin_lock_irqsave(sdev->request_queue->queue_lock, flags);
> sdev->scsi_dh_data = scsi_dh_data;
> spin_unlock_irqrestore(sdev->request_queue->queue_lock, flags);
> - try_module_get(THIS_MODULE);
>
> - sdev_printk(KERN_NOTICE, sdev, "Attached %s
", RDAC_NAME);
> + sdev_printk(KERN_NOTICE, sdev,
> + "%s: LUN %d (%s)
",
> + RDAC_NAME, h->lun, lun_state[(int)h->lun_state]);
> +
> + try_module_get(THIS_MODULE);
>
> return 0;
> +
> +failed:
> + kfree(scsi_dh_data);
> + sdev_printk(KERN_ERR, sdev, "%s: not attached
",
> + RDAC_NAME);
> + return -EINVAL;
> }
>
> static void rdac_bus_detach( struct scsi_device *sdev )
> @@ -645,7 +669,7 @@ static void rdac_bus_detach( struct scsi_device *sdev )
> kref_put(&h->ctlr->kref, release_controller);
> kfree(scsi_dh_data);
> module_put(THIS_MODULE);
> - sdev_printk(KERN_NOTICE, sdev, "Detached %s
", RDAC_NAME);
> + sdev_printk(KERN_NOTICE, sdev, "%s: Detached
", RDAC_NAME);
> }
>
> static int __init rdac_init(void)

--
dm-devel mailing list
dm-devel@redhat.com
https://www.redhat.com/mailman/listinfo/dm-devel
 
Old 07-17-2008, 11:53 PM
Chandra Seetharaman
 
Default scsi_dh: Update RDAC device handler

This patch updates the RDAC device handler to
refuse to attach to devices not supporting the
RDAC vpd pages.

Signed-off-by: Hannes Reinecke <hare@suse.de>
Signed-off-by: Chandra Seetharaman <sekharan@us.ibm.com>
---
drivers/scsi/device_handler/scsi_dh_rdac.c | 163 ++++++++++++++++------------
1 files changed, 94 insertions(+), 69 deletions(-)

Index: linux-2.6.26-git5/drivers/scsi/device_handler/scsi_dh_rdac.c
================================================== =================
--- linux-2.6.26-git5.orig/drivers/scsi/device_handler/scsi_dh_rdac.c
+++ linux-2.6.26-git5/drivers/scsi/device_handler/scsi_dh_rdac.c
@@ -173,6 +173,11 @@ struct rdac_dh_data {
#define RDAC_STATE_ACTIVE 0
#define RDAC_STATE_PASSIVE 1
unsigned char state;
+
+#define RDAC_LUN_UNOWNED 0
+#define RDAC_LUN_OWNED 1
+#define RDAC_LUN_AVT 2
+ char lun_state;
unsigned char sense[SCSI_SENSE_BUFFERSIZE];
union {
struct c2_inquiry c2;
@@ -182,6 +187,13 @@ struct rdac_dh_data {
} inq;
};

+static const char *lun_state[] =
+{
+ "unowned",
+ "owned",
+ "owned (AVT mode)",
+};
+
static LIST_HEAD(ctlr_list);
static DEFINE_SPINLOCK(list_lock);

@@ -197,9 +209,8 @@ static struct request *get_rdac_req(stru
{
struct request *rq;
struct request_queue *q = sdev->request_queue;
- struct rdac_dh_data *h = get_rdac_data(sdev);

- rq = blk_get_request(q, rw, GFP_KERNEL);
+ rq = blk_get_request(q, rw, GFP_NOIO);

if (!rq) {
sdev_printk(KERN_INFO, sdev,
@@ -207,17 +218,14 @@ static struct request *get_rdac_req(stru
return NULL;
}

- if (buflen && blk_rq_map_kern(q, rq, buffer, buflen, GFP_KERNEL)) {
+ if (buflen && blk_rq_map_kern(q, rq, buffer, buflen, GFP_NOIO)) {
blk_put_request(rq);
sdev_printk(KERN_INFO, sdev,
"get_rdac_req: blk_rq_map_kern failed.
");
return NULL;
}

- memset(&rq->cmd, 0, BLK_MAX_CDB);
- rq->sense = h->sense;
- memset(rq->sense, 0, SCSI_SENSE_BUFFERSIZE);
- rq->sense_len = 0;
+ memset(rq->cmd, 0, BLK_MAX_CDB);

rq->cmd_type = REQ_TYPE_BLOCK_PC;
rq->cmd_flags |= REQ_FAILFAST | REQ_NOMERGE;
@@ -227,12 +235,12 @@ static struct request *get_rdac_req(stru
return rq;
}

-static struct request *rdac_failover_get(struct scsi_device *sdev)
+static struct request *rdac_failover_get(struct scsi_device *sdev,
+ struct rdac_dh_data *h)
{
struct request *rq;
struct rdac_mode_common *common;
unsigned data_size;
- struct rdac_dh_data *h = get_rdac_data(sdev);

if (h->ctlr->use_ms10) {
struct rdac_pg_expanded *rdac_pg;
@@ -277,6 +285,10 @@ static struct request *rdac_failover_get
}
rq->cmd_len = COMMAND_SIZE(rq->cmd[0]);

+ rq->sense = h->sense;
+ memset(rq->sense, 0, SCSI_SENSE_BUFFERSIZE);
+ rq->sense_len = 0;
+
return rq;
}

@@ -321,11 +333,10 @@ done:
}

static int submit_inquiry(struct scsi_device *sdev, int page_code,
- unsigned int len)
+ unsigned int len, struct rdac_dh_data *h)
{
struct request *rq;
struct request_queue *q = sdev->request_queue;
- struct rdac_dh_data *h = get_rdac_data(sdev);
int err = SCSI_DH_RES_TEMP_UNAVAIL;

rq = get_rdac_req(sdev, &h->inq, len, READ);
@@ -338,59 +349,68 @@ static int submit_inquiry(struct scsi_de
rq->cmd[2] = page_code;
rq->cmd[4] = len;
rq->cmd_len = COMMAND_SIZE(INQUIRY);
+
+ rq->sense = h->sense;
+ memset(rq->sense, 0, SCSI_SENSE_BUFFERSIZE);
+ rq->sense_len = 0;
+
err = blk_execute_rq(q, NULL, rq, 1);
if (err == -EIO)
err = SCSI_DH_IO;
+
+ blk_put_request(rq);
done:
return err;
}

-static int get_lun(struct scsi_device *sdev)
+static int get_lun(struct scsi_device *sdev, struct rdac_dh_data *h)
{
int err;
struct c8_inquiry *inqp;
- struct rdac_dh_data *h = get_rdac_data(sdev);

- err = submit_inquiry(sdev, 0xC8, sizeof(struct c8_inquiry));
+ err = submit_inquiry(sdev, 0xC8, sizeof(struct c8_inquiry), h);
if (err == SCSI_DH_OK) {
inqp = &h->inq.c8;
- h->lun = inqp->lun[7]; /* currently it uses only one byte */
+ if (inqp->page_code != 0xc8)
+ return SCSI_DH_NOSYS;
+ if (inqp->page_id[0] != 'e' || inqp->page_id[1] != 'd' ||
+ inqp->page_id[2] != 'i' || inqp->page_id[3] != 'd')
+ return SCSI_DH_NOSYS;
+ h->lun = scsilun_to_int((struct scsi_lun *)inqp->lun);
}
return err;
}

-#define RDAC_OWNED 0
-#define RDAC_UNOWNED 1
-#define RDAC_FAILED 2
-static int check_ownership(struct scsi_device *sdev)
+static int check_ownership(struct scsi_device *sdev, struct rdac_dh_data *h)
{
int err;
struct c9_inquiry *inqp;
- struct rdac_dh_data *h = get_rdac_data(sdev);

- err = submit_inquiry(sdev, 0xC9, sizeof(struct c9_inquiry));
+ err = submit_inquiry(sdev, 0xC9, sizeof(struct c9_inquiry), h);
if (err == SCSI_DH_OK) {
- err = RDAC_UNOWNED;
inqp = &h->inq.c9;
- /*
- * If in AVT mode or if the path already owns the LUN,
- * return RDAC_OWNED;
- */
- if (((inqp->avte_cvp >> 7) == 0x1) ||
- ((inqp->avte_cvp & 0x1) != 0))
- err = RDAC_OWNED;
- } else
- err = RDAC_FAILED;
+ if ((inqp->avte_cvp >> 7) == 0x1) {
+ /* LUN in AVT mode */
+ sdev_printk(KERN_NOTICE, sdev,
+ "%s: AVT mode detected
",
+ RDAC_NAME);
+ h->lun_state = RDAC_LUN_AVT;
+ } else if ((inqp->avte_cvp & 0x1) != 0) {
+ /* LUN was owned by the controller */
+ h->lun_state = RDAC_LUN_OWNED;
+ }
+ }
+
return err;
}

-static int initialize_controller(struct scsi_device *sdev)
+static int initialize_controller(struct scsi_device *sdev,
+ struct rdac_dh_data *h)
{
int err;
struct c4_inquiry *inqp;
- struct rdac_dh_data *h = get_rdac_data(sdev);

- err = submit_inquiry(sdev, 0xC4, sizeof(struct c4_inquiry));
+ err = submit_inquiry(sdev, 0xC4, sizeof(struct c4_inquiry), h);
if (err == SCSI_DH_OK) {
inqp = &h->inq.c4;
h->ctlr = get_controller(inqp->subsys_id, inqp->slot_id);
@@ -400,13 +420,12 @@ static int initialize_controller(struct
return err;
}

-static int set_mode_select(struct scsi_device *sdev)
+static int set_mode_select(struct scsi_device *sdev, struct rdac_dh_data *h)
{
int err;
struct c2_inquiry *inqp;
- struct rdac_dh_data *h = get_rdac_data(sdev);

- err = submit_inquiry(sdev, 0xC2, sizeof(struct c2_inquiry));
+ err = submit_inquiry(sdev, 0xC2, sizeof(struct c2_inquiry), h);
if (err == SCSI_DH_OK) {
inqp = &h->inq.c2;
/*
@@ -421,13 +440,13 @@ static int set_mode_select(struct scsi_d
return err;
}

-static int mode_select_handle_sense(struct scsi_device *sdev)
+static int mode_select_handle_sense(struct scsi_device *sdev,
+ unsigned char *sensebuf)
{
struct scsi_sense_hdr sense_hdr;
- struct rdac_dh_data *h = get_rdac_data(sdev);
int sense, err = SCSI_DH_IO, ret;

- ret = scsi_normalize_sense(h->sense, SCSI_SENSE_BUFFERSIZE, &sense_hdr);
+ ret = scsi_normalize_sense(sensebuf, SCSI_SENSE_BUFFERSIZE, &sense_hdr);
if (!ret)
goto done;

@@ -451,14 +470,13 @@ done:
return err;
}

-static int send_mode_select(struct scsi_device *sdev)
+static int send_mode_select(struct scsi_device *sdev, struct rdac_dh_data *h)
{
struct request *rq;
struct request_queue *q = sdev->request_queue;
- struct rdac_dh_data *h = get_rdac_data(sdev);
int err = SCSI_DH_RES_TEMP_UNAVAIL;

- rq = rdac_failover_get(sdev);
+ rq = rdac_failover_get(sdev, h);
if (!rq)
goto done;

@@ -466,9 +484,11 @@ static int send_mode_select(struct scsi_

err = blk_execute_rq(q, NULL, rq, 1);
if (err != SCSI_DH_OK)
- err = mode_select_handle_sense(sdev);
+ err = mode_select_handle_sense(sdev, h->sense);
if (err == SCSI_DH_OK)
h->state = RDAC_STATE_ACTIVE;
+
+ blk_put_request(rq);
done:
return err;
}
@@ -478,38 +498,23 @@ static int rdac_activate(struct scsi_dev
struct rdac_dh_data *h = get_rdac_data(sdev);
int err = SCSI_DH_OK;

- if (h->lun == UNINITIALIZED_LUN) {
- err = get_lun(sdev);
- if (err != SCSI_DH_OK)
- goto done;
- }
-
- err = check_ownership(sdev);
- switch (err) {
- case RDAC_UNOWNED:
- break;
- case RDAC_OWNED:
- err = SCSI_DH_OK;
- goto done;
- case RDAC_FAILED:
- default:
- err = SCSI_DH_IO;
+ err = check_ownership(sdev, h);
+ if (err != SCSI_DH_OK)
goto done;
- }

if (!h->ctlr) {
- err = initialize_controller(sdev);
+ err = initialize_controller(sdev, h);
if (err != SCSI_DH_OK)
goto done;
}

if (h->ctlr->use_ms10 == -1) {
- err = set_mode_select(sdev);
+ err = set_mode_select(sdev, h);
if (err != SCSI_DH_OK)
goto done;
}
-
- err = send_mode_select(sdev);
+ if (h->lun_state == RDAC_LUN_UNOWNED)
+ err = send_mode_select(sdev, h);
done:
return err;
}
@@ -606,11 +611,12 @@ static int rdac_bus_attach(struct scsi_d
struct scsi_dh_data *scsi_dh_data;
struct rdac_dh_data *h;
unsigned long flags;
+ int err;

scsi_dh_data = kzalloc(sizeof(struct scsi_device_handler *)
+ sizeof(*h) , GFP_KERNEL);
if (!scsi_dh_data) {
- sdev_printk(KERN_ERR, sdev, "Attach failed %s.
",
+ sdev_printk(KERN_ERR, sdev, "%s: Attach failed
",
RDAC_NAME);
return 0;
}
@@ -619,14 +625,33 @@ static int rdac_bus_attach(struct scsi_d
h = (struct rdac_dh_data *) scsi_dh_data->buf;
h->lun = UNINITIALIZED_LUN;
h->state = RDAC_STATE_ACTIVE;
+
+ err = get_lun(sdev, h);
+ if (err != SCSI_DH_OK)
+ goto failed;
+
+ err = check_ownership(sdev, h);
+ if (err != SCSI_DH_OK)
+ goto failed;
+
+ if (!try_module_get(THIS_MODULE))
+ goto failed;
+
spin_lock_irqsave(sdev->request_queue->queue_lock, flags);
sdev->scsi_dh_data = scsi_dh_data;
spin_unlock_irqrestore(sdev->request_queue->queue_lock, flags);
- try_module_get(THIS_MODULE);

- sdev_printk(KERN_NOTICE, sdev, "Attached %s
", RDAC_NAME);
+ sdev_printk(KERN_NOTICE, sdev,
+ "%s: LUN %d (%s)
",
+ RDAC_NAME, h->lun, lun_state[(int)h->lun_state]);

return 0;
+
+failed:
+ kfree(scsi_dh_data);
+ sdev_printk(KERN_ERR, sdev, "%s: not attached
",
+ RDAC_NAME);
+ return -EINVAL;
}

static void rdac_bus_detach( struct scsi_device *sdev )
@@ -645,7 +670,7 @@ static void rdac_bus_detach( struct scsi
kref_put(&h->ctlr->kref, release_controller);
kfree(scsi_dh_data);
module_put(THIS_MODULE);
- sdev_printk(KERN_NOTICE, sdev, "Detached %s
", RDAC_NAME);
+ sdev_printk(KERN_NOTICE, sdev, "%s: Detached
", RDAC_NAME);
}



--
dm-devel mailing list
dm-devel@redhat.com
https://www.redhat.com/mailman/listinfo/dm-devel
 

Thread Tools




All times are GMT. The time now is 09:47 PM.

VBulletin, Copyright ©2000 - 2014, Jelsoft Enterprises Ltd.
Content Relevant URLs by vBSEO ©2007, Crawlability, Inc.
Copyright ©2007 - 2008, www.linux-archive.org