4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
22 * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
23 * Use is subject to license terms.
28 * I18N message number ranges
29 * This file: 4500 - 4999
30 * Shared common messages: 1 - 1999
46 #include <sys/exechdr.h>
49 #include <sys/types.h>
50 #include <sys/fibre-channel/fcio.h>
51 #include <sys/socalreg.h>
53 * The following define is not to
54 * include sys/fc4/fcal_linkapp.h
55 * file from sys/socalio.h, since it
56 * has same structure defines as in
57 * sys/fibre-channel/fcio.h.
59 #define _SYS_FC4_FCAL_LINKAPP_H
60 #include <sys/socalio.h>
70 #define FEPROM_SIZE 256*1024
71 #define FEPROM_MAX_PROGRAM 25
72 #define FEPROM_MAX_ERASE 1000
73 #define FEPROM_READ_MEMORY 0x00
74 #define FEPROM_ERASE 0x20
75 #define FEPROM_ERASE_VERIFY 0xa0
76 #define FEPROM_PROGRAM 0x40
77 #define FEPROM_PROGRAM_VERIFY 0xc0
78 #define FEPROM_RESET 0xff
83 #define PROM_SIZ 0x20010
86 #define MAX_WAIT_TIME 30
89 * The next define is to work around a problem with sbusmem driver not
90 * able to round up mmap() requests that are not around page boundaries.
92 #define PROM_SIZ_ROUNDED 0x22000
93 #define SAMPLE_SIZ 0x100
95 #define REG_OFFSET 0x20000
97 #define FEPROM_WWN_OFFSET 0x3fe00
99 #define FEPROM_SUN_WWN 0x50200200
102 * We'll leave this on leadville, as the onboard
103 * isn't allowed to be zapped by luxadm
106 #define ONBOARD_SOCAL "SUNW,socal@d"
108 #define SOCAL_STR "SUNW,socal"
109 #define SOCAL_STR_LEN 10
112 static uchar_t buffer
[FEPROM_SIZE
];
114 static char sbus_list
[HBA_MAX
][PATH_MAX
];
115 static char sbussoc_list
[HBA_MAX
][PATH_MAX
];
116 static char bootpath
[PATH_MAX
];
117 static char version
[MAXNAMELEN
];
119 static uint_t
getsbuslist(void);
120 static int load_file(char *, caddr_t
, volatile socal_reg_t
*);
121 static void usec_delay(int);
122 static void getbootdev(unsigned int);
123 static void getsocpath(char *, int *);
124 static int loadsocpath(const char *, int *);
125 static int warn(void);
126 static int findversion(int, uchar_t
*);
127 static int write_feprom(uchar_t
*, uchar_t
*, volatile socal_reg_t
*);
128 static int feprom_erase(volatile uchar_t
*, volatile socal_reg_t
*);
130 static struct exec exec
;
133 fcal_update(unsigned int verbose
, char *file
)
136 int fd
, strfound
= 0, retval
= 0;
137 int fbuf_idx
, fd1
, bytes_read
;
143 volatile socal_reg_t
*regs
;
144 char *slotname
, socal
[MAXNAMELEN
];
151 if ((fd1
= open(file
, O_RDONLY
)) == -1) {
152 (void) fprintf(stderr
,
154 "Error: open() failed on file "
159 * We will just make a check to see if it the file
160 * has the "SUNW,socal" strings in it
161 * We cannot use strstr() here because we are operating on
162 * binary data and so is very likely to have embedded NULLs
164 while (!strfound
&& ((bytes_read
= read(fd1
,
165 fbuf
, BUFSIZ
)) > 0)) {
166 for (fbuf_idx
= 0; fbuf_idx
< bytes_read
;
168 /* First check for the SUNW,socal string */
169 if (strncmp((fbuf
+ fbuf_idx
), SOCAL_STR
,
170 SOCAL_STR_LEN
) == 0) {
180 (void) fprintf(stderr
,
182 "Error: %s is not a "
183 "FC100/S Fcode file\n"), file
);
189 * Get count of, and names of SBus slots using the SBus memory
192 (void) getbootdev(verbose
);
193 if (getenv("_LUX_D_DEBUG") != NULL
) {
194 (void) fprintf(stdout
, " Bootpath: %s\n", bootpath
);
197 numslots
= getsbuslist();
198 (void) fprintf(stdout
,
199 MSGSTR(4503, "\n Found Path to %d FC100/S Cards\n"), numslots
);
201 for (i
= 0; i
< numslots
; i
++) {
204 * Open SBus memory for this slot.
206 slotname
= &sbus_list
[i
][0];
207 if (fflag
&& (strcmp(slotname
, bootpath
) == 0)) {
208 (void) fprintf(stderr
,
209 MSGSTR(4504, " Ignoring %s (bootpath)\n"), slotname
);
213 (void) sprintf(socal
, "%s:0", &sbussoc_list
[i
][0]);
215 if ((fd
= open(socal
, O_RDWR
)) < 0) {
216 (void) sprintf(socal
, "%s:1", &sbussoc_list
[i
][0]);
217 if ((fd
= open(socal
, O_RDWR
)) < 0) {
218 (void) fprintf(stderr
,
219 MSGSTR(4505, "Could not open %s\n"),
220 &sbussoc_list
[i
][0]);
221 (void) fprintf(stderr
,
222 MSGSTR(4506, "Ignoring %s\n"),
223 &sbussoc_list
[i
][0]);
232 (void) fprintf(stdout
, "\n ");
233 (void) fprintf(stdout
,
234 MSGSTR(85, "Opening %s\n"), slotname
);
237 fd
= open(slotname
, O_RDWR
);
240 perror(MSGSTR(4507, "open of slotname"));
246 * Mmap that SBus memory into my memory space.
248 addr
= mmap((caddr_t
)0, PROM_SIZ_ROUNDED
, PROT_READ
|PROT_WRITE
,
251 if (addr
== MAP_FAILED
) {
252 perror(MSGSTR(46, "mmap"));
258 if ((int)addr
== -1) {
259 perror(MSGSTR(46, "mmap"));
265 regs
= (socal_reg_t
*)((int)addr
+ REG_OFFSET
);
267 (void) fprintf(stdout
,
268 MSGSTR(4508, "\n Device: %s\n"),
269 &sbussoc_list
[i
][0]);
275 retval
+= load_file(file
, addr
, regs
);
277 if (findversion(i
, (uchar_t
*)&version
[0]) == FOUND
) {
278 (void) fprintf(stdout
,
280 " Detected FC100/S Version: %s\n"), version
);
284 if (munmap(addr
, PROM_SIZ
) == -1) {
285 perror(MSGSTR(4510, "munmap"));
292 (void) fprintf(stdout
, " ");
293 (void) fprintf(stdout
, MSGSTR(125, "Complete\n"));
298 findversion(int index
, uchar_t
*version
)
302 struct socal_fm_version
*buffer
;
303 char socal
[MAXNAMELEN
];
309 char fw_rev
[FC_FW_REV_SIZE
+ 1];
312 if ((dev_type
= g_get_path_type(&sbussoc_list
[index
][0])) == 0) {
313 return (L_INVALID_PATH
);
317 if (dev_type
& FC4_FCA_MASK
) {
318 P_DPRINTF("findversion: found an FC4 path\n");
319 (void) sprintf(socal
, "%s:0", &sbussoc_list
[index
][0]);
320 if ((fd
= open(socal
, O_RDWR
)) < 0) {
321 (void) sprintf(socal
, "%s:1", &sbussoc_list
[index
][0]);
322 if ((fd
= open(socal
, O_RDWR
)) < 0) {
323 (void) fprintf(stderr
,
324 MSGSTR(4511, "Could not open %s\n"),
325 &sbussoc_list
[index
][0]);
330 if ((buffer
= (struct socal_fm_version
*)malloc(
331 sizeof (struct socal_fm_version
))) == NULL
) {
332 (void) fprintf(stderr
, MSGSTR(10,
333 " Error: Unable to allocate memory."));
334 (void) fprintf(stderr
, "\n");
339 buffer
->fcode_ver
= (char *)version
;
340 buffer
->mcode_ver
= mcode_ver
;
341 buffer
->prom_ver
= prom_ver
;
342 buffer
->fcode_ver_len
= MAXNAMELEN
- 1;
343 buffer
->mcode_ver_len
= 100;
344 buffer
->prom_ver_len
= 100;
346 if (ioctl(fd
, FCIO_FCODE_MCODE_VERSION
, buffer
) < 0) {
347 (void) fprintf(stderr
, MSGSTR(4512,
348 "fcal_s_download: could not get"
349 " fcode version.\n"));
354 version
[buffer
->fcode_ver_len
] = '\0';
357 } else if (dev_type
& FC_FCA_MASK
) {
359 * Get the fcode and prom's fw version
360 * using new ioctls. Currently, we pass
361 * only the fcode version to the calling function
362 * and ignore the FW version (using the existing
363 * implementation). The function definition
364 * might be changed in future to pass both the
365 * fcode and FW revisions to the calling function, if
366 * needed by the calling function.
368 P_DPRINTF("findversion: found an FC path\n");
369 (void) sprintf(fp
, "%s/fp@0,0:devctl",
370 &sbussoc_list
[index
][0]);
371 if ((fd
= open(fp
, O_RDWR
)) < 0) {
372 (void) sprintf(fp
, "%s/fp@1,0:devctl",
373 &sbussoc_list
[index
][0]);
374 if ((fd
= open(fp
, O_RDWR
)) < 0) {
375 (void) fprintf(stderr
,
376 MSGSTR(4511, "Could not open %s\n"),
377 &sbussoc_list
[index
][0]);
382 /* Get the fcode version */
383 bzero(version
, sizeof (version
));
384 fcio
.fcio_cmd
= FCIO_GET_FCODE_REV
;
385 /* Information read operation */
386 fcio
.fcio_xfer
= FCIO_XFER_READ
;
387 fcio
.fcio_obuf
= (caddr_t
)version
;
388 fcio
.fcio_olen
= MAXNAMELEN
;
390 for (ntries
= 0; ntries
< MAX_RETRIES
; ntries
++) {
391 if (ioctl(fd
, FCIO_CMD
, &fcio
) != 0) {
392 if ((errno
== EAGAIN
) &&
393 (ntries
+1 < MAX_RETRIES
)) {
395 (void) sleep(MAX_WAIT_TIME
);
398 I_DPRINTF("ioctl FCIO_GET_FCODE_REV failed.\n"
399 "Error: %s\n", strerror(errno
));
401 return (L_FCIO_GET_FCODE_REV_FAIL
);
405 version
[MAXNAMELEN
-1] = '\0';
407 /* Get the FW revision */
408 bzero(fw_rev
, sizeof (fw_rev
));
409 fcio
.fcio_cmd
= FCIO_GET_FW_REV
;
410 /* Information read operation */
411 fcio
.fcio_xfer
= FCIO_XFER_READ
;
412 fcio
.fcio_obuf
= (caddr_t
)fw_rev
;
413 fcio
.fcio_olen
= FC_FW_REV_SIZE
;
414 for (ntries
= 0; ntries
< MAX_RETRIES
; ntries
++) {
415 if (ioctl(fd
, FCIO_CMD
, &fcio
) != 0) {
416 if ((errno
== EAGAIN
) &&
417 (ntries
+1 < MAX_RETRIES
)) {
419 (void) sleep(MAX_WAIT_TIME
);
422 I_DPRINTF(" FCIO_GET_FW_REV ioctl failed.\n"
423 " Error: %s\n", strerror(errno
));
425 return (L_FCIO_GET_FW_REV_FAIL
);
435 * program an FEprom with data from 'source_address'.
436 * program the FEprom with zeroes,
438 * program it with the real data.
441 feprom_program(uchar_t
*source_address
, uchar_t
*dest_address
,
442 volatile socal_reg_t
*regs
)
446 (void) fprintf(stdout
, MSGSTR(4513, "Filling with zeroes...\n"));
447 if (!write_feprom((uchar_t
*)0, dest_address
, regs
)) {
448 (void) fprintf(stderr
,
449 MSGSTR(4514, "FEprom at 0x%x: zero fill failed\n"),
454 (void) fprintf(stdout
, MSGSTR(4515, "Erasing...\n"));
455 for (i
= 0; i
< FEPROM_MAX_ERASE
; i
++) {
456 if (feprom_erase(dest_address
, regs
))
460 if (i
>= FEPROM_MAX_ERASE
) {
461 (void) fprintf(stderr
,
462 MSGSTR(4516, "FEprom at 0x%x: failed to erase\n"),
467 (void) fprintf(stderr
, MSGSTR(4517,
468 "FEprom erased after %d attempt\n"), i
);
470 (void) fprintf(stderr
, MSGSTR(4518,
471 "FEprom erased after %d attempts\n"), i
);
475 (void) fprintf(stdout
, MSGSTR(4519, "Programming...\n"));
476 if (!(write_feprom(source_address
, dest_address
, regs
))) {
477 (void) fprintf(stderr
,
478 MSGSTR(4520, "FEprom at 0x%x: write failed\n"),
483 /* select the zeroth bank at end so we can read it */
484 regs
->socal_cr
.w
&= ~(0x30000);
485 (void) fprintf(stdout
, MSGSTR(4521, "Programming done\n"));
490 * program an FEprom one byte at a time using hot electron injection.
493 write_feprom(uchar_t
*source_address
, uchar_t
*dest_address
,
494 volatile socal_reg_t
*regs
)
497 uchar_t
*s
= source_address
;
500 for (i
= 0; i
< FEPROM_SIZE
; i
++, s
++) {
502 if ((i
& 0xffff) == 0) {
503 (void) fprintf(stdout
,
504 MSGSTR(4522, "selecting bank %d\n"), i
>>16);
505 regs
->socal_cr
.w
&= ~(0x30000);
506 regs
->socal_cr
.w
|= i
& 0x30000;
509 d
= dest_address
+ (i
& 0xffff);
511 for (pulse
= 0; pulse
< FEPROM_MAX_PROGRAM
; pulse
++) {
513 *d
= source_address
? *s
: 0;
515 *d
= FEPROM_PROGRAM_VERIFY
;
517 if (*d
== (source_address
? *s
: 0))
521 if (pulse
>= FEPROM_MAX_PROGRAM
) {
522 *dest_address
= FEPROM_RESET
;
527 *dest_address
= FEPROM_RESET
;
532 * erase an FEprom using Fowler-Nordheim tunneling.
535 feprom_erase(volatile uchar_t
*dest_address
, volatile socal_reg_t
*regs
)
538 volatile uchar_t
*d
= dest_address
;
544 usec_delay(10000); /* wait 10ms while FEprom erases */
546 for (i
= 0; i
< FEPROM_SIZE
; i
++) {
548 if ((i
& 0xffff) == 0) {
549 regs
->socal_cr
.w
&= ~(0x30000);
550 regs
->socal_cr
.w
|= i
& 0x30000;
553 d
= dest_address
+ (i
& 0xffff);
555 *d
= FEPROM_ERASE_VERIFY
;
558 *dest_address
= FEPROM_RESET
;
562 *dest_address
= FEPROM_RESET
;
575 } while (now
< then
);
582 char devpath
[PATH_MAX
];
584 /* We're searching the /devices directory, so... */
585 (void) strcpy(devpath
, "/devices");
587 /* get the directory entries under /devices for socal sbusmem */
588 (void) getsocpath(devpath
, (int *)&devcnt
);
594 getbootdev(unsigned int verbose
)
599 char bootdev
[PATH_MAX
];
604 if ((ptr
= popen(df
, "r")) != NULL
) {
605 while (fgets(buf
, BUFSIZ
, ptr
) != NULL
) {
606 if (p
= strstr(buf
, "/dev/dsk/")) {
607 (void) memset((char *)&bootdev
[0], 0,
610 while (*p1
!= '\0') {
611 if (!isalnum(*p1
) && (*p1
!= '/'))
615 (void) sscanf(p
, "%s", bootdev
);
621 (void) fprintf(stderr
, MSGSTR(44,
622 "root is not on a local disk!\n"));
623 (void) memset((char *)&bootpath
[0], 0, PATH_MAX
);
631 char *sbusmem
= "/sbusmem@";
632 char *slot
= ",0:slot";
634 ls
= (char *)malloc(PATH_MAX
);
635 (void) memset((char *)ls
, NULL
, PATH_MAX
);
636 (void) strcpy(ls
, "ls -l ");
637 (void) strcat(ls
, bootdev
);
638 if ((ptr
= popen(ls
, "r")) != NULL
) {
639 while (fgets(buf
, BUFSIZ
, ptr
) != NULL
) {
640 if (p
= strstr(buf
, "/devices")) {
641 if (p1
= strstr(buf
, "sbus")) {
644 p2
= strstr(p1
, "@");
650 p2
= strstr(p1
, "@");
660 (void) memset((char *)&bootdev
[0], 0, PATH_MAX
);
661 (void) sscanf(p
, "%s", bootdev
);
662 (void) memset((char *)&bootpath
[0], 0, PATH_MAX
);
663 (void) strcat(bootpath
, bootdev
);
664 (void) strcat(bootpath
, sbusmem
);
666 (void) strncat(bootpath
, p2
, 1);
667 (void) strcat(bootpath
, slot
);
668 (void) strncat(bootpath
, p2
, 1);
675 * This function reads "size" bytes from the FC100/S PROM.
676 * source_address: PROM address
677 * dest_address: local memeory
678 * offset: Location in PROM to start reading from.
681 feprom_read(uchar_t
*source_address
, uchar_t
*dest_address
,
682 int offset
, int size
, volatile socal_reg_t
*regs
)
684 uchar_t
*s
= source_address
;
685 uchar_t
*d
= dest_address
;
688 if (getenv("_LUX_D_DEBUG") != NULL
) {
689 (void) fprintf(stdout
,
690 " feprom_read: selecting bank %d\n",
693 (void) fprintf(stdout
, " Data read: ");
696 regs
->socal_cr
.w
= i
& 0xf0000;
697 s
= source_address
+ (i
& 0xffff);
698 *s
= FEPROM_READ_MEMORY
;
700 for (; s
< source_address
+ (i
& 0xffff) + size
; d
++, s
++) {
702 if ((getenv("_LUX_D_DEBUG") != NULL
) &&
704 (void) fprintf(stdout
, "0x%x ", *d
);
707 if ((getenv("_LUX_D_DEBUG") != NULL
) &&
709 (void) fprintf(stdout
, "\n From offset: 0x%x\n",
716 load_file(char *file
, caddr_t prom
, volatile socal_reg_t
*regs
)
718 uint_t wwn_d8
, wwn_lo
;
720 int ffd
= open(file
, 0);
722 wwn_hi
= FEPROM_SUN_WWN
;
725 perror(MSGSTR(4524, "open of file"));
728 (void) fprintf(stdout
, MSGSTR(4525, "Loading FCode: %s\n"), file
);
730 if (read(ffd
, &exec
, sizeof (exec
)) != sizeof (exec
)) {
731 perror(MSGSTR(4526, "read exec"));
735 if (exec
.a_trsize
|| exec
.a_drsize
) {
736 (void) fprintf(stderr
,
737 MSGSTR(4527, "%s: is relocatable\n"), file
);
741 if (exec
.a_data
|| exec
.a_bss
) {
742 (void) fprintf(stderr
,
743 MSGSTR(4528, "%s: has data or bss\n"), file
);
747 if (exec
.a_machtype
!= M_SPARC
) {
748 (void) fprintf(stderr
,
749 MSGSTR(4529, "%s: not for SPARC\n"), file
);
753 (void) fprintf(stdout
, MSGSTR(4530,
754 "Loading 0x%x bytes from %s at offset 0x%x\n"),
755 (int)exec
.a_text
, file
, 0);
757 if (read(ffd
, &buffer
, exec
.a_text
) != exec
.a_text
) {
758 perror(MSGSTR(4531, "read"));
764 feprom_read((uchar_t
*)prom
, (uchar_t
*)&wwn_d8
,
765 FEPROM_WWN_OFFSET
, 4, regs
);
766 feprom_read((uchar_t
*)prom
, (uchar_t
*)&wwn_lo
,
767 FEPROM_WWN_OFFSET
+ 4, 4, regs
);
768 wwn_hi
|= wwn_d8
& 0x0f; /* only last digit is interesting */
769 if (getenv("_LUX_D_DEBUG") != NULL
) {
770 (void) fprintf(stdout
,
771 " load_file: Writing WWN hi:0x%x lo:0x%x "
772 "to the FC100/S PROM\n", wwn_hi
, wwn_lo
);
774 /* put wwn into buffer location */
775 bcopy((const void *)&wwn_hi
,
776 (void *)&buffer
[FEPROM_WWN_OFFSET
],
778 bcopy((const void *)&wwn_lo
,
779 (void *)&buffer
[FEPROM_WWN_OFFSET
+ 4],
781 bcopy((const void *)&wwn_hi
,
782 (void *)&buffer
[FEPROM_WWN_OFFSET
+ 8],
784 bcopy((const void *)&wwn_lo
,
785 (void *)&buffer
[FEPROM_WWN_OFFSET
+ 0xc],
788 if (feprom_program((uchar_t
*)buffer
, (uchar_t
*)prom
, regs
) == 0) {
789 /* here 0 means failure */
803 (void) fprintf(stderr
, MSGSTR(4532,
804 "\nWARNING!! This program will update the FCode in this FC100/S Sbus Card.\n"));
805 (void) fprintf(stderr
, MSGSTR(4533,
806 "This may take a few (5) minutes. Please be patient.\n"));
809 (void) fprintf(stderr
, MSGSTR(4534,
810 "Do you wish to continue ? (y/n) "));
814 if ((strcmp(input
, MSGSTR(4535, "y")) == 0) ||
815 (strcmp(input
, MSGSTR(40, "yes")) == 0)) {
817 } else if ((strcmp(input
, MSGSTR(4536, "n")) == 0) ||
818 (strcmp(input
, MSGSTR(45, "no")) == 0)) {
819 (void) fprintf(stderr
, MSGSTR(4537, "Not Downloading FCode\n"));
822 (void) fprintf(stderr
, MSGSTR(4538, "Invalid input\n"));
830 * Searches the /devices directory recursively returning all soc_name
831 * entries in sbussoc_list (global). This excludes port entries and
832 * onboard socal (which leaves only directory entries with
833 * soc_name included). devcnt is updated to reflect number of soc_name
838 getsocpath(char *devpath
, int *devcnt
)
845 if (lstat(devpath
, &statbuf
) < 0) {
846 (void) fprintf(stderr
,
847 MSGSTR(4539, "Error: %s lstat() error\n"), devpath
);
851 if (S_ISDIR(statbuf
.st_mode
) == 0)
854 * we don't care about it - return
859 if (strstr(devpath
, ONBOARD_SOCAL
))
862 if (strstr(devpath
, SOCAL_STR
)) {
863 /* It's a keeper - call the load function */
864 if ((loadsocpath(devpath
, devcnt
)) < 0) {
865 (void) fprintf(stderr
,
866 MSGSTR(4540, "Error: Cannot set device list\n"),
871 * if socal directory - return,
872 * nothing else to see here
879 * It's a directory. Call ourself to
880 * traverse the path(s)
883 ptr
= devpath
+ strlen(devpath
);
887 /* Forget the /devices/pseudo/ directory */
888 if (strcmp(devpath
, "/devices/pseudo/") == 0)
891 if ((dp
= opendir(devpath
)) == NULL
) {
892 (void) fprintf(stderr
,
893 MSGSTR(4541, "Error: %s Can't read directory\n"), devpath
);
897 while ((dirp
= readdir(dp
)) != NULL
) {
899 if (strcmp(dirp
->d_name
, ".") == 0 ||
900 strcmp(dirp
->d_name
, "..") == 0)
903 (void) strcpy(ptr
, dirp
->d_name
); /* append name */
904 getsocpath(devpath
, devcnt
);
907 if (closedir(dp
) < 0) {
908 (void) fprintf(stderr
,
909 MSGSTR(4542, "Error: %s Can't close directory\n"), devpath
);
915 loadsocpath(const char *pathname
, int *devcnt
)
922 char buffer
[PATH_MAX
];
926 * Okay we found a device, now let's load it in to sbussoc_list
927 * and load the sbusmem file into sbus_list
930 if (pathname
!= NULL
&& *devcnt
< HBA_MAX
) {
931 (void) strcpy(sbussoc_list
[*devcnt
], pathname
);
932 if (sp_tmp
= strstr(sbussoc_list
[*devcnt
], SOCAL_STR
)) {
934 /* len_tmp will be len of "SUNW,socal@" */
935 len_tmp
= SOCAL_STR_LEN
+ 1;
937 len
= strlen(sbussoc_list
[*devcnt
]) - strlen(sp
);
938 (void) strncpy(buffer
, sbussoc_list
[*devcnt
], len
);
941 (void) sprintf(sbus_list
[*devcnt
], "%ssbusmem@%c,0:slot%c",
942 buffer
, sp
[0], sp
[0]);