|
@@ -4326,29 +4326,65 @@ static const struct ata_blacklist_entry ata_device_blacklist [] = {
|
|
{ }
|
|
{ }
|
|
};
|
|
};
|
|
|
|
|
|
-static int strn_pattern_cmp(const char *patt, const char *name, int wildchar)
|
|
|
|
|
|
+/**
|
|
|
|
+ * glob_match - match a text string against a glob-style pattern
|
|
|
|
+ * @text: the string to be examined
|
|
|
|
+ * @pattern: the glob-style pattern to be matched against
|
|
|
|
+ *
|
|
|
|
+ * Either/both of text and pattern can be empty strings.
|
|
|
|
+ *
|
|
|
|
+ * Match text against a glob-style pattern, with wildcards and simple sets:
|
|
|
|
+ *
|
|
|
|
+ * ? matches any single character.
|
|
|
|
+ * * matches any run of characters.
|
|
|
|
+ * [xyz] matches a single character from the set: x, y, or z.
|
|
|
|
+ *
|
|
|
|
+ * Note: hyphenated ranges [0-9] are _not_ supported here.
|
|
|
|
+ * The special characters ?, [, or *, can be matched using a set, eg. [*]
|
|
|
|
+ *
|
|
|
|
+ * Example patterns: "SD1?", "SD1[012345]", "*R0", SD*1?[012]*xx"
|
|
|
|
+ *
|
|
|
|
+ * This function uses one level of recursion per '*' in pattern.
|
|
|
|
+ * Since it calls _nothing_ else, and has _no_ explicit local variables,
|
|
|
|
+ * this will not cause stack problems for any reasonable use here.
|
|
|
|
+ *
|
|
|
|
+ * RETURNS:
|
|
|
|
+ * 0 on match, 1 otherwise.
|
|
|
|
+ */
|
|
|
|
+static int glob_match (const char *text, const char *pattern)
|
|
{
|
|
{
|
|
- const char *p;
|
|
|
|
- int len;
|
|
|
|
-
|
|
|
|
- /*
|
|
|
|
- * check for trailing wildcard: *\0
|
|
|
|
- */
|
|
|
|
- p = strchr(patt, wildchar);
|
|
|
|
- if (p && ((*(p + 1)) == 0))
|
|
|
|
- len = p - patt;
|
|
|
|
- else {
|
|
|
|
- len = strlen(name);
|
|
|
|
- if (!len) {
|
|
|
|
- if (!*patt)
|
|
|
|
- return 0;
|
|
|
|
- return -1;
|
|
|
|
|
|
+ do {
|
|
|
|
+ /* Match single character or a '?' wildcard */
|
|
|
|
+ if (*text == *pattern || *pattern == '?') {
|
|
|
|
+ if (!*pattern++)
|
|
|
|
+ return 0; /* End of both strings: match */
|
|
|
|
+ } else {
|
|
|
|
+ /* Match single char against a '[' bracketed ']' pattern set */
|
|
|
|
+ if (!*text || *pattern != '[')
|
|
|
|
+ break; /* Not a pattern set */
|
|
|
|
+ while (*++pattern && *pattern != ']' && *text != *pattern);
|
|
|
|
+ if (!*pattern || *pattern == ']')
|
|
|
|
+ return 1; /* No match */
|
|
|
|
+ while (*pattern && *pattern++ != ']');
|
|
|
|
+ }
|
|
|
|
+ } while (*++text && *pattern);
|
|
|
|
+
|
|
|
|
+ /* Match any run of chars against a '*' wildcard */
|
|
|
|
+ if (*pattern == '*') {
|
|
|
|
+ if (!*++pattern)
|
|
|
|
+ return 0; /* Match: avoid recursion at end of pattern */
|
|
|
|
+ /* Loop to handle additional pattern chars after the wildcard */
|
|
|
|
+ while (*text) {
|
|
|
|
+ if (glob_match(text, pattern) == 0)
|
|
|
|
+ return 0; /* Remainder matched */
|
|
|
|
+ ++text; /* Absorb (match) this char and try again */
|
|
}
|
|
}
|
|
}
|
|
}
|
|
-
|
|
|
|
- return strncmp(patt, name, len);
|
|
|
|
|
|
+ if (!*text && !*pattern)
|
|
|
|
+ return 0; /* End of both strings: match */
|
|
|
|
+ return 1; /* No match */
|
|
}
|
|
}
|
|
-
|
|
|
|
|
|
+
|
|
static unsigned long ata_dev_blacklisted(const struct ata_device *dev)
|
|
static unsigned long ata_dev_blacklisted(const struct ata_device *dev)
|
|
{
|
|
{
|
|
unsigned char model_num[ATA_ID_PROD_LEN + 1];
|
|
unsigned char model_num[ATA_ID_PROD_LEN + 1];
|
|
@@ -4359,10 +4395,10 @@ static unsigned long ata_dev_blacklisted(const struct ata_device *dev)
|
|
ata_id_c_string(dev->id, model_rev, ATA_ID_FW_REV, sizeof(model_rev));
|
|
ata_id_c_string(dev->id, model_rev, ATA_ID_FW_REV, sizeof(model_rev));
|
|
|
|
|
|
while (ad->model_num) {
|
|
while (ad->model_num) {
|
|
- if (!strn_pattern_cmp(ad->model_num, model_num, '*')) {
|
|
|
|
|
|
+ if (!glob_match(model_num, ad->model_num)) {
|
|
if (ad->model_rev == NULL)
|
|
if (ad->model_rev == NULL)
|
|
return ad->horkage;
|
|
return ad->horkage;
|
|
- if (!strn_pattern_cmp(ad->model_rev, model_rev, '*'))
|
|
|
|
|
|
+ if (!glob_match(model_rev, ad->model_rev))
|
|
return ad->horkage;
|
|
return ad->horkage;
|
|
}
|
|
}
|
|
ad++;
|
|
ad++;
|