]> bbs.cooldavid.org Git - net-next-2.6.git/blobdiff - drivers/ata/libata-core.c
docbook: fix fatal error from libata
[net-next-2.6.git] / drivers / ata / libata-core.c
index ddf8e48627878999c17f686fcfb05dce669a2b9c..7ef7c4f216fa58567e161c82118155411d070074 100644 (file)
@@ -98,8 +98,6 @@ static unsigned long ata_dev_blacklisted(const struct ata_device *dev);
 
 unsigned int ata_print_id = 1;
 
-struct workqueue_struct *ata_aux_wq;
-
 struct ata_force_param {
        const char      *name;
        unsigned int    cbl;
@@ -4167,15 +4165,13 @@ static const struct ata_blacklist_entry ata_device_blacklist [] = {
        { "WDC AC23200L",       "21.10N21",     ATA_HORKAGE_NODMA },
        { "Compaq CRD-8241B",   NULL,           ATA_HORKAGE_NODMA },
        { "CRD-8400B",          NULL,           ATA_HORKAGE_NODMA },
-       { "CRD-8480B",          NULL,           ATA_HORKAGE_NODMA },
-       { "CRD-8482B",          NULL,           ATA_HORKAGE_NODMA },
+       { "CRD-848[02]B",       NULL,           ATA_HORKAGE_NODMA },
        { "CRD-84",             NULL,           ATA_HORKAGE_NODMA },
        { "SanDisk SDP3B",      NULL,           ATA_HORKAGE_NODMA },
        { "SanDisk SDP3B-64",   NULL,           ATA_HORKAGE_NODMA },
        { "SANYO CD-ROM CRD",   NULL,           ATA_HORKAGE_NODMA },
        { "HITACHI CDR-8",      NULL,           ATA_HORKAGE_NODMA },
-       { "HITACHI CDR-8335",   NULL,           ATA_HORKAGE_NODMA },
-       { "HITACHI CDR-8435",   NULL,           ATA_HORKAGE_NODMA },
+       { "HITACHI CDR-8[34]35",NULL,           ATA_HORKAGE_NODMA },
        { "Toshiba CD-ROM XM-6202B", NULL,      ATA_HORKAGE_NODMA },
        { "TOSHIBA CD-ROM XM-1702BC", NULL,     ATA_HORKAGE_NODMA },
        { "CD-532E-A",          NULL,           ATA_HORKAGE_NODMA },
@@ -4211,70 +4207,16 @@ static const struct ata_blacklist_entry ata_device_blacklist [] = {
        { "OCZ CORE_SSD",       "02.10104",     ATA_HORKAGE_NONCQ },
 
        /* Seagate NCQ + FLUSH CACHE firmware bug */
-       { "ST31500341AS",       "SD15",         ATA_HORKAGE_NONCQ |
-                                               ATA_HORKAGE_FIRMWARE_WARN },
-       { "ST31500341AS",       "SD16",         ATA_HORKAGE_NONCQ |
-                                               ATA_HORKAGE_FIRMWARE_WARN },
-       { "ST31500341AS",       "SD17",         ATA_HORKAGE_NONCQ |
-                                               ATA_HORKAGE_FIRMWARE_WARN },
-       { "ST31500341AS",       "SD18",         ATA_HORKAGE_NONCQ |
-                                               ATA_HORKAGE_FIRMWARE_WARN },
-       { "ST31500341AS",       "SD19",         ATA_HORKAGE_NONCQ |
-                                               ATA_HORKAGE_FIRMWARE_WARN },
-
-       { "ST31000333AS",       "SD15",         ATA_HORKAGE_NONCQ |
-                                               ATA_HORKAGE_FIRMWARE_WARN },
-       { "ST31000333AS",       "SD16",         ATA_HORKAGE_NONCQ |
-                                               ATA_HORKAGE_FIRMWARE_WARN },
-       { "ST31000333AS",       "SD17",         ATA_HORKAGE_NONCQ |
-                                               ATA_HORKAGE_FIRMWARE_WARN },
-       { "ST31000333AS",       "SD18",         ATA_HORKAGE_NONCQ |
-                                               ATA_HORKAGE_FIRMWARE_WARN },
-       { "ST31000333AS",       "SD19",         ATA_HORKAGE_NONCQ |
-                                               ATA_HORKAGE_FIRMWARE_WARN },
-
-       { "ST3640623AS",        "SD15",         ATA_HORKAGE_NONCQ |
-                                               ATA_HORKAGE_FIRMWARE_WARN },
-       { "ST3640623AS",        "SD16",         ATA_HORKAGE_NONCQ |
-                                               ATA_HORKAGE_FIRMWARE_WARN },
-       { "ST3640623AS",        "SD17",         ATA_HORKAGE_NONCQ |
-                                               ATA_HORKAGE_FIRMWARE_WARN },
-       { "ST3640623AS",        "SD18",         ATA_HORKAGE_NONCQ |
-                                               ATA_HORKAGE_FIRMWARE_WARN },
-       { "ST3640623AS",        "SD19",         ATA_HORKAGE_NONCQ |
+       { "ST31500341AS",       "SD1[5-9]",     ATA_HORKAGE_NONCQ |
                                                ATA_HORKAGE_FIRMWARE_WARN },
 
-       { "ST3640323AS",        "SD15",         ATA_HORKAGE_NONCQ |
-                                               ATA_HORKAGE_FIRMWARE_WARN },
-       { "ST3640323AS",        "SD16",         ATA_HORKAGE_NONCQ |
-                                               ATA_HORKAGE_FIRMWARE_WARN },
-       { "ST3640323AS",        "SD17",         ATA_HORKAGE_NONCQ |
-                                               ATA_HORKAGE_FIRMWARE_WARN },
-       { "ST3640323AS",        "SD18",         ATA_HORKAGE_NONCQ |
-                                               ATA_HORKAGE_FIRMWARE_WARN },
-       { "ST3640323AS",        "SD19",         ATA_HORKAGE_NONCQ |
+       { "ST31000333AS",       "SD1[5-9]",     ATA_HORKAGE_NONCQ |
                                                ATA_HORKAGE_FIRMWARE_WARN },
 
-       { "ST3320813AS",        "SD15",         ATA_HORKAGE_NONCQ |
-                                               ATA_HORKAGE_FIRMWARE_WARN },
-       { "ST3320813AS",        "SD16",         ATA_HORKAGE_NONCQ |
-                                               ATA_HORKAGE_FIRMWARE_WARN },
-       { "ST3320813AS",        "SD17",         ATA_HORKAGE_NONCQ |
-                                               ATA_HORKAGE_FIRMWARE_WARN },
-       { "ST3320813AS",        "SD18",         ATA_HORKAGE_NONCQ |
-                                               ATA_HORKAGE_FIRMWARE_WARN },
-       { "ST3320813AS",        "SD19",         ATA_HORKAGE_NONCQ |
+       { "ST3640[36]23AS",     "SD1[5-9]",     ATA_HORKAGE_NONCQ |
                                                ATA_HORKAGE_FIRMWARE_WARN },
 
-       { "ST3320613AS",        "SD15",         ATA_HORKAGE_NONCQ |
-                                               ATA_HORKAGE_FIRMWARE_WARN },
-       { "ST3320613AS",        "SD16",         ATA_HORKAGE_NONCQ |
-                                               ATA_HORKAGE_FIRMWARE_WARN },
-       { "ST3320613AS",        "SD17",         ATA_HORKAGE_NONCQ |
-                                               ATA_HORKAGE_FIRMWARE_WARN },
-       { "ST3320613AS",        "SD18",         ATA_HORKAGE_NONCQ |
-                                               ATA_HORKAGE_FIRMWARE_WARN },
-       { "ST3320613AS",        "SD19",         ATA_HORKAGE_NONCQ |
+       { "ST3320[68]13AS",     "SD1[5-9]",     ATA_HORKAGE_NONCQ |
                                                ATA_HORKAGE_FIRMWARE_WARN },
 
        /* Blacklist entries taken from Silicon Image 3124/3132
@@ -4303,12 +4245,7 @@ static const struct ata_blacklist_entry ata_device_blacklist [] = {
        /* Devices which get the IVB wrong */
        { "QUANTUM FIREBALLlct10 05", "A03.0900", ATA_HORKAGE_IVB, },
        /* Maybe we should just blacklist TSSTcorp... */
-       { "TSSTcorp CDDVDW SH-S202H", "SB00",     ATA_HORKAGE_IVB, },
-       { "TSSTcorp CDDVDW SH-S202H", "SB01",     ATA_HORKAGE_IVB, },
-       { "TSSTcorp CDDVDW SH-S202J", "SB00",     ATA_HORKAGE_IVB, },
-       { "TSSTcorp CDDVDW SH-S202J", "SB01",     ATA_HORKAGE_IVB, },
-       { "TSSTcorp CDDVDW SH-S202N", "SB00",     ATA_HORKAGE_IVB, },
-       { "TSSTcorp CDDVDW SH-S202N", "SB01",     ATA_HORKAGE_IVB, },
+       { "TSSTcorp CDDVDW SH-S202[HJN]", "SB0[01]",  ATA_HORKAGE_IVB, },
 
        /* Devices that do not need bridging limits applied */
        { "MTRON MSP-SATA*",            NULL,   ATA_HORKAGE_BRIDGE_OK, },
@@ -4326,29 +4263,73 @@ 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.
+ *             [a-d]   matches a single character from the range: a, b, c, or d.
+ *             [a-d0-9] matches a single character from either range.
+ *
+ *     The special characters ?, [, -, or *, can be matched using a set, eg. [*]
+ *     Behaviour with malformed patterns is undefined, though generally reasonable.
+ *
+ *     Sample patterns:  "SD1?",  "SD1[0-5]",  "*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 - 1) != '[')
+                                       if (*text > *(pattern - 1) && *text < *(pattern + 1)) {
+                                               ++pattern;
+                                               break;
+                                       }
+                       }
+                       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)
 {
        unsigned char model_num[ATA_ID_PROD_LEN + 1];
@@ -4359,10 +4340,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));
 
        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)
                                return ad->horkage;
-                       if (!strn_pattern_cmp(ad->model_rev, model_rev, '*'))
+                       if (!glob_match(model_rev, ad->model_rev))
                                return ad->horkage;
                }
                ad++;
@@ -5611,6 +5592,7 @@ struct ata_port *ata_port_alloc(struct ata_host *host)
        ap->msg_enable = ATA_MSG_DRV | ATA_MSG_ERR | ATA_MSG_WARN;
 #endif
 
+       mutex_init(&ap->scsi_scan_mutex);
        INIT_DELAYED_WORK(&ap->hotplug_task, ata_scsi_hotplug);
        INIT_WORK(&ap->scsi_rescan_task, ata_scsi_dev_rescan);
        INIT_LIST_HEAD(&ap->eh_done_q);
@@ -6549,29 +6531,20 @@ static int __init ata_init(void)
 
        ata_parse_force_param();
 
-       ata_aux_wq = create_singlethread_workqueue("ata_aux");
-       if (!ata_aux_wq)
-               goto fail;
-
        rc = ata_sff_init();
-       if (rc)
-               goto fail;
+       if (rc) {
+               kfree(ata_force_tbl);
+               return rc;
+       }
 
        printk(KERN_DEBUG "libata version " DRV_VERSION " loaded.\n");
        return 0;
-
-fail:
-       kfree(ata_force_tbl);
-       if (ata_aux_wq)
-               destroy_workqueue(ata_aux_wq);
-       return rc;
 }
 
 static void __exit ata_exit(void)
 {
        ata_sff_exit();
        kfree(ata_force_tbl);
-       destroy_workqueue(ata_aux_wq);
 }
 
 subsys_initcall(ata_init);