]> pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - drivers/scsi/osd/osd_uld.c
Merge branch 'percpu-cpumask-x86-for-linus-2' of git://git.kernel.org/pub/scm/linux...
[linux-2.6-omap-h63xx.git] / drivers / scsi / osd / osd_uld.c
index f6f9a99adaa6bbe9d38baf3290ab7f1939e1c98d..f8b1a749958b1f7cbfea0c095af5fdbee599da1e 100644 (file)
@@ -173,6 +173,69 @@ static const struct file_operations osd_fops = {
        .unlocked_ioctl = osd_uld_ioctl,
 };
 
+struct osd_dev *osduld_path_lookup(const char *path)
+{
+       struct nameidata nd;
+       struct inode *inode;
+       struct cdev *cdev;
+       struct osd_uld_device *uninitialized_var(oud);
+       int error;
+
+       if (!path || !*path) {
+               OSD_ERR("Mount with !path || !*path\n");
+               return ERR_PTR(-EINVAL);
+       }
+
+       error = path_lookup(path, LOOKUP_FOLLOW, &nd);
+       if (error) {
+               OSD_ERR("path_lookup of %s faild=>%d\n", path, error);
+               return ERR_PTR(error);
+       }
+
+       inode = nd.path.dentry->d_inode;
+       error = -EINVAL; /* Not the right device e.g osd_uld_device */
+       if (!S_ISCHR(inode->i_mode)) {
+               OSD_DEBUG("!S_ISCHR()\n");
+               goto out;
+       }
+
+       cdev = inode->i_cdev;
+       if (!cdev) {
+               OSD_ERR("Before mounting an OSD Based filesystem\n");
+               OSD_ERR("  user-mode must open+close the %s device\n", path);
+               OSD_ERR("  Example: bash: echo < %s\n", path);
+               goto out;
+       }
+
+       /* The Magic wand. Is it our char-dev */
+       /* TODO: Support sg devices */
+       if (cdev->owner != THIS_MODULE) {
+               OSD_ERR("Error mounting %s - is not an OSD device\n", path);
+               goto out;
+       }
+
+       oud = container_of(cdev, struct osd_uld_device, cdev);
+
+       __uld_get(oud);
+       error = 0;
+
+out:
+       path_put(&nd.path);
+       return error ? ERR_PTR(error) : &oud->od;
+}
+EXPORT_SYMBOL(osduld_path_lookup);
+
+void osduld_put_device(struct osd_dev *od)
+{
+       if (od) {
+               struct osd_uld_device *oud = container_of(od,
+                                               struct osd_uld_device, od);
+
+               __uld_put(oud);
+       }
+}
+EXPORT_SYMBOL(osduld_put_device);
+
 /*
  * Scsi Device operations
  */
@@ -180,6 +243,7 @@ static const struct file_operations osd_fops = {
 static int __detect_osd(struct osd_uld_device *oud)
 {
        struct scsi_device *scsi_device = oud->od.scsi_device;
+       char caps[OSD_CAP_LEN];
        int error;
 
        /* sending a test_unit_ready as first command seems to be needed
@@ -191,6 +255,10 @@ static int __detect_osd(struct osd_uld_device *oud)
        if (error)
                OSD_ERR("warning: scsi_test_unit_ready failed\n");
 
+       osd_sec_init_nosec_doall_caps(caps, &osd_root_object, false, true);
+       if (osd_auto_detect_ver(&oud->od, caps))
+               return -ENODEV;
+
        return 0;
 }