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