]> git.hungrycats.org Git - linux/commitdiff
[PATCH] aacraid: Detect non-committed array
authorMark Haverkamp <markh@osdl.org>
Mon, 13 Sep 2004 12:48:43 +0000 (08:48 -0400)
committerChristoph Hellwig <hch@lst.de>
Mon, 13 Sep 2004 12:48:43 +0000 (08:48 -0400)
From:  Mark Salyzyn at Adaptec

In the case of this driver patch, we will report to the user via a
syslogd kernel message that a foreign array has been ignored in
non-intel environments; or intel environments where the BIOS fails to
load to perform this set of housekeeping functions. There is a
provision, via the commit variable, to change this behavior to accept
the configuration instead.

Signed-off-by: Mark Haverkamp <markh@osdl.org>
Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com>
drivers/scsi/aacraid/aachba.c
drivers/scsi/aacraid/aacraid.h
drivers/scsi/aacraid/linit.c

index bb03a95fad6a7b376d9165468ec5942e611cede3..238621eea425a62f463effe008e74affe971cd84 100644 (file)
@@ -193,6 +193,80 @@ MODULE_PARM_DESC(commit, "Control whether a COMMIT_CONFIG is issued to the adapt
 static int nondasd = -1;
 static int dacmode = -1;
 
+static int commit = -1;
+
+/**
+ *     aac_get_config_status   -       check the adapter configuration
+ *     @common: adapter to query
+ *
+ *     Query config status, and commit the configuration if needed.
+ */
+int aac_get_config_status(struct aac_dev *dev)
+{
+       int status = 0;
+       struct fib * fibptr;
+
+       if (!(fibptr = fib_alloc(dev)))
+               return -ENOMEM;
+
+       fib_init(fibptr);
+       {
+               struct aac_get_config_status *dinfo;
+               dinfo = (struct aac_get_config_status *) fib_data(fibptr);
+
+               dinfo->command = cpu_to_le32(VM_ContainerConfig);
+               dinfo->type = cpu_to_le32(CT_GET_CONFIG_STATUS);
+               dinfo->count = cpu_to_le32(sizeof(((struct aac_get_config_status_resp *)NULL)->data));
+       }
+
+       status = fib_send(ContainerCommand,
+                           fibptr,
+                           sizeof (struct aac_get_config_status),
+                           FsaNormal,
+                           1, 1,
+                           NULL, NULL);
+       if (status < 0 ) {
+               printk(KERN_WARNING "aac_get_config_status: SendFIB failed.\n");
+       } else {
+               struct aac_get_config_status_resp *reply
+                 = (struct aac_get_config_status_resp *) fib_data(fibptr);
+               dprintk((KERN_WARNING
+                 "aac_get_config_status: response=%d status=%d action=%d\n",
+                 reply->response, reply->status, reply->data.action));
+               if ((reply->response != ST_OK)
+                || (reply->status != CT_OK)
+                || (reply->data.action > CFACT_PAUSE)) {
+                       printk(KERN_WARNING "aac_get_config_status: Will not issue the Commit Configuration\n");
+                       status = -EINVAL;
+               }
+       }
+       fib_complete(fibptr);
+       /* Send a CT_COMMIT_CONFIG to enable discovery of devices */
+       if (status >= 0) {
+               if (commit == 1) {
+                       struct aac_commit_config * dinfo;
+                       fib_init(fibptr);
+                       dinfo = (struct aac_commit_config *) fib_data(fibptr);
+       
+                       dinfo->command = cpu_to_le32(VM_ContainerConfig);
+                       dinfo->type = cpu_to_le32(CT_COMMIT_CONFIG);
+       
+                       status = fib_send(ContainerCommand,
+                                   fibptr,
+                                   sizeof (struct aac_commit_config),
+                                   FsaNormal,
+                                   1, 1,
+                                   NULL, NULL);
+                       fib_complete(fibptr);
+               } else if (commit == 0) {
+                       printk(KERN_WARNING
+                         "aac_get_config_status: Foreign device configurations are being ignored\n");
+               }
+       }
+       fib_free(fibptr);
+       return status;
+}
+
 /**
  *     aac_get_containers      -       list containers
  *     @common: adapter to probe
index 20302a3e89fc683978b3d689788680760e066c88..fb379f8900036ba9048891f36fd66306857ee699 100644 (file)
@@ -57,6 +57,7 @@ struct diskparm
 #define                CT_VOLUME_OF_MIRRORS    12      /* volume of mirror */
 #define                CT_PSEUDO_RAID          13      /* really raid4 */
 #define                CT_LAST_VOLUME_TYPE     14
+#define        CT_OK                   218
 
 /*
  *     Types of objects addressable in some fashion by the client.
@@ -1168,6 +1169,52 @@ union aac_contentinfo {
        struct aac_fsinfo filesys;      /* valid iff ObjType == FT_FILESYS && !(ContentState & FSCS_NOTCLEAN) */
 };
 
+/*
+ *     Query for Container Configuration Status
+ */
+
+#define CT_GET_CONFIG_STATUS 147
+struct aac_get_config_status {
+       u32             command;        /* VM_ContainerConfig */
+       u32             type;           /* CT_GET_CONFIG_STATUS */
+       u32             parm1;
+       u32             parm2;
+       u32             parm3;
+       u32             parm4;
+       u32             parm5;
+       u32             count;  /* sizeof(((struct aac_get_config_status_resp *)NULL)->data) */
+};
+
+#define CFACT_CONTINUE 0
+#define CFACT_PAUSE    1
+#define CFACT_ABORT    2
+struct aac_get_config_status_resp {
+       u32             response; /* ST_OK */
+       u32             dummy0;
+       u32             status; /* CT_OK */
+       u32             parm1;
+       u32             parm2;
+       u32             parm3;
+       u32             parm4;
+       u32             parm5;
+       struct {
+               u32     action; /* CFACT_CONTINUE, CFACT_PAUSE or CFACT_ABORT */
+               u16     flags;
+               s16     count;
+       }               data;
+};
+
+/*
+ *     Accept the configuration as-is
+ */
+
+#define CT_COMMIT_CONFIG 152
+
+struct aac_commit_config {
+       u32             command;        /* VM_ContainerConfig */
+       u32             type;           /* CT_COMMIT_CONFIG */
+};
+
 /*
  *     Query for "mountable" objects, ie, objects that are typically
  *     associated with a drive letter on the client (host) side.
@@ -1443,6 +1490,7 @@ void aac_consumer_free(struct aac_dev * dev, struct aac_queue * q, u32 qnum);
 int fib_complete(struct fib * context);
 #define fib_data(fibctx) ((void *)(fibctx)->hw_fib->data)
 struct aac_dev *aac_init_adapter(struct aac_dev *dev);
+int aac_get_config_status(struct aac_dev *dev);
 int aac_get_containers(struct aac_dev *dev);
 int aac_scsi_cmd(struct scsi_cmnd *cmd);
 int aac_dev_ioctl(struct aac_dev *dev, int cmd, void __user *arg);
index 04a8a571a28eca9fe1f66155eb11877fb7deb81c..129873af79fc4a2492cdf445aac65e3cbf958168 100644 (file)
@@ -589,6 +589,7 @@ static int __devinit aac_probe_one(struct pci_dev *pdev,
        else
                shost->max_channel = 1;
 
+       aac_get_config_status(aac);
        aac_get_containers(aac);
        aac_devices[aac_count-1] = aac;