/* * Copyright (C) IBM Corporation. 2007 * Author: Doug Maxey * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This 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 program. If not, see . */ /* - DEFINITION section. */ %{ /* literal block. include lines, decls, defns. */ //#define YYDEBUG 1 #if YYDEBUG #define DPRINT(fmt,...) printf(fmt,__VA_ARGS__) #else #define DPRINT(fmt,...) do {} while(0) #endif #include "prom_parse.h" #include "iscsi_obp.h" %} %union { #define STR_LEN 16384 char str[STR_LEN]; } /* definitions. */ %token BUSNAME BOOTDEV %token IPV4 IQN %token OBPPARM OBPQUAL %token HEX4 HEX16 %token VDEVICE VDEVINST VDEVDEV VDEVRAW %token CHOSEN %token FILENAME %type devpath busses bus bootdev %type disklabel diskpart %type vdevice vdev_parms vdev_parm %type obp_quals obp_qual obp_params obp_param %type ipaddr ipv4 ipv6 %type hexpart hexseq %locations %parse-param {struct ofw_dev *ofwdev} %% devpath: '/' { DPRINT("****rootonly: \"%s\"\n", "/"); } | '/' busses bootdev { DPRINT("****devpath busses:\n/%s/%s\n", $2, $3); } | '/' busses bootdev disklabel { ofwdev->dev_path = malloc(strlen($2) + strlen($3) + 3); sprintf(ofwdev->dev_path, "/%s%s", $2, $3); DPRINT("****devpath busses bootdev " "disklabel:\n/%s/%s%s\n", $2, $3, $4); } | '/' busses bootdev obp_quals obp_params { ofwdev->dev_path = malloc(strlen($2) + strlen($3) + 3); sprintf(ofwdev->dev_path, "/%s%s", $2, $3); DPRINT("****busses bootdev obp_quals obp_parms:\n" "/%s/%s:%s%s\n", $2, $3, $4, $5); } | '/' busses bootdev obp_quals obp_params disklabel { ofwdev->dev_path = malloc(strlen($2) + strlen($3) + 3); sprintf(ofwdev->dev_path, "/%s%s", $2, $3); DPRINT("****busses bootdev obp_quals obp_parms " "disklabel:\n/%s:%s%s%s\n", $2, $4, $5, $6); } | '/' vdevice bootdev vdev_parms obp_quals obp_params disklabel { DPRINT("****vdevice bootdev obp_parms " "disklabel:\n/%s:%s%s%s%s\n", $2, $4, $5, $6, $7); } ; busses: bus { strcpy($$, $1); } | busses '/' bus { snprintf($$, STR_LEN, "%s/%s", $1, $3); } ; bus: BUSNAME { strcpy($$, $1); } | BUSNAME '@' HEX4 { snprintf($$, STR_LEN, "%s@%s", $1, $3); } | BUSNAME '@' HEX4 ',' HEX4 { snprintf($$, STR_LEN, "%s@%s,%s", $1, $3, $5); } | BUSNAME '@' HEX16 { snprintf($$, STR_LEN, "%s@%s", $1, $3); } | BUSNAME ',' HEX4 '@' HEX16 { snprintf($$, STR_LEN, "%s,%s@%s", $1, $3, $5); } ; bootdev: '/' BOOTDEV ':' { snprintf($$, STR_LEN, "/%s", $2); } | '/' BOOTDEV '@' HEX4 ':' { snprintf($$, STR_LEN, "/%s@%s", $2, $4); } | '/' BOOTDEV '@' HEX4 ',' HEX4 ':' { snprintf($$, STR_LEN, "/%s@%s,%s", $2, $4, $6); } ; vdevice: VDEVICE '/' VDEVINST { snprintf($$, STR_LEN, "%s/%s", $1, $3); } ; vdev_parms: ':' vdev_parm { snprintf($$, STR_LEN, ":%s", $2); } | vdev_parms ',' vdev_parm { snprintf($$, STR_LEN, "%s,%s", $1, $3); } | vdev_parms ',' VDEVRAW { snprintf($$, STR_LEN, "%s,%s", $1, $3); } ; vdev_parm: VDEVDEV '=' CHOSEN { snprintf($$, STR_LEN, "%s=%s", $1, $3); } ; obp_params: ',' obp_param { snprintf($$, STR_LEN, ",%s", $2); } | obp_params ',' obp_param { snprintf($$, STR_LEN, "%s,%s", $1, $3); } | obp_params ',' disklabel { snprintf($$, STR_LEN, "%s,%s", $1, $3); } ; obp_param: HEX4 { snprintf($$, STR_LEN, "%s", $1); } | OBPPARM '=' HEX16 { /* luns > 0 are the SAM-3+ hex representation. */ obp_parm_hexnum(ofwdev, $1, $3); snprintf($$, STR_LEN, "%s=%s", $1, $3); } | OBPPARM '=' ipaddr { obp_parm_addr(ofwdev, $1, $3); snprintf($$, STR_LEN, "%s=%s", $1, $3); } | OBPPARM '=' IQN { obp_parm_iqn(ofwdev, $1, $3); snprintf($$, STR_LEN, "%s=%s", $1, $3); } | OBPPARM '=' HEX4 { obp_parm_hexnum(ofwdev, $1, $3); snprintf($$, STR_LEN, "%s=%s", $1, $3); } | OBPPARM '=' FILENAME { obp_parm_str(ofwdev, $1, $3); snprintf($$, STR_LEN, "%s=%s", $1, $3); } ; obp_quals: obp_qual { snprintf($$, STR_LEN, "%s", $1); } | obp_quals ',' obp_qual { snprintf($$, STR_LEN, "%s,%s", $1, $3); } ; obp_qual: OBPQUAL { snprintf($$, STR_LEN, "%s", obp_qual_set(ofwdev, $1)); } | vdev_parm { snprintf($$, STR_LEN, "%s", $1); } ; ipaddr: ipv4 { snprintf($$, STR_LEN, "%s", $1); } | ipv6 { snprintf($$, STR_LEN, "%s", $1); } ; ipv4: IPV4 { snprintf($$, STR_LEN, "%s", $1); } ; ipv6: hexpart { snprintf($$, STR_LEN, "%s", $1); } | hexpart ':' ipv4 { snprintf($$, STR_LEN, "%s:%s", $1, $3); } ; hexpart: hexseq { snprintf($$, STR_LEN, "%s", $1); } | hexpart "::" { snprintf($$, STR_LEN, "%s::", $1); } | hexpart "::" hexseq { snprintf($$, STR_LEN, "%s::%s", $1, $3); } | "::" hexseq { snprintf($$, STR_LEN, "::%s", $2); } ; hexseq: HEX4 { snprintf($$, STR_LEN, "%s", $1); } | hexseq ":" HEX4 { snprintf($$, STR_LEN, "%s:%s", $1, $3); } ; disklabel: diskpart { snprintf($$, STR_LEN, "%s", $1); } | HEX4 diskpart { snprintf($$, STR_LEN, "%s%s", $1, $2); } | '@' HEX4 ',' HEX4 diskpart { snprintf($$, STR_LEN, "@%s,%s%s", $2, $4, $5); } ; diskpart: ':' HEX4 { snprintf($$, STR_LEN, ":%s", $2); } | ':' HEX4 ',' FILENAME { snprintf($$, STR_LEN, ":%s,%s", $2, $4); } ; %%