2 * $Id: defgsc.c,v 1.1 2001/04/15 11:12:37 ant Exp $
3 * Copyright (c) 1997 by Matthew Jacob
5 * This software is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Library General Public
7 * License as published by the Free Software Foundation; version 2.
9 * This software is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Library General Public License for more details.
14 * You should have received a copy of the GNU Library General Public
15 * License along with this software; if not, write to the Free
16 * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18 * The author may be reached via electronic communications at
22 * or, via United States Postal Address
26 * San Francisco, CA, 94131
30 #include <sys/types.h>
31 #include <sys/cfgdb.h>
32 #include <sys/cfgodm.h>
35 static const char *triple = "type = '%s' AND class = '%s' AND subclass = '%s'";
36 static const char *utype =
37 "uniquetype = '%s' and connkey = '%s' and connwhere = '%s'";
40 err_exit(char exitcode)
42 odm_close_class(CuDv_CLASS);
43 odm_close_class(PdDv_CLASS);
53 char *class, *subclass, *type, *parent, *connect;
54 char sstring[256], lname[256];
55 char parent_loc[LOCSIZE];
60 int seqno, rc, errflg, c;
64 class = subclass = type = NULL;
65 parent = connect = NULL;
67 while ((c = getopt(a, v, "p:w:c:s:t:")) != EOF) {
103 * Verify that we have the right triple and all of it specified.
105 if (class == NULL || subclass == NULL || type == NULL) {
108 if (strcmp(class, "generic") ||
109 strcmp(subclass, "scsi") ||
110 strcmp(type, "gsc")) {
114 * Verify that a parent and a connection address was specified
116 if (parent == NULL || connect == NULL) {
123 if (odm_initialize() == -1) {
126 if (odm_lock("/etc/objrepos/config_lock", 0) == -1) {
130 * Get the PreDefined Device Object
132 (void) sprintf(sstring, triple, type, class, subclass);
133 rc = (int) odm_get_first(PdDv_CLASS, sstring, &PdDv);
136 } else if (rc == -1) {
141 * Open the Customized Device data base
143 if ((int) (cusdev = odm_open_class(CuDv_CLASS)) == -1) {
147 * Check parent device
149 (void) sprintf(sstring, "name = '%s'", parent);
150 rc = (int) odm_get_first(cusdev, sstring, &CuDv);
152 err_exit(E_NOCuDvPARENT);
153 } else if (rc == -1) {
156 (void) memset(parent_loc, 0, sizeof parent_loc);
157 (void) strncpy(parent_loc, CuDv.location, sizeof CuDv.location);
158 (void) sprintf(sstring, utype, CuDv.PdDvLn_Lvalue, subclass , connect);
159 rc = (int) odm_get_first(PdCn_CLASS, sstring, &PdCn);
161 err_exit(E_INVCONNECT);
162 } else if (rc == -1) {
170 /* generate logical name for device */
171 if ((seqno = genseq(PdDv.prefix)) < 0) {
172 err_exit(E_MAKENAME);
174 (void) sprintf(lname, "%s%d", PdDv.prefix, seqno);
175 (void) sprintf(sstring, "name = '%s'", lname);
176 rc = (int) odm_get_first(cusdev, sstring, &CuDv);
179 } else if (rc != 0) {
181 * Name already exists
185 /* Put device name into new CuDv object */
186 (void) strcpy(CuDv.name, lname);
189 * Fill in remainder of new customized device object
193 * Location codes for SCSI devices consists of 4 pairs of
194 * digits separated by hyphens. The first two pairs of digits
195 * identify the adapter's slot number. The last two pairs of
196 * digits identify the adapter connector number and the scsi
197 * connection address. As far as I can tell, there never
198 * is a non-zero value on the connector number for SCSI
201 * This is further complicated by a slight difference in
202 * this naming convention where Model 320 and Model 220
203 * machines define the parent (adapter) location as 00-00-0S,
204 * so we'll detect that variant.
206 * This can also be further complicated by the fact that
207 * connection addresses changed between AIX Release 3.2.X
208 * and AIX Release 4.X, where the trailing digit pair went
209 * from a simple two digits (Target ID adjacent to Logical
210 * Unit Number) to two digits separated by a comma. However,
211 * since that is an argument passed in via the command line,
212 * we can say, "Not our problem," and drive onwards.
214 if (strlen(parent_loc) <= 5) {
215 (void) sprintf(CuDv.location, "%s-00-%s", parent_loc, connect);
217 (void) sprintf(CuDv.location, "%s-%s", parent_loc, connect);
220 CuDv.status = DEFINED;
221 CuDv.chgstatus = PdDv.chgstatus;
222 strcpy(CuDv.ddins, PdDv.DvDr);
223 strcpy(CuDv.PdDvLn_Lvalue, PdDv.uniquetype);
224 strcpy(CuDv.parent, parent);
225 strcpy(CuDv.connwhere, connect);
227 if (odm_add_obj(cusdev, &CuDv) == -1) {
230 if (odm_close_class(CuDv_CLASS) == -1) {
231 err_exit(E_ODMCLOSE);
235 * Device defined successfully.
236 * Print device name to stdout with a space appended.
238 fprintf(stdout, "%s ", CuDv.name);
242 * Overrides for Emacs so that we follow Linus's tabbing style.
243 * Emacs will notice this stuff at the end of the file and automatically
244 * adjust the settings for this buffer only. This must remain at the end
246 * ---------------------------------------------------------------------------
249 * c-brace-imaginary-offset: 0
251 * c-argdecl-indent: 4
253 * c-continued-statement-offset: 4
254 * c-continued-brace-offset: 0