aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/ata
diff options
context:
space:
mode:
authorAlan Cox <alan@lxorguk.ukuu.org.uk>2006-10-27 22:08:46 -0400
committerJeff Garzik <jeff@garzik.org>2006-12-01 22:40:28 -0500
commit6919a0a6cfdad9e83d02cef5973826acd416560c (patch)
tree7f3d444c1c12077efe0824b8cb02b78a877c16d2 /drivers/ata
parentfbbb262d9ea9bdbd79d7058271560e9990bc62d3 (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.c123
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
3017static const char * const ata_dma_blacklist [] = { 3020struct 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", 3026static 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
3050static int ata_strim(char *s, size_t len) 3071static 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
3062static int ata_dma_blacklisted(const struct ata_device *dev) 3083unsigned 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
3109static 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);
6153EXPORT_SYMBOL_GPL(ata_host_resume); 6179EXPORT_SYMBOL_GPL(ata_host_resume);
6154EXPORT_SYMBOL_GPL(ata_id_string); 6180EXPORT_SYMBOL_GPL(ata_id_string);
6155EXPORT_SYMBOL_GPL(ata_id_c_string); 6181EXPORT_SYMBOL_GPL(ata_id_c_string);
6182EXPORT_SYMBOL_GPL(ata_device_blacklisted);
6156EXPORT_SYMBOL_GPL(ata_scsi_simulate); 6183EXPORT_SYMBOL_GPL(ata_scsi_simulate);
6157 6184
6158EXPORT_SYMBOL_GPL(ata_pio_need_iordy); 6185EXPORT_SYMBOL_GPL(ata_pio_need_iordy);