diff options
| -rw-r--r-- | drivers/ata/libata-core.c | 18 |
1 files changed, 16 insertions, 2 deletions
diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c index 065507c46644..a61af3818c84 100644 --- a/drivers/ata/libata-core.c +++ b/drivers/ata/libata-core.c | |||
| @@ -1231,6 +1231,9 @@ unsigned int ata_dev_classify(const struct ata_taskfile *tf) | |||
| 1231 | * | 1231 | * |
| 1232 | * We follow the current spec and consider that 0x69/0x96 | 1232 | * We follow the current spec and consider that 0x69/0x96 |
| 1233 | * identifies a port multiplier and 0x3c/0xc3 a SEMB device. | 1233 | * identifies a port multiplier and 0x3c/0xc3 a SEMB device. |
| 1234 | * Unfortunately, WDC WD1600JS-62MHB5 (a hard drive) reports | ||
| 1235 | * SEMB signature. This is worked around in | ||
| 1236 | * ata_dev_read_id(). | ||
| 1234 | */ | 1237 | */ |
| 1235 | if ((tf->lbam == 0) && (tf->lbah == 0)) { | 1238 | if ((tf->lbam == 0) && (tf->lbah == 0)) { |
| 1236 | DPRINTK("found ATA device by sig\n"); | 1239 | DPRINTK("found ATA device by sig\n"); |
| @@ -1248,8 +1251,8 @@ unsigned int ata_dev_classify(const struct ata_taskfile *tf) | |||
| 1248 | } | 1251 | } |
| 1249 | 1252 | ||
| 1250 | if ((tf->lbam == 0x3c) && (tf->lbah == 0xc3)) { | 1253 | if ((tf->lbam == 0x3c) && (tf->lbah == 0xc3)) { |
| 1251 | printk(KERN_INFO "ata: SEMB device ignored\n"); | 1254 | DPRINTK("found SEMB device by sig (could be ATA device)\n"); |
| 1252 | return ATA_DEV_SEMB_UNSUP; /* not yet */ | 1255 | return ATA_DEV_SEMB; |
| 1253 | } | 1256 | } |
| 1254 | 1257 | ||
| 1255 | DPRINTK("unknown device\n"); | 1258 | DPRINTK("unknown device\n"); |
| @@ -2080,6 +2083,7 @@ int ata_dev_read_id(struct ata_device *dev, unsigned int *p_class, | |||
| 2080 | struct ata_taskfile tf; | 2083 | struct ata_taskfile tf; |
| 2081 | unsigned int err_mask = 0; | 2084 | unsigned int err_mask = 0; |
| 2082 | const char *reason; | 2085 | const char *reason; |
| 2086 | bool is_semb = class == ATA_DEV_SEMB; | ||
| 2083 | int may_fallback = 1, tried_spinup = 0; | 2087 | int may_fallback = 1, tried_spinup = 0; |
| 2084 | int rc; | 2088 | int rc; |
| 2085 | 2089 | ||
| @@ -2090,6 +2094,8 @@ retry: | |||
| 2090 | ata_tf_init(dev, &tf); | 2094 | ata_tf_init(dev, &tf); |
| 2091 | 2095 | ||
| 2092 | switch (class) { | 2096 | switch (class) { |
| 2097 | case ATA_DEV_SEMB: | ||
| 2098 | class = ATA_DEV_ATA; /* some hard drives report SEMB sig */ | ||
| 2093 | case ATA_DEV_ATA: | 2099 | case ATA_DEV_ATA: |
| 2094 | tf.command = ATA_CMD_ID_ATA; | 2100 | tf.command = ATA_CMD_ID_ATA; |
| 2095 | break; | 2101 | break; |
| @@ -2126,6 +2132,14 @@ retry: | |||
| 2126 | return -ENOENT; | 2132 | return -ENOENT; |
| 2127 | } | 2133 | } |
| 2128 | 2134 | ||
| 2135 | if (is_semb) { | ||
| 2136 | ata_dev_printk(dev, KERN_INFO, "IDENTIFY failed on " | ||
| 2137 | "device w/ SEMB sig, disabled\n"); | ||
| 2138 | /* SEMB is not supported yet */ | ||
| 2139 | *p_class = ATA_DEV_SEMB_UNSUP; | ||
| 2140 | return 0; | ||
| 2141 | } | ||
| 2142 | |||
| 2129 | if ((err_mask == AC_ERR_DEV) && (tf.feature & ATA_ABORTED)) { | 2143 | if ((err_mask == AC_ERR_DEV) && (tf.feature & ATA_ABORTED)) { |
| 2130 | /* Device or controller might have reported | 2144 | /* Device or controller might have reported |
| 2131 | * the wrong device class. Give a shot at the | 2145 | * the wrong device class. Give a shot at the |
