-
-/*
- * Test if "dev" should be configured on or off.
- * This processes the options literally from left to right.
- * This lets the user specify stupid combinations of options,
- * but at least the result should be very predictable.
- */
-static int eeh_check_opts_config(struct device_node *dn,
- int class_code, int vendor_id, int device_id,
- int default_state)
-{
- char devname[32], classname[32];
- char *strs[8], *s;
- int nstrs, i;
- int ret = default_state;
-
- /* Build list of strings to match */
- nstrs = 0;
- s = (char *)get_property(dn, "ibm,loc-code", 0);
- if (s)
- strs[nstrs++] = s;
- sprintf(devname, "dev%04x:%04x", vendor_id, device_id);
- strs[nstrs++] = devname;
- sprintf(classname, "class%04x", class_code);
- strs[nstrs++] = classname;
- strs[nstrs++] = ""; /* yes, this matches the empty string */
-
- /*
- * Now see if any string matches the eeh_opts list.
- * The eeh_opts list entries start with + or -.
- */
- for (s = eeh_opts; s && (s < (eeh_opts + eeh_opts_last));
- s += strlen(s)+1) {
- for (i = 0; i < nstrs; i++) {
- if (strcasecmp(strs[i], s+1) == 0) {
- ret = (strs[i][0] == '+') ? 1 : 0;
- }
- }
- }
- return ret;
-}
-
-/*
- * Handle kernel eeh-on & eeh-off cmd line options for eeh.
- *
- * We support:
- * eeh-off=loc1,loc2,loc3...
- *
- * and this option can be repeated so
- * eeh-off=loc1,loc2 eeh-off=loc3
- * is the same as eeh-off=loc1,loc2,loc3
- *
- * loc is an IBM location code that can be found in a manual or
- * via openfirmware (or the Hardware Management Console).
- *
- * We also support these additional "loc" values:
- *
- * dev#:# vendor:device id in hex (e.g. dev1022:2000)
- * class# class id in hex (e.g. class0200)
- *
- * If no location code is specified all devices are assumed
- * so eeh-off means eeh by default is off.
- */
-
-/*
- * This is implemented as a null separated list of strings.
- * Each string looks like this: "+X" or "-X"
- * where X is a loc code, vendor:device, class (as shown above)
- * or empty which is used to indicate all.
- *
- * We interpret this option string list so that it will literally
- * behave left-to-right even if some combinations don't make sense.
- */
-static int __init eeh_parm(char *str, int state)
-{
- char *s, *cur, *curend;
-
- if (!eeh_opts) {
- eeh_opts = alloc_bootmem(EEH_MAX_OPTS);
- eeh_opts[eeh_opts_last++] = '+'; /* default */
- eeh_opts[eeh_opts_last++] = '\0';
- }
- if (*str == '\0') {
- eeh_opts[eeh_opts_last++] = state ? '+' : '-';
- eeh_opts[eeh_opts_last++] = '\0';
- return 1;
- }
- if (*str == '=')
- str++;
- for (s = str; s && *s != '\0'; s = curend) {
- cur = s;
- /* ignore empties. Don't treat as "all-on" or "all-off" */
- while (*cur == ',')
- cur++;
- curend = strchr(cur, ',');
- if (!curend)
- curend = cur + strlen(cur);
- if (*cur) {
- int curlen = curend-cur;
- if (eeh_opts_last + curlen > EEH_MAX_OPTS-2) {
- printk(KERN_WARNING "EEH: sorry...too many "
- "eeh cmd line options\n");
- return 1;
- }
- eeh_opts[eeh_opts_last++] = state ? '+' : '-';
- strncpy(eeh_opts+eeh_opts_last, cur, curlen);
- eeh_opts_last += curlen;
- eeh_opts[eeh_opts_last++] = '\0';
- }
- }
-
- return 1;
-}
-
-static int __init eehoff_parm(char *str)
-{
- return eeh_parm(str, 0);
-}
-
-static int __init eehon_parm(char *str)
-{
- return eeh_parm(str, 1);
-}
-
-__setup("eeh-off", eehoff_parm);
-__setup("eeh-on", eehon_parm);