📄 cfggsc.c
字号:
/* * $Id: cfggsc.c,v 1.1 2001/04/15 11:12:37 ant Exp $ * Copyright (c) 1997 by Matthew Jacob * * This software is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; version 2. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public * License along with this software; if not, write to the Free * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * * The author may be reached via electronic communications at * * mjacob@feral.com * * or, via United States Postal Address * * Matthew Jacob * 1831 Castro Street * San Francisco, CA, 94131 */#include <stdio.h>#include <sys/scsi.h>#include <sys/types.h>#include <sys/errno.h>#include <sys/ioctl.h>#include <sys/devinfo.h>#include <sys/device.h>#include <sys/cfgodm.h>#include <cf.h>#include <sys/cfgdb.h>#include <fcntl.h>#include <sys/sysconfig.h>#include <sys/errno.h>#include <sys/device.h>#include <sys/mode.h>#include "gscdds.h"extern mid_t loadext(char *, int, int);static int verbose;static struct gsc_ddsinfo ddsinfo;int main(int a, char **v);static void check_add_sockets(dev_t, int, char *, char *);static int has_driver_get_vpd(char *, int, char *);#define MKNOD_MODE S_IFCHR|S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH#define vprintf if (verbose) printfstatic voiderr_exit(char exitcode){ odm_close_class(CuDv_CLASS); odm_close_class(PdDv_CLASS); odm_terminate(); exit(exitcode);}intmain(int a, char **v){ extern char *optarg; char sstring[256], bufname[256], conns[NAMESIZE], *ptr, *lname; struct Class *cprp, *cusdev, *predev; struct CuDvDr dpr, *dprp; struct CuDv parobj, cusobj, hdobj, *xprp; struct PdDv preobj; struct CuAt *attrobj; int rc, c, errflg, ipl_phase, unit, munit, howmany, lun, domake; dev_t ctl; long major; int *mlist; mid_t kmid; struct cfg_dd dd; lname = NULL; errflg = 0; ipl_phase = RUNTIME_CFG; (void) memset((void *) &ddsinfo, 0, sizeof ddsinfo); while ((c = getopt(a, v, "l:12v")) != EOF) { switch (c) { case 'l': if (lname != NULL) errflg++; lname = optarg; break; case 'v': verbose++; break; case '1': if (ipl_phase != RUNTIME_CFG) errflg++; ipl_phase = PHASE1; break; case '2': if (ipl_phase != RUNTIME_CFG) errflg++; ipl_phase = PHASE2; break; default: errflg++; } } if (errflg) exit (E_ARGS); if (lname == NULL) exit(E_LNAME); if (odm_initialize() == -1) { return (E_ODMINIT); } /* lock the database */ if (odm_lock("/etc/objrepos/config_lock",0) == -1) err_exit(E_ODMLOCK); /* open customized devices object class */ if ((int)(cusdev = odm_open_class(CuDv_CLASS)) == -1) err_exit(E_ODMOPEN); /* search for customized object with this logical name */ sprintf(sstring, "name = '%s'", lname); rc = (int) odm_get_first(cusdev, sstring, &cusobj); if (rc == 0) { /* No CuDv object with this name */ err_exit(E_NOCuDv); } else if (rc == -1) { /* ODM failure */ err_exit(E_ODMGET); } /* open predefined devices object class */ if ((int)(predev = odm_open_class(PdDv_CLASS)) == -1) err_exit(E_ODMOPEN); /* get predefined device object for this logical name */ sprintf(sstring, "uniquetype = '%s'", cusobj.PdDvLn_Lvalue); rc = (int)odm_get_first(predev, sstring, &preobj); if (rc == 0) { /* No PdDv object for this device */ err_exit(E_NOPdDv); } else if (rc == -1) { /* ODM failure */ err_exit(E_ODMGET); } /* close predefined device object class */ if (odm_close_class(predev) == -1) err_exit(E_ODMCLOSE); if (ipl_phase != RUNTIME_CFG) setleds(preobj.led); /* * Now, if the device is already configured, we're * pretty much done. */ if (cusobj.status == AVAILABLE) { /* close customized device object class */ if (odm_close_class(cusdev) == -1) err_exit(E_ODMCLOSE); odm_terminate(); return(E_OK); } if (cusobj.status != DEFINED) { vprintf("bad state: %d\n", cusobj.status); err_exit(E_DEVSTATE); } /* get the device's parent object */ sprintf(sstring, "name = '%s'", cusobj.parent); rc = (int) odm_get_first(cusdev, sstring, &parobj); if (rc == 0) { /* Parent device not in CuDv */ err_exit(E_NOCuDvPARENT); } else if (rc == -1) { /* ODM failure */ err_exit(E_ODMGET); } /* Parent MUST be available to continue */ if (parobj.status != AVAILABLE) err_exit(E_PARENTSTATE); /* make sure that no other devices are configured */ /* at this location */ sprintf(sstring, "parent = '%s' AND location='%s' AND status=%d", cusobj.parent, cusobj.location, AVAILABLE); rc = (int) odm_get_first(cusdev, sstring, &cusobj); if (rc == -1) { /* odm failure */ err_exit(E_ODMGET); } else if (rc) { /* Error: device config'd at this location */ err_exit(E_AVAILCONNECT); } memcpy(conns, cusobj.location, NAMESIZE); vprintf("now fool with luns: location is %s\n", conns); ptr = conns; while (*ptr && ptr < &conns[NAMESIZE]) ptr++; ptr--; if (ptr < &conns[1]) { err_exit(E_BADATTR); } lun = *ptr - '0'; vprintf("I see lun %d\n", lun); if (lun < 0 || lun >= 8) err_exit(E_INVCONNECT); ddsinfo.lun = lun; /* * Generate Target */ if (ptr[-1] == ',') { *(--ptr) = 0; } else { *ptr = 0; } while (ptr > conns && *ptr != '-') ptr--; if (*ptr == '-') ptr++; ddsinfo.target = strtol(ptr, (char **) NULL, 0); vprintf("I see tgt %d ptr = %d\n", ddsinfo.target, ptr - conns); /* * Generate dev_t for adapter */ cprp = odm_open_class(CuDvDr_CLASS) ; sprintf(sstring, "value3 = %s", cusobj.parent); rc = (int) odm_get_obj(cprp, sstring, &dpr, TRUE); if (rc == 0) { err_exit(E_NOCuDvPARENT); } else if (rc == -1) { err_exit(E_ODMGET); } ddsinfo.busid = (dev_t) makedev(atoi(dpr.value1), atoi(dpr.value2)); vprintf("I see %d.%d for connecting adapter\n", major(ddsinfo.busid), minor(ddsinfo.busid)); /* * Get unit number out of logical name */ ptr = lname; ptr += strlen(preobj.prefix); unit = atoi(ptr); vprintf("I see %d as unit\n", unit); /* * Okay, now that we have the pertinent information that we'll * need (adapter dev_t, device type, target, lbits, shareable, * unit number), we can look into actually loading/configuring the * current driver. */ (void) sprintf(bufname, "/dev/%s", lname); /* * Get or generate major number.. */ if ((major = (long) genmajor(preobj.DvDr)) == -1) { odm_terminate(); return (E_MAJORNO); } vprintf("major is %d\n", major); /* * Let's see if this is the first time through. If it's * the first time through, getminor will return NULL * or won't have any minors in the list. */ mlist = getminor(major, &howmany, preobj.DvDr); vprintf("getminor: %x and howmany %d for %s\n", mlist, howmany, preobj.DvDr); domake = 1; if (mlist != NULL && howmany != 0) { /* * We have a list of minors already. * See if we already have the minor * we want defined. */ for (c = 0; c < howmany; c++) { if (mlist[c] == unit) { vprintf("unit %d already has minor\n", unit); domake = 0; break; } } } if (domake) { (void) unlink(bufname); /* * Now create the minor number that will match the unit number. * We really don't care whether genminor succeeds, since * we've alreay unlinked the device node. */ mlist = genminor(preobj.DvDr, major, unit, 1, 1, 1); if (mlist == (long *) NULL) { err_exit(E_MINORNO); } vprintf("making %s as %d.%d with minor returned as %d\n", bufname, major, unit, *mlist); if (mknod(bufname, MKNOD_MODE, makedev(major, unit))) { err_exit(E_MKSPECIAL); } } else { (void) mknod(bufname, MKNOD_MODE, makedev(major, unit)); } /* * Load the driver.... */ kmid = loadext(preobj.DvDr, TRUE, FALSE); if (!kmid) { err_exit(E_LOADEXT); } /* * And configure the driver... */ dd.kmid = kmid; dd.devno = makedev(major, unit); dd.cmd = CFG_INIT; dd.ddsptr = (caddr_t) &ddsinfo; dd.ddslen = sizeof (ddsinfo); if (sysconfig(SYS_CFGDD, &dd, sizeof (dd)) == CONF_FAIL) { int saverr = errno; /* * Unload driver... */ (void) loadext(preobj.DvDr, FALSE, FALSE); switch(saverr) { case ENODEV: err_exit(E_WRONGDEVICE); /* NOTREACHED */ break; case EBUSY: err_exit(E_AVAILCONNECT); /* NOTREACHED */ break; case EINVAL: default: err_exit(E_CFGINIT); /* NOTREACHED */ break; } } /* now mark the device as available */ cusobj.status = AVAILABLE; if (odm_change_obj(CuDv_CLASS, &cusobj) == -1) { /* * Unconfigure driver (for this instance)... */ dd.kmid = 0; dd.ddsptr = (caddr_t) NULL; dd.ddslen = (int ) 0; dd.cmd = CFG_TERM; (void) sysconfig(SYS_CFGDD, &dd, sizeof (dd)); /* * Unload driver... */ (void) loadext(preobj.DvDr, FALSE, FALSE); err_exit (E_ODMUPDATE); } (void) odm_terminate(); return (E_OK);}/* * Overrides for Emacs so that we follow Linus's tabbing style. * Emacs will notice this stuff at the end of the file and automatically * adjust the settings for this buffer only. This must remain at the end * of the file. * --------------------------------------------------------------------------- * Local variables: * c-indent-level: 4 * c-brace-imaginary-offset: 0 * c-brace-offset: -4 * c-argdecl-indent: 4 * c-label-offset: -4 * c-continued-statement-offset: 4 * c-continued-brace-offset: 0 * End: */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -