a3702400af5993503bd274954b4ac5e1579abc1c
// ========== Copyright Header Begin ==========================================
// OpenSPARC T2 Processor File: disk_parser.cc
// Copyright (c) 2006 Sun Microsystems, Inc. All Rights Reserved.
// DO NOT ALTER OR REMOVE COPYRIGHT NOTICES.
// The above named program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public
// License version 2 as published by the Free Software Foundation.
// The above named program 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
// General Public License for more details.
// You should have received a copy of the GNU General Public
// License along with this work; if not, write to the Free Software
// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
// ========== Copyright Header End ============================================
#define MAX_SCSI_DISK_PARTITIONS 8
#define MAX_SCSI_TARGETS 16
#define LINE_BUF_SIZE 1024
extern SCSIDisk
*parser_disk
;
static char ** parse_args (const char * string
, int * pargc
) {
char ** pargv
= (char**) calloc (allocc
, sizeof(char*));
char * tmpstr
= (char*) strdup (string
);
int inquotes
= 0; /* when we're inside " quotes */
int backslash
= 0; /* yet another flag... */
// remove leading white space
if ((*s
== '\0') || (*s
== '\n')) {
while (!isspace(*s
) || inquotes
) {
// copy parsed arg into argv
pargv
[argc
++] = (char*) strdup (ps
);
// re-allocate argv if we have too many args
pargv
= (char**) realloc (pargv
, sizeof(char*) * allocc
);
// skip white space between words
if ((*s
== '\0') || (*s
== '\n'))
pargv
[argc
++] = (char*) strdup (ps
);
static void free_args (int argc
, char ** argv
) {
for (i
= 0; i
< argc
; i
++) {
char *process_str(const char *src
) {
char *dst
= (char *)calloc(ls
+1, sizeof(char));
if ((src
[0] == '\'' /* single quoted */
|| (src
[0] == '"' /* or double quoted cases */
} else if (ls
> 9 /* dotted hex case */
&& src
[2] == '.' && src
[5] == '.' && src
[8] == '.') {
if (src
[i
] != '.') dst
[j
++] = src
[i
];
} else { /* default case */
// Scan through the whole file to parse all configs related to a target
int scsi_parse_config(const char * fname
, FILE *fp
, int target
) {
char line_buf
[LINE_BUF_SIZE
];
int target_id
, disk_id
, partition_id
;
bool write_flag
, vtoc_part
;
const char *vendor_id
, *product_id
, *revision_id
;
const char *prodserial_no
, *brdserial_no
;
const char *port_wwn
, *node_wwn
;
const char *bytes_per_sector
;
const char *sectors_per_track
;
const char *tracks_per_cylinder
;
while (charP
= fgets(line_buf
, LINE_BUF_SIZE
, fp
)) {
// initializing variables
target_id
= disk_id
= partition_id
= -1;
vendor_id
= product_id
= revision_id
= NULL
;
prodserial_no
= brdserial_no
= NULL
;
port_wwn
= node_wwn
= NULL
;
sectors_per_track
= NULL
;
tracks_per_cylinder
= NULL
;
// lineno is used to track the error
// parse all parameters into arg
argv
= parse_args(charP
, &argc
);
fprintf(stderr
, "%s: lineno %d: insufficient args.\n", fname
, lineno
);
result
= sscanf(argv
[0], "t%dd%ds%x", &target_id
, &disk_id
, &partition_id
);
fprintf(stderr
, "%s: lineno %d: wrong disk partition name.\n", fname
, lineno
);
if (target_id
>= MAX_SCSI_TARGETS
|| target_id
< 0) {
fprintf(stderr
, "%s: lineno %d: invalid target id.\n", fname
, lineno
);
fprintf(stderr
, "%s: lineno %d: invalid disk id.\n", fname
, lineno
);
if (partition_id
>= MAX_SCSI_DISK_PARTITIONS
|| partition_id
< 0) {
fprintf(stderr
, "%s: lineno %d: invalid partition id.\n", fname
, lineno
);
bool other_params
= false;
// the third parameter is either "ro", or "rw", or "vtoc", or others
if (strcmp(argv
[i
], "ro") == 0) {
} else if (strcmp(argv
[i
], "rw") == 0) {
} else if (strcmp(argv
[i
], "vtoc") == 0) {
// the fourth parameter is "votc", or others
if (!other_params
&& i
< argc
) {
if (strcmp(argv
[i
], "vtoc") == 0) {
if (argval ("vendor-id", argv
[i
], &vendor_id
))
parser_disk
->set_vendor_id(process_str(vendor_id
));
else if (argval ("product-id", argv
[i
], &product_id
))
parser_disk
->set_product_id(process_str(product_id
));
else if (argval ("revision-id", argv
[i
], &revision_id
))
parser_disk
->set_revision_id(process_str(revision_id
));
else if (argval ("serial-no", argv
[i
], &serial_no
))
parser_disk
->set_serial_no(process_str(serial_no
));
else if (argval ("prodserial-no", argv
[i
], &prodserial_no
))
parser_disk
->set_prodserial_no(process_str(prodserial_no
));
else if (argval ("brdserial-no", argv
[i
], &brdserial_no
))
parser_disk
->set_brdserial_no(process_str(brdserial_no
));
else if (argval ("port-wwn", argv
[i
], &port_wwn
))
parser_disk
->set_port_wwn(process_str(port_wwn
));
else if (argval ("node-wwn", argv
[i
], &node_wwn
))
parser_disk
->set_node_wwn(process_str(node_wwn
));
else if (argval ("bytes/sector", argv
[i
], &bytes_per_sector
))
parser_disk
->set_bytes_per_sector(atoi(bytes_per_sector
));
else if (argval ("sectors/track", argv
[i
], §ors_per_track
))
parser_disk
->set_sectors_per_track(atoi(sectors_per_track
));
else if (argval ("tracks/cylinder", argv
[i
], &tracks_per_cylinder
))
parser_disk
->set_tracks_per_cylinder(atoi(tracks_per_cylinder
));
else if (argval ("dd", argv
[i
], &disk_delay
))
parser_disk
->set_disk_delay(process_str(disk_delay
));
else if (argval ("debug-file", argv
[i
], &debug_file
))
parser_disk
->set_debug_file(process_str(debug_file
));
else if (argval ("debug-level", argv
[i
], &debug_level
))
parser_disk
->set_debug_level(atoi(debug_level
));
fprintf(stderr
, "%s: lineno %d: unrecognized arg.\n", fname
, lineno
);
parser_disk
->add_partition(partition_id
, argv
[1], write_flag
, vtoc_part
);