• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /****************************************************************************
2  * drivers/bch/bchdev_unregister.c
3  *
4  * Licensed to the Apache Software Foundation (ASF) under one or more
5  * contributor license agreements.  See the NOTICE file distributed with
6  * this work for additional information regarding copyright ownership.  The
7  * ASF licenses this file to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance with the
9  * License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
15  * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
16  * License for the specific language governing permissions and limitations
17  * under the License.
18  *
19  ****************************************************************************/
20 
21 /****************************************************************************
22  * Included Files
23  ****************************************************************************/
24 #include <sys/stat.h>
25 #include <unistd.h>
26 #include <fcntl.h>
27 #include <sched.h>
28 #include <errno.h>
29 #include <assert.h>
30 #include <sys/ioctl.h>
31 #include "bch.h"
32 #include "fs/driver.h"
33 
34 #define _err PRINTK
35 
36 /****************************************************************************
37  * Public Functions
38  ****************************************************************************/
39 
40 /****************************************************************************
41  * Name: bchdev_unregister
42  *
43  * Description:
44  *   Unregister character driver access to a block device that was created
45  *   by a previous call to bchdev_register().
46  *
47  ****************************************************************************/
48 
bchdev_unregister(const char * chardev)49 int bchdev_unregister(const char *chardev)
50 {
51   struct bchlib_s *bch;
52   int fd;
53   int ret;
54 
55   /* Sanity check */
56 
57   if (!chardev)
58     {
59       return -EINVAL;
60     }
61 
62   /* Open the character driver associated with chardev */
63 
64   fd = open(chardev, O_RDONLY);
65   if (fd < 0)
66     {
67       _err("ERROR: Failed to open %s: %d\n", chardev, errno);
68       return -errno;
69     }
70 
71   /* Get a reference to the internal data structure.  On success, we
72    * will hold a reference count on the state structure.
73    */
74 
75   ret = ioctl(fd, DIOC_GETPRIV, (unsigned long)((uintptr_t)&bch));
76   (void)close(fd);
77 
78   if (ret < 0)
79     {
80       _err("ERROR: ioctl failed: %d\n", errno);
81       return -errno;
82     }
83 
84   /* Lock out context switches.  If there are no other references
85    * and no context switches, then we can assume that we can safely
86    * teardown the driver.
87    */
88 
89   LOS_TaskLock();
90 
91   /* Check if the internal structure is non-busy (we hold one reference). */
92 
93   if (bch->refs > 1)
94     {
95       ret = -EBUSY;
96       goto errout_with_lock;
97     }
98 
99   /* Unregister the driver (this cannot suspend or we lose our non-preemptive
100    * state!).  Once the driver is successfully unregistered, we can assume
101    * we have exclusive access to the state instance.
102    */
103 
104   ret = unregister_driver(chardev);
105   if (ret < 0)
106     {
107       goto errout_with_lock;
108     }
109 
110   LOS_TaskUnlock();
111 
112   /* Release the internal structure */
113 
114   bch->refs = 0;
115   return bchlib_teardown(bch);
116 
117 errout_with_lock:
118   bch->refs--;
119   LOS_TaskUnlock();
120   return ret;
121 }
122