4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh * CDDL HEADER START
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh * The contents of this file are subject to the terms of the
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh * Common Development and Distribution License (the "License").
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh * You may not use this file except in compliance with the License.
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh * See the License for the specific language governing permissions
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh * and limitations under the License.
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh * When distributing Covered Code, include this CDDL HEADER in each
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh * If applicable, add the following below this CDDL HEADER, with the
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh * fields enclosed by brackets "[]" replaced with your own identifying
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh * information: Portions Copyright [yyyy] [name of copyright owner]
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh * CDDL HEADER END
616875b414de63a60e3f732e0d9b5345f07f9221David Hollister * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh * Use is subject to license terms.
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh * Copyright 2012 Milan Jurik. All rights reserved.
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dhextern void nscsetup();
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dhextern int _nsc_init_raw(int);
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dhextern void _nsc_deinit_raw();
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dhextern void _nsc_init_start();
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dhextern void _nsc_deinit_dev();
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dhextern int _nsc_frz_start(char *, int *);
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dhextern int _nsc_frz_stop(char *, int *);
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dhextern int _nsc_frz_isfrozen(char *, int *);
c3bc407cfbd238a18e4728ad5f36f39cecdb062fdh/* Maximum number of devices - tunable in nsctl.conf */
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh/* Internal version of _nsc_max_devices */
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dhextern void _nsc_global_setup(void);
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dhstatic void nscteardown();
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh * Solaris specific driver module interface code.
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dhextern int nscioctl(dev_t, int, intptr_t, int, cred_t *, int *);
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh nodev, /* not a block driver, strategy not an entry point */
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh 0, /* not a STREAMS driver, no cb_str routine */
96c4a178a18cd52ee5001195f1552d9cef0c38f0Chris Horne D_NEW | D_MP | D_64BIT, /* safe for multi-thread/multi-processor */
c3bc407cfbd238a18e4728ad5f36f39cecdb062fdhstatic int _nsctl_getinfo(dev_info_t *, ddi_info_cmd_t, void *, void **);
96c4a178a18cd52ee5001195f1552d9cef0c38f0Chris Hornestatic int _nsctl_attach(dev_info_t *, ddi_attach_cmd_t);
96c4a178a18cd52ee5001195f1552d9cef0c38f0Chris Hornestatic int _nsctl_detach(dev_info_t *, ddi_detach_cmd_t);
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh 0, /* device reference count */
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh (struct bus_ops *)0
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh * Solaris module load time code
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh * Solaris module unload time code
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh * Solaris module info code
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh * Attach an instance of the device. This happens before an open
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh * can succeed.
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh /* Announce presence of the device */
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh * Get the node parameters now that we can look up.
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh "nsc_min_nodeid", 0);
c40ba10d39e7750947725517ec5639ef2d6e90e5Reed _nsc_max_devices = ddi_prop_get_int(DDI_DEV_T_ANY, dip,
c3bc407cfbd238a18e4728ad5f36f39cecdb062fdh * Init raw requires the _nsc_max_devices value and so
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh * cannot be done before the nsc_max_devices property has
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh * been read which can only be done after the module is
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh * attached and we have a dip.
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh "!nsctl: unable to initialize raw io provider: %d",
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh * Init rest of soft state structure
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh /* free anything we allocated here */
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh "!_nsctl_attach: ddi_create_minor_node failed %d",
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh /* Announce presence of the device */
c3bc407cfbd238a18e4728ad5f36f39cecdb062fdh /* mark the device as attached, opens may proceed */
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh/* ARGSUSED */
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh_nsctl_getinfo(dev_info_t *dip, ddi_info_cmd_t cmd, void *arg, void **result)
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh switch (cmd) {
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh /* The "instance" number is the minor number */
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh return (rc);
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh/* ARGSUSED */
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh return (0);
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh * When using mc, nscsetup is done through mc callback to global_init.
499cfd156ad653fc27397c5f021047c091dd12c5David Hollister mutex_init(&_nsc_drv_lock, NULL, MUTEX_DRIVER, NULL);
73a3eccd27d9673a6407274ea0de350699562fd9David Hollister cmn_err(CE_WARN, "!_nsc_init: register io failed - raw");
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh * Called after the mc refresh is complete (SEG_INIT callbacks have
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh * been received) and module _attach() is done. Only does any real
73a3eccd27d9673a6407274ea0de350699562fd9David Hollister * work when all of the above conditions have been met.
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh _nsc_minor_fd = nsc_kmem_zalloc(sizeof (nsc_fd_t *)*_nsc_maxdev,
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh _nsc_minor_slp = nsc_kmem_zalloc(sizeof (kmutex_t *)*_nsc_maxdev,
c40ba10d39e7750947725517ec5639ef2d6e90e5Reed nsc_kmem_free(_nsc_minor_fd, sizeof (nsc_fd_t *) * _nsc_maxdev);
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dhstatic void
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh /* Check all devices were closed. Index 0 is the prototype dev. */
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh#endif /* DEBUG */
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh nsc_kmem_free(_nsc_minor_fd, sizeof (nsc_fd_t *) * _nsc_maxdev);
c3bc407cfbd238a18e4728ad5f36f39cecdb062fdh nsc_kmem_free(_nsc_minor_slp, sizeof (kmutex_t *) * _nsc_maxdev);
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh return (0);
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh return (0);
c3bc407cfbd238a18e4728ad5f36f39cecdb062fdh return (0);
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh/* ARGSUSED */
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh slp = nsc_kmem_alloc(sizeof (kmutex_t), 0, _nsc_local_mem);
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh return (0);
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh op = nsc_kmem_alloc(sizeof (*op), KM_SLEEP, _nsc_local_mem);
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh if (ddi_copyin((void *)arg, op, sizeof (*op), mode) < 0) {
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh fd = nsc_open(op->path, (op->flag & NSC_TYPES), 0, 0, &rc);
c3bc407cfbd238a18e4728ad5f36f39cecdb062fdh return (rc);
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh return (rc);
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh return (0);
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh/* ARGSUSED */
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh return (0);
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh return (0);
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh return (0);
b18a19c275d2531444fcd2f66664cbe3c6897f6aJesse Butler/* ARGSUSED */
02b04f6e56ca306b4945eca969f282cfe6999414Srikanth, Ramana if (resv && (rc = nsc_reserve(fd, NSC_PCATCH)) != 0) {
c3bc407cfbd238a18e4728ad5f36f39cecdb062fdh return (rc);
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh/* ARGSUSED */
02b04f6e56ca306b4945eca969f282cfe6999414Srikanth, Ramananscwrite(dev_t dev, uio_t *uiop, cred_t *crp)
02b04f6e56ca306b4945eca969f282cfe6999414Srikanth, Ramana if (resv && (rc = nsc_reserve(fd, NSC_PCATCH)) != 0) {
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh return (rc);
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh return (0);
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh return (0);
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh return (rc);
c3bc407cfbd238a18e4728ad5f36f39cecdb062fdh return (rc);
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh/* ARGSUSED */
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dhnscioctl(dev_t dev, int cmd, intptr_t arg, int mode, cred_t *crp, int *rvp)
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh switch (cmd) {
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh path = nsc_kmem_alloc(NSC_MAXPATH, KM_SLEEP, _nsc_local_mem);
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh if (ddi_copyin((void *)arg, path, NSC_MAXPATH, mode) < 0)
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh path = nsc_kmem_alloc(NSC_MAXPATH, KM_SLEEP, _nsc_local_mem);
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh if (ddi_copyin((void *)arg, path, NSC_MAXPATH, mode) < 0)
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh path = nsc_kmem_alloc(NSC_MAXPATH, KM_SLEEP, _nsc_local_mem);
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh if (ddi_copyin((void *)arg, path, NSC_MAXPATH, mode) < 0)
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh /* return sizes of global memory segments */
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh /* return contents of global segments */
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh * nvmem systems:
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh * clear the hdr dirty bit to prevent loading from nvme on reboot
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh if (ddi_copyin((void *)arg, bsize, sizeof (*bsize), mode) < 0) {
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh if (rc == 0) {
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh return (rc);
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh * Used by _nsc_global_setup() in case nvram is dirty and has saved a different
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh * value for nsc_max_devices. We need to use the saved value, not the new
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh * one configured by the user.