Home | History | Annotate | Line # | Download | only in dev
bio.c revision 1.1.22.3
      1 /*	$NetBSD: bio.c,v 1.1.22.3 2007/10/15 20:37:08 riz Exp $ */
      2 /*	$OpenBSD: bio.c,v 1.9 2007/03/20 02:35:55 marco Exp $	*/
      3 
      4 /*
      5  * Copyright (c) 2002 Niklas Hallqvist.  All rights reserved.
      6  *
      7  * Redistribution and use in source and binary forms, with or without
      8  * modification, are permitted provided that the following conditions
      9  * are met:
     10  * 1. Redistributions of source code must retain the above copyright
     11  *    notice, this list of conditions and the following disclaimer.
     12  * 2. Redistributions in binary form must reproduce the above copyright
     13  *    notice, this list of conditions and the following disclaimer in the
     14  *    documentation and/or other materials provided with the distribution.
     15  *
     16  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
     17  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
     18  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
     19  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
     20  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
     21  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     22  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     23  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     24  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
     25  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     26  */
     27 
     28 /* A device controller ioctl tunnelling device.  */
     29 
     30 #include <sys/cdefs.h>
     31 __KERNEL_RCSID(0, "$NetBSD: bio.c,v 1.1.22.3 2007/10/15 20:37:08 riz Exp $");
     32 
     33 #include <sys/param.h>
     34 #include <sys/conf.h>
     35 #include <sys/device.h>
     36 #include <sys/event.h>
     37 #include <sys/ioctl.h>
     38 #include <sys/malloc.h>
     39 #include <sys/queue.h>
     40 #include <sys/systm.h>
     41 #include <sys/proc.h>
     42 
     43 #include <dev/biovar.h>
     44 
     45 struct bio_mapping {
     46 	LIST_ENTRY(bio_mapping) bm_link;
     47 	struct device *bm_dev;
     48 	int (*bm_ioctl)(struct device *, u_long, caddr_t);
     49 };
     50 
     51 LIST_HEAD(, bio_mapping) bios = LIST_HEAD_INITIALIZER(bios);
     52 
     53 void	bioattach(int);
     54 int	bioclose(dev_t, int, int, struct proc *);
     55 int	bioioctl(dev_t, u_long, caddr_t, int, struct proc *);
     56 int	bioopen(dev_t, int, int, struct proc *);
     57 
     58 int	bio_delegate_ioctl(struct bio_mapping *, u_long, void *);
     59 struct	bio_mapping *bio_lookup(char *);
     60 int	bio_validate(void *);
     61 
     62 const struct cdevsw bio_cdevsw = {
     63         bioopen, bioclose, noread, nowrite, bioioctl,
     64         nostop, notty, nopoll, nommap, nokqfilter, 0
     65 };
     66 
     67 
     68 void
     69 bioattach(int nunits)
     70 {
     71 }
     72 
     73 int
     74 bioopen(dev_t dev, int flags, int mode, struct proc *p)
     75 {
     76 	return (0);
     77 }
     78 
     79 int
     80 bioclose(dev_t dev, int flags, int mode, struct proc *p)
     81 {
     82 	return (0);
     83 }
     84 
     85 int
     86 bioioctl(dev_t dev, u_long cmd, caddr_t addr, int flag, struct  proc *p)
     87 {
     88 	struct bio_locate *locate;
     89 	struct bio_common *common;
     90 	char name[16];
     91 	int error;
     92 
     93 	switch(cmd) {
     94 	case BIOCLOCATE:
     95 	case BIOCINQ:
     96 	case BIOCDISK:
     97 	case BIOCVOL:
     98 	case BIOCBLINK:
     99 	case BIOCSETSTATE:
    100 	case BIOCALARM:
    101 		break;
    102 	default:
    103 		return ENOTTY;
    104 	}
    105 
    106 	switch (cmd) {
    107 	case BIOCLOCATE:
    108 		locate = (struct bio_locate *)addr;
    109 		error = copyinstr(locate->bl_name, name, 16, NULL);
    110 		if (error != 0)
    111 			return (error);
    112 		locate->bl_cookie = bio_lookup(name);
    113 		if (locate->bl_cookie == NULL)
    114 			return (ENOENT);
    115 		break;
    116 
    117 	default:
    118 		common = (struct bio_common *)addr;
    119 		if (!bio_validate(common->bc_cookie)) {
    120 			return (ENOENT);
    121 		}
    122 		error =  bio_delegate_ioctl(
    123 		    (struct bio_mapping *)common->bc_cookie, cmd, addr);
    124 		return (error);
    125 	}
    126 	return (0);
    127 }
    128 
    129 int
    130 bio_register(struct device *dev, int (*ioctl)(struct device *, u_long, caddr_t))
    131 {
    132 	struct bio_mapping *bm;
    133 
    134 	MALLOC(bm, struct bio_mapping *, sizeof *bm, M_DEVBUF, M_NOWAIT);
    135 	if (bm == NULL)
    136 		return (ENOMEM);
    137 	bm->bm_dev = dev;
    138 	bm->bm_ioctl = ioctl;
    139 	LIST_INSERT_HEAD(&bios, bm, bm_link);
    140 	return (0);
    141 }
    142 
    143 void
    144 bio_unregister(struct device *dev)
    145 {
    146 	struct bio_mapping *bm, *next;
    147 
    148 	for (bm = LIST_FIRST(&bios); bm != NULL; bm = next) {
    149 		next = LIST_NEXT(bm, bm_link);
    150 
    151 		if (dev == bm->bm_dev) {
    152 			LIST_REMOVE(bm, bm_link);
    153 			free(bm, M_DEVBUF);
    154 		}
    155 	}
    156 }
    157 
    158 struct bio_mapping *
    159 bio_lookup(char *name)
    160 {
    161 	struct bio_mapping *bm;
    162 
    163 	LIST_FOREACH(bm, &bios, bm_link) {
    164 		if (strcmp(name, bm->bm_dev->dv_xname) == 0) {
    165 			return (bm);
    166 		}
    167 	}
    168 	return (NULL);
    169 }
    170 
    171 int
    172 bio_validate(void *cookie)
    173 {
    174 	struct bio_mapping *bm;
    175 
    176 	LIST_FOREACH(bm, &bios, bm_link) {
    177 		if (bm == cookie) {
    178 			return (1);
    179 		}
    180 	}
    181 	return (0);
    182 }
    183 
    184 int
    185 bio_delegate_ioctl(struct bio_mapping *bm, u_long cmd, void *addr)
    186 {
    187 
    188 	return (bm->bm_ioctl(bm->bm_dev, cmd, addr));
    189 }
    190