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