156832Sralph /*- 2*63224Sbostic * Copyright (c) 1992, 1993 3*63224Sbostic * The Regents of the University of California. All rights reserved. 456832Sralph * 556832Sralph * This code is derived from software contributed to Berkeley by 656832Sralph * Ralph Campbell. 756832Sralph * 856832Sralph * %sccs.include.redist.c% 956832Sralph * 10*63224Sbostic * @(#)devopen.c 8.1 (Berkeley) 06/10/93 1156832Sralph */ 1256832Sralph 1356832Sralph #include <stand/stand.h> 1456832Sralph 1556832Sralph /* 1656832Sralph * Decode the string 'fname', open the device and return the remaining 1756832Sralph * file name if any. 1856832Sralph */ 1956832Sralph devopen(f, fname, file) 2056832Sralph struct open_file *f; 2156832Sralph char *fname; 2256832Sralph char **file; /* out */ 2356832Sralph { 2456832Sralph register char *cp; 2556832Sralph register char *ncp; 2656832Sralph register struct devsw *dp; 2756832Sralph register int c, i; 2856832Sralph int ctlr = 0, unit = 0, part = 0; 2956832Sralph char namebuf[20]; 3056832Sralph int rc; 3156832Sralph 3256832Sralph cp = fname; 3356832Sralph ncp = namebuf; 3456832Sralph 3556832Sralph /* look for a string like '5/rz0/vmunix' or '5/rz3f/vmunix */ 3656832Sralph if ((c = *cp) >= '0' && c <= '9') { 3756832Sralph ctlr = c - '0'; 3856832Sralph /* skip the '/' */ 3956832Sralph if (*++cp != '/') 4056832Sralph return (ENXIO); 4156832Sralph cp++; 4256832Sralph while ((c = *cp) != '\0') { 4356832Sralph if (c == '/') 4456832Sralph break; 4556832Sralph if (c >= '0' && c <= '9') { 4656832Sralph /* read unit number */ 4756832Sralph unit = c - '0'; 4856832Sralph 4956832Sralph /* look for a partition */ 5056832Sralph if ((c = *++cp) >= 'a' && c <= 'h') { 5156832Sralph part = c - 'a'; 5256832Sralph c = *++cp; 5356832Sralph } 5456832Sralph if (c != '/') 5556832Sralph return (ENXIO); 5656832Sralph break; 5756832Sralph } 5856832Sralph if (ncp < namebuf + sizeof(namebuf) - 1) 5956832Sralph *ncp++ = c; 6056832Sralph cp++; 6156832Sralph } 6256832Sralph } else { 6356832Sralph /* expect a string like 'rz(0,0,0)vmunix' */ 6456832Sralph while ((c = *cp) != '\0') { 6556832Sralph if (c == '(') { 6656832Sralph cp++; 6756832Sralph break; 6856832Sralph } 6956832Sralph if (ncp < namebuf + sizeof(namebuf) - 1) 7056832Sralph *ncp++ = c; 7156832Sralph cp++; 7256832Sralph } 7356832Sralph 7456832Sralph /* get controller number */ 7556832Sralph if ((c = *cp) >= '0' && c <= '9') { 7656832Sralph ctlr = c - '0'; 7756832Sralph c = *++cp; 7856832Sralph } 7956832Sralph 8056832Sralph if (c == ',') { 8156832Sralph /* get SCSI device number */ 8256832Sralph if ((c = *++cp) >= '0' && c <= '9') { 8356832Sralph unit = c - '0'; 8456832Sralph c = *++cp; 8556832Sralph } 8656832Sralph 8756832Sralph if (c == ',') { 8856832Sralph /* get partition number */ 8956832Sralph if ((c = *++cp) >= '0' && c <= '9') { 9056832Sralph part = c - '0'; 9156832Sralph c = *++cp; 9256832Sralph } 9356832Sralph } 9456832Sralph } 9556832Sralph if (c != ')') 9656832Sralph return (ENXIO); 9756832Sralph cp++; 9856832Sralph } 9956832Sralph *ncp = '\0'; 10056832Sralph 10156832Sralph for (dp = devsw, i = 0; i < ndevs; dp++, i++) 10256832Sralph if (dp->dv_name && strcmp(namebuf, dp->dv_name) == 0) 10356832Sralph goto fnd; 10456832Sralph printf("Unknown device '%s'\nKnown devices are:", namebuf); 10556832Sralph for (dp = devsw, i = 0; i < ndevs; dp++, i++) 10656832Sralph if (dp->dv_name) 10756832Sralph printf(" %s", dp->dv_name); 10856832Sralph printf("\n"); 10956832Sralph return (ENXIO); 11056832Sralph 11156832Sralph fnd: 11256832Sralph rc = (dp->dv_open)(f, ctlr, unit, part); 11356832Sralph if (rc) 11456832Sralph return (rc); 11556832Sralph 11656832Sralph f->f_dev = dp; 11756832Sralph if (file && *cp != '\0') 11856832Sralph *file = cp; 11956832Sralph return (0); 12056832Sralph } 121