122514Sdarrenr/* $NetBSD: devopen.c,v 1.6 2005/12/11 12:16:20 christos Exp $ */ 253024Sguido 322514Sdarrenr/*- 480486Sdarrenr * Copyright (c) 1992, 1993 522514Sdarrenr * The Regents of the University of California. All rights reserved. 622514Sdarrenr * 722514Sdarrenr * This code is derived from software contributed to Berkeley by 822514Sdarrenr * Ralph Campbell. 922514Sdarrenr * 1022514Sdarrenr * Redistribution and use in source and binary forms, with or without 1122514Sdarrenr * modification, are permitted provided that the following conditions 1222514Sdarrenr * are met: 1322514Sdarrenr * 1. Redistributions of source code must retain the above copyright 1422514Sdarrenr * notice, this list of conditions and the following disclaimer. 1522514Sdarrenr * 2. Redistributions in binary form must reproduce the above copyright 1622514Sdarrenr * notice, this list of conditions and the following disclaimer in the 1722514Sdarrenr * documentation and/or other materials provided with the distribution. 1822514Sdarrenr * 3. Neither the name of the University nor the names of its contributors 1922514Sdarrenr * may be used to endorse or promote products derived from this software 2022514Sdarrenr * without specific prior written permission. 2122514Sdarrenr * 2222514Sdarrenr * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 2322514Sdarrenr * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 2422514Sdarrenr * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 2522514Sdarrenr * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 2622514Sdarrenr * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 2722514Sdarrenr * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 2822514Sdarrenr * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 2922514Sdarrenr * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 3022514Sdarrenr * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 3122514Sdarrenr * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 3222514Sdarrenr * SUCH DAMAGE. 3322514Sdarrenr * 3422514Sdarrenr * @(#)devopen.c 8.1 (Berkeley) 6/10/93 3522514Sdarrenr */ 3622514Sdarrenr 3731183Speter#include <lib/libsa/stand.h> 3880486Sdarrenr 3922514Sdarrenr/* 4022514Sdarrenr * Decode the string 'fname', open the device and return the remaining 4122514Sdarrenr * file name if any. 4222514Sdarrenr */ 4322514Sdarrenrint 4422514Sdarrenrdevopen(struct open_file *f, const char *fname, char **file) 4522514Sdarrenr /* file: out */ 4622514Sdarrenr{ 4722514Sdarrenr register char *cp; 4822514Sdarrenr register char *ncp; 4922514Sdarrenr register struct devsw *dp; 5022514Sdarrenr#if 0 5122514Sdarrenr register int c, i; 5222514Sdarrenr#endif 5322514Sdarrenr int ctlr = 0, unit = 0, part = 0; 5422514Sdarrenr char namebuf[20]; 5522514Sdarrenr int rc; 5622514Sdarrenr 5722514Sdarrenr cp = (char *)fname; 5822514Sdarrenr ncp = namebuf; 5922514Sdarrenr 6022514Sdarrenr#if 0 6122514Sdarrenr /* look for a string like '5/rz0/vmunix' or '5/rz3f/vmunix */ 6222514Sdarrenr if ((c = *cp) >= '0' && c <= '9') { 6322514Sdarrenr ctlr = c - '0'; 6422514Sdarrenr /* skip the '/' */ 6522514Sdarrenr if (*++cp != '/') 6622514Sdarrenr return (ENXIO); 6722514Sdarrenr cp++; 6822514Sdarrenr while ((c = *cp) != '\0') { 6922514Sdarrenr if (c == '/') 7022514Sdarrenr break; 7122514Sdarrenr if (c >= '0' && c <= '9') { 7222514Sdarrenr /* read unit number */ 7322514Sdarrenr unit = c - '0'; 7422514Sdarrenr 7522514Sdarrenr /* look for a partition */ 7622514Sdarrenr if ((c = *++cp) >= 'a' && c <= 'h') { 7722514Sdarrenr part = c - 'a'; 7822514Sdarrenr c = *++cp; 7922514Sdarrenr } 8022514Sdarrenr if (c != '/') 8122514Sdarrenr return (ENXIO); 8222514Sdarrenr break; 8322514Sdarrenr } 8422514Sdarrenr if (ncp < namebuf + sizeof(namebuf) - 1) 8522514Sdarrenr *ncp++ = c; 8622514Sdarrenr cp++; 8722514Sdarrenr } 8822514Sdarrenr *ncp = '\0'; 8922514Sdarrenr /* 9022514Sdarrenr * XXX 9122514Sdarrenr * pulling strchr from the C library, should pull from libkern. 9222514Sdarrenr */ 9322514Sdarrenr } else if (strchr(cp, '(')) { 9422514Sdarrenr /* expect a string like 'rz(0,0,0)vmunix' */ 9522514Sdarrenr while ((c = *cp) != '\0') { 9622514Sdarrenr if (c == '(') { 9722514Sdarrenr cp++; 9822514Sdarrenr break; 9922514Sdarrenr } 10022514Sdarrenr if (ncp < namebuf + sizeof(namebuf) - 1) 10122514Sdarrenr *ncp++ = c; 10222514Sdarrenr cp++; 10322514Sdarrenr } 10422514Sdarrenr 10522514Sdarrenr /* get controller number */ 10622514Sdarrenr if ((c = *cp) >= '0' && c <= '9') { 10722514Sdarrenr ctlr = c - '0'; 10822514Sdarrenr c = *++cp; 10922514Sdarrenr } 11022514Sdarrenr 11122514Sdarrenr if (c == ',') { 11222514Sdarrenr /* get SCSI device number */ 11322514Sdarrenr if ((c = *++cp) >= '0' && c <= '9') { 11422514Sdarrenr unit = c - '0'; 11522514Sdarrenr c = *++cp; 11622514Sdarrenr } 11722514Sdarrenr 11822514Sdarrenr if (c == ',') { 11922514Sdarrenr /* get partition number */ 12022514Sdarrenr if ((c = *++cp) >= '0' && c <= '9') { 12122514Sdarrenr part = c - '0'; 12222514Sdarrenr c = *++cp; 12322514Sdarrenr } 12422514Sdarrenr } 12522514Sdarrenr } 12622514Sdarrenr if (c != ')') 12722514Sdarrenr return (ENXIO); 12822514Sdarrenr cp++; 12922514Sdarrenr *ncp = '\0'; 13022514Sdarrenr } else { 13122514Sdarrenr#endif 13222514Sdarrenr dp = devsw; 13322514Sdarrenr ctlr = unit = part = 0; 13422514Sdarrenr goto fnd; 13522514Sdarrenr#if 0 13622514Sdarrenr } 13722514Sdarrenr 13822514Sdarrenr for (dp = devsw, i = 0; i < ndevs; dp++, i++) 13922514Sdarrenr if (dp->dv_name && strcmp(namebuf, dp->dv_name) == 0) 14022514Sdarrenr goto fnd; 14122514Sdarrenr printf("Unknown device '%s'\nKnown devices are:", namebuf); 14222514Sdarrenr for (dp = devsw, i = 0; i < ndevs; dp++, i++) 14322514Sdarrenr if (dp->dv_name) 14422514Sdarrenr printf(" %s", dp->dv_name); 14522514Sdarrenr printf("\n"); 14622514Sdarrenr return (ENXIO); 14722514Sdarrenr#endif 14822514Sdarrenr 14922514Sdarrenrfnd: 15022514Sdarrenr rc = (dp->dv_open)(f, ctlr, unit, part); 15122514Sdarrenr if (rc) 15222514Sdarrenr return (rc); 15322514Sdarrenr 15422514Sdarrenr f->f_dev = dp; 15522514Sdarrenr if (file && *cp != '\0') 15622514Sdarrenr *file = cp; 15722514Sdarrenr return (0); 15822514Sdarrenr} 15922514Sdarrenr