1*56832Sralph /*- 2*56832Sralph * Copyright (c) 1992 The Regents of the University of California. 3*56832Sralph * All rights reserved. 4*56832Sralph * 5*56832Sralph * This code is derived from software contributed to Berkeley by 6*56832Sralph * Ralph Campbell. 7*56832Sralph * 8*56832Sralph * %sccs.include.redist.c% 9*56832Sralph * 10*56832Sralph * @(#)devopen.c 7.1 (Berkeley) 11/15/92 11*56832Sralph */ 12*56832Sralph 13*56832Sralph #include <stand/stand.h> 14*56832Sralph 15*56832Sralph /* 16*56832Sralph * Decode the string 'fname', open the device and return the remaining 17*56832Sralph * file name if any. 18*56832Sralph */ 19*56832Sralph devopen(f, fname, file) 20*56832Sralph struct open_file *f; 21*56832Sralph char *fname; 22*56832Sralph char **file; /* out */ 23*56832Sralph { 24*56832Sralph register char *cp; 25*56832Sralph register char *ncp; 26*56832Sralph register struct devsw *dp; 27*56832Sralph register int c, i; 28*56832Sralph int ctlr = 0, unit = 0, part = 0; 29*56832Sralph char namebuf[20]; 30*56832Sralph int rc; 31*56832Sralph 32*56832Sralph cp = fname; 33*56832Sralph ncp = namebuf; 34*56832Sralph 35*56832Sralph /* look for a string like '5/rz0/vmunix' or '5/rz3f/vmunix */ 36*56832Sralph if ((c = *cp) >= '0' && c <= '9') { 37*56832Sralph ctlr = c - '0'; 38*56832Sralph /* skip the '/' */ 39*56832Sralph if (*++cp != '/') 40*56832Sralph return (ENXIO); 41*56832Sralph cp++; 42*56832Sralph while ((c = *cp) != '\0') { 43*56832Sralph if (c == '/') 44*56832Sralph break; 45*56832Sralph if (c >= '0' && c <= '9') { 46*56832Sralph /* read unit number */ 47*56832Sralph unit = c - '0'; 48*56832Sralph 49*56832Sralph /* look for a partition */ 50*56832Sralph if ((c = *++cp) >= 'a' && c <= 'h') { 51*56832Sralph part = c - 'a'; 52*56832Sralph c = *++cp; 53*56832Sralph } 54*56832Sralph if (c != '/') 55*56832Sralph return (ENXIO); 56*56832Sralph break; 57*56832Sralph } 58*56832Sralph if (ncp < namebuf + sizeof(namebuf) - 1) 59*56832Sralph *ncp++ = c; 60*56832Sralph cp++; 61*56832Sralph } 62*56832Sralph } else { 63*56832Sralph /* expect a string like 'rz(0,0,0)vmunix' */ 64*56832Sralph while ((c = *cp) != '\0') { 65*56832Sralph if (c == '(') { 66*56832Sralph cp++; 67*56832Sralph break; 68*56832Sralph } 69*56832Sralph if (ncp < namebuf + sizeof(namebuf) - 1) 70*56832Sralph *ncp++ = c; 71*56832Sralph cp++; 72*56832Sralph } 73*56832Sralph 74*56832Sralph /* get controller number */ 75*56832Sralph if ((c = *cp) >= '0' && c <= '9') { 76*56832Sralph ctlr = c - '0'; 77*56832Sralph c = *++cp; 78*56832Sralph } 79*56832Sralph 80*56832Sralph if (c == ',') { 81*56832Sralph /* get SCSI device number */ 82*56832Sralph if ((c = *++cp) >= '0' && c <= '9') { 83*56832Sralph unit = c - '0'; 84*56832Sralph c = *++cp; 85*56832Sralph } 86*56832Sralph 87*56832Sralph if (c == ',') { 88*56832Sralph /* get partition number */ 89*56832Sralph if ((c = *++cp) >= '0' && c <= '9') { 90*56832Sralph part = c - '0'; 91*56832Sralph c = *++cp; 92*56832Sralph } 93*56832Sralph } 94*56832Sralph } 95*56832Sralph if (c != ')') 96*56832Sralph return (ENXIO); 97*56832Sralph cp++; 98*56832Sralph } 99*56832Sralph *ncp = '\0'; 100*56832Sralph 101*56832Sralph for (dp = devsw, i = 0; i < ndevs; dp++, i++) 102*56832Sralph if (dp->dv_name && strcmp(namebuf, dp->dv_name) == 0) 103*56832Sralph goto fnd; 104*56832Sralph printf("Unknown device '%s'\nKnown devices are:", namebuf); 105*56832Sralph for (dp = devsw, i = 0; i < ndevs; dp++, i++) 106*56832Sralph if (dp->dv_name) 107*56832Sralph printf(" %s", dp->dv_name); 108*56832Sralph printf("\n"); 109*56832Sralph return (ENXIO); 110*56832Sralph 111*56832Sralph fnd: 112*56832Sralph rc = (dp->dv_open)(f, ctlr, unit, part); 113*56832Sralph if (rc) 114*56832Sralph return (rc); 115*56832Sralph 116*56832Sralph f->f_dev = dp; 117*56832Sralph if (file && *cp != '\0') 118*56832Sralph *file = cp; 119*56832Sralph return (0); 120*56832Sralph } 121