diff options
author | Alan Cox <alan@lxorguk.ukuu.org.uk> | 2006-10-27 22:08:46 -0400 |
---|---|---|
committer | Jeff Garzik <jeff@garzik.org> | 2006-12-01 22:40:28 -0500 |
commit | 6919a0a6cfdad9e83d02cef5973826acd416560c (patch) | |
tree | 7f3d444c1c12077efe0824b8cb02b78a877c16d2 /drivers/ata | |
parent | fbbb262d9ea9bdbd79d7058271560e9990bc62d3 (diff) |
[PATCH] libata: Revamp blacklist support to allow multiple kinds of blacklisting flaws
Signed-off-by: Alan Cox <alan@redhat.com>
Cc: Jeff Garzik <jeff@garzik.org>
Cc: Tejun Heo <htejun@gmail.com>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Jeff Garzik <jeff@garzik.org>
Diffstat (limited to 'drivers/ata')
-rw-r--r-- | drivers/ata/libata-core.c | 123 |
1 files changed, 75 insertions, 48 deletions
diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c index b896119cccd3..b4fbfebafd26 100644 --- a/drivers/ata/libata-core.c +++ b/drivers/ata/libata-core.c | |||
@@ -1345,7 +1345,10 @@ static void ata_dev_config_ncq(struct ata_device *dev, | |||
1345 | desc[0] = '\0'; | 1345 | desc[0] = '\0'; |
1346 | return; | 1346 | return; |
1347 | } | 1347 | } |
1348 | 1348 | if (ata_device_blacklisted(dev) & ATA_HORKAGE_NONCQ) { | |
1349 | snprintf(desc, desc_sz, "NCQ (not used)"); | ||
1350 | return; | ||
1351 | } | ||
1349 | if (ap->flags & ATA_FLAG_NCQ) { | 1352 | if (ap->flags & ATA_FLAG_NCQ) { |
1350 | hdepth = min(ap->scsi_host->can_queue, ATA_MAX_QUEUE - 1); | 1353 | hdepth = min(ap->scsi_host->can_queue, ATA_MAX_QUEUE - 1); |
1351 | dev->flags |= ATA_DFLAG_NCQ; | 1354 | dev->flags |= ATA_DFLAG_NCQ; |
@@ -3014,37 +3017,55 @@ int ata_dev_revalidate(struct ata_device *dev, int post_reset) | |||
3014 | return rc; | 3017 | return rc; |
3015 | } | 3018 | } |
3016 | 3019 | ||
3017 | static const char * const ata_dma_blacklist [] = { | 3020 | struct ata_blacklist_entry { |
3018 | "WDC AC11000H", NULL, | 3021 | const char *model_num; |
3019 | "WDC AC22100H", NULL, | 3022 | const char *model_rev; |
3020 | "WDC AC32500H", NULL, | 3023 | unsigned long horkage; |
3021 | "WDC AC33100H", NULL, | 3024 | }; |
3022 | "WDC AC31600H", NULL, | 3025 | |
3023 | "WDC AC32100H", "24.09P07", | 3026 | static const struct ata_blacklist_entry ata_device_blacklist [] = { |
3024 | "WDC AC23200L", "21.10N21", | 3027 | /* Devices with DMA related problems under Linux */ |
3025 | "Compaq CRD-8241B", NULL, | 3028 | { "WDC AC11000H", NULL, ATA_HORKAGE_NODMA }, |
3026 | "CRD-8400B", NULL, | 3029 | { "WDC AC22100H", NULL, ATA_HORKAGE_NODMA }, |
3027 | "CRD-8480B", NULL, | 3030 | { "WDC AC32500H", NULL, ATA_HORKAGE_NODMA }, |
3028 | "CRD-8482B", NULL, | 3031 | { "WDC AC33100H", NULL, ATA_HORKAGE_NODMA }, |
3029 | "CRD-84", NULL, | 3032 | { "WDC AC31600H", NULL, ATA_HORKAGE_NODMA }, |
3030 | "SanDisk SDP3B", NULL, | 3033 | { "WDC AC32100H", "24.09P07", ATA_HORKAGE_NODMA }, |
3031 | "SanDisk SDP3B-64", NULL, | 3034 | { "WDC AC23200L", "21.10N21", ATA_HORKAGE_NODMA }, |
3032 | "SANYO CD-ROM CRD", NULL, | 3035 | { "Compaq CRD-8241B", NULL, ATA_HORKAGE_NODMA }, |
3033 | "HITACHI CDR-8", NULL, | 3036 | { "CRD-8400B", NULL, ATA_HORKAGE_NODMA }, |
3034 | "HITACHI CDR-8335", NULL, | 3037 | { "CRD-8480B", NULL, ATA_HORKAGE_NODMA }, |
3035 | "HITACHI CDR-8435", NULL, | 3038 | { "CRD-8482B", NULL, ATA_HORKAGE_NODMA }, |
3036 | "Toshiba CD-ROM XM-6202B", NULL, | 3039 | { "CRD-84", NULL, ATA_HORKAGE_NODMA }, |
3037 | "TOSHIBA CD-ROM XM-1702BC", NULL, | 3040 | { "SanDisk SDP3B", NULL, ATA_HORKAGE_NODMA }, |
3038 | "CD-532E-A", NULL, | 3041 | { "SanDisk SDP3B-64", NULL, ATA_HORKAGE_NODMA }, |
3039 | "E-IDE CD-ROM CR-840", NULL, | 3042 | { "SANYO CD-ROM CRD", NULL, ATA_HORKAGE_NODMA }, |
3040 | "CD-ROM Drive/F5A", NULL, | 3043 | { "HITACHI CDR-8", NULL, ATA_HORKAGE_NODMA }, |
3041 | "WPI CDD-820", NULL, | 3044 | { "HITACHI CDR-8335", NULL, ATA_HORKAGE_NODMA }, |
3042 | "SAMSUNG CD-ROM SC-148C", NULL, | 3045 | { "HITACHI CDR-8435", NULL, ATA_HORKAGE_NODMA }, |
3043 | "SAMSUNG CD-ROM SC", NULL, | 3046 | { "Toshiba CD-ROM XM-6202B", NULL, ATA_HORKAGE_NODMA }, |
3044 | "SanDisk SDP3B-64", NULL, | 3047 | { "TOSHIBA CD-ROM XM-1702BC", NULL, ATA_HORKAGE_NODMA }, |
3045 | "ATAPI CD-ROM DRIVE 40X MAXIMUM",NULL, | 3048 | { "CD-532E-A", NULL, ATA_HORKAGE_NODMA }, |
3046 | "_NEC DV5800A", NULL, | 3049 | { "E-IDE CD-ROM CR-840",NULL, ATA_HORKAGE_NODMA }, |
3047 | "SAMSUNG CD-ROM SN-124", "N001" | 3050 | { "CD-ROM Drive/F5A", NULL, ATA_HORKAGE_NODMA }, |
3051 | { "WPI CDD-820", NULL, ATA_HORKAGE_NODMA }, | ||
3052 | { "SAMSUNG CD-ROM SC-148C", NULL, ATA_HORKAGE_NODMA }, | ||
3053 | { "SAMSUNG CD-ROM SC", NULL, ATA_HORKAGE_NODMA }, | ||
3054 | { "SanDisk SDP3B-64", NULL, ATA_HORKAGE_NODMA }, | ||
3055 | { "ATAPI CD-ROM DRIVE 40X MAXIMUM",NULL,ATA_HORKAGE_NODMA }, | ||
3056 | { "_NEC DV5800A", NULL, ATA_HORKAGE_NODMA }, | ||
3057 | { "SAMSUNG CD-ROM SN-124","N001", ATA_HORKAGE_NODMA }, | ||
3058 | |||
3059 | /* Devices we expect to fail diagnostics */ | ||
3060 | |||
3061 | /* Devices where NCQ should be avoided */ | ||
3062 | /* NCQ is slow */ | ||
3063 | { "WDC WD740ADFD-00", NULL, ATA_HORKAGE_NONCQ }, | ||
3064 | |||
3065 | /* Devices with NCQ limits */ | ||
3066 | |||
3067 | /* End Marker */ | ||
3068 | { } | ||
3048 | }; | 3069 | }; |
3049 | 3070 | ||
3050 | static int ata_strim(char *s, size_t len) | 3071 | static int ata_strim(char *s, size_t len) |
@@ -3059,20 +3080,12 @@ static int ata_strim(char *s, size_t len) | |||
3059 | return len; | 3080 | return len; |
3060 | } | 3081 | } |
3061 | 3082 | ||
3062 | static int ata_dma_blacklisted(const struct ata_device *dev) | 3083 | unsigned long ata_device_blacklisted(const struct ata_device *dev) |
3063 | { | 3084 | { |
3064 | unsigned char model_num[40]; | 3085 | unsigned char model_num[40]; |
3065 | unsigned char model_rev[16]; | 3086 | unsigned char model_rev[16]; |
3066 | unsigned int nlen, rlen; | 3087 | unsigned int nlen, rlen; |
3067 | int i; | 3088 | const struct ata_blacklist_entry *ad = ata_device_blacklist; |
3068 | |||
3069 | /* We don't support polling DMA. | ||
3070 | * DMA blacklist those ATAPI devices with CDB-intr (and use PIO) | ||
3071 | * if the LLDD handles only interrupts in the HSM_ST_LAST state. | ||
3072 | */ | ||
3073 | if ((dev->ap->flags & ATA_FLAG_PIO_POLLING) && | ||
3074 | (dev->flags & ATA_DFLAG_CDB_INTR)) | ||
3075 | return 1; | ||
3076 | 3089 | ||
3077 | ata_id_string(dev->id, model_num, ATA_ID_PROD_OFS, | 3090 | ata_id_string(dev->id, model_num, ATA_ID_PROD_OFS, |
3078 | sizeof(model_num)); | 3091 | sizeof(model_num)); |
@@ -3081,17 +3094,30 @@ static int ata_dma_blacklisted(const struct ata_device *dev) | |||
3081 | nlen = ata_strim(model_num, sizeof(model_num)); | 3094 | nlen = ata_strim(model_num, sizeof(model_num)); |
3082 | rlen = ata_strim(model_rev, sizeof(model_rev)); | 3095 | rlen = ata_strim(model_rev, sizeof(model_rev)); |
3083 | 3096 | ||
3084 | for (i = 0; i < ARRAY_SIZE(ata_dma_blacklist); i += 2) { | 3097 | while (ad->model_num) { |
3085 | if (!strncmp(ata_dma_blacklist[i], model_num, nlen)) { | 3098 | if (!strncmp(ad->model_num, model_num, nlen)) { |
3086 | if (ata_dma_blacklist[i+1] == NULL) | 3099 | if (ad->model_rev == NULL) |
3087 | return 1; | 3100 | return ad->horkage; |
3088 | if (!strncmp(ata_dma_blacklist[i], model_rev, rlen)) | 3101 | if (!strncmp(ad->model_rev, model_rev, rlen)) |
3089 | return 1; | 3102 | return ad->horkage; |
3090 | } | 3103 | } |
3104 | ad++; | ||
3091 | } | 3105 | } |
3092 | return 0; | 3106 | return 0; |
3093 | } | 3107 | } |
3094 | 3108 | ||
3109 | static int ata_dma_blacklisted(const struct ata_device *dev) | ||
3110 | { | ||
3111 | /* We don't support polling DMA. | ||
3112 | * DMA blacklist those ATAPI devices with CDB-intr (and use PIO) | ||
3113 | * if the LLDD handles only interrupts in the HSM_ST_LAST state. | ||
3114 | */ | ||
3115 | if ((dev->ap->flags & ATA_FLAG_PIO_POLLING) && | ||
3116 | (dev->flags & ATA_DFLAG_CDB_INTR)) | ||
3117 | return 1; | ||
3118 | return (ata_device_blacklisted(dev) & ATA_HORKAGE_NODMA) ? 1 : 0; | ||
3119 | } | ||
3120 | |||
3095 | /** | 3121 | /** |
3096 | * ata_dev_xfermask - Compute supported xfermask of the given device | 3122 | * ata_dev_xfermask - Compute supported xfermask of the given device |
3097 | * @dev: Device to compute xfermask for | 3123 | * @dev: Device to compute xfermask for |
@@ -6153,6 +6179,7 @@ EXPORT_SYMBOL_GPL(ata_host_suspend); | |||
6153 | EXPORT_SYMBOL_GPL(ata_host_resume); | 6179 | EXPORT_SYMBOL_GPL(ata_host_resume); |
6154 | EXPORT_SYMBOL_GPL(ata_id_string); | 6180 | EXPORT_SYMBOL_GPL(ata_id_string); |
6155 | EXPORT_SYMBOL_GPL(ata_id_c_string); | 6181 | EXPORT_SYMBOL_GPL(ata_id_c_string); |
6182 | EXPORT_SYMBOL_GPL(ata_device_blacklisted); | ||
6156 | EXPORT_SYMBOL_GPL(ata_scsi_simulate); | 6183 | EXPORT_SYMBOL_GPL(ata_scsi_simulate); |
6157 | 6184 | ||
6158 | EXPORT_SYMBOL_GPL(ata_pio_need_iordy); | 6185 | EXPORT_SYMBOL_GPL(ata_pio_need_iordy); |