blob: d1445d74e9c3329e0a4ea85ff14f44a644a9d466 [file] [log] [blame]
Thomas Gleixner457c8992019-05-19 13:08:55 +01001// SPDX-License-Identifier: GPL-2.0-only
Linus Torvalds1da177e2005-04-16 15:20:36 -07002/*
Linus Torvalds1da177e2005-04-16 15:20:36 -07003 * Copyright (C) 2000-2002 Andre Hedrick <andre@linux-ide.org>
Alan Coxccd32e22008-11-02 21:40:08 +01004 * Copyright (C) 2003 Red Hat
Linus Torvalds1da177e2005-04-16 15:20:36 -07005 *
6 */
7
Linus Torvalds1da177e2005-04-16 15:20:36 -07008#include <linux/module.h>
9#include <linux/types.h>
10#include <linux/string.h>
11#include <linux/kernel.h>
12#include <linux/timer.h>
13#include <linux/mm.h>
14#include <linux/interrupt.h>
15#include <linux/major.h>
16#include <linux/errno.h>
17#include <linux/genhd.h>
18#include <linux/blkpg.h>
19#include <linux/slab.h>
20#include <linux/pci.h>
21#include <linux/delay.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070022#include <linux/ide.h>
23#include <linux/bitops.h>
Michal Schmidt1e862402006-07-30 03:03:29 -070024#include <linux/nmi.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070025
26#include <asm/byteorder.h>
27#include <asm/irq.h>
Linus Torvalds7c0f6ba2016-12-24 11:46:01 -080028#include <linux/uaccess.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070029#include <asm/io.h>
30
Bartlomiej Zolnierkiewiczed4af482008-07-15 21:21:48 +020031void SELECT_MASK(ide_drive_t *drive, int mask)
Linus Torvalds1da177e2005-04-16 15:20:36 -070032{
Bartlomiej Zolnierkiewiczac95bee2008-04-26 22:25:14 +020033 const struct ide_port_ops *port_ops = drive->hwif->port_ops;
34
35 if (port_ops && port_ops->maskproc)
36 port_ops->maskproc(drive, mask);
Linus Torvalds1da177e2005-04-16 15:20:36 -070037}
38
Bartlomiej Zolnierkiewicz92eb4382008-07-23 19:55:53 +020039u8 ide_read_error(ide_drive_t *drive)
40{
Sergei Shtylyov3153c262009-04-08 14:13:03 +020041 struct ide_taskfile tf;
Bartlomiej Zolnierkiewicz92eb4382008-07-23 19:55:53 +020042
Sergei Shtylyov3153c262009-04-08 14:13:03 +020043 drive->hwif->tp_ops->tf_read(drive, &tf, IDE_VALID_ERROR);
Bartlomiej Zolnierkiewicz92eb4382008-07-23 19:55:53 +020044
Sergei Shtylyov3153c262009-04-08 14:13:03 +020045 return tf.error;
Bartlomiej Zolnierkiewicz92eb4382008-07-23 19:55:53 +020046}
47EXPORT_SYMBOL_GPL(ide_read_error);
48
Bartlomiej Zolnierkiewicz4dde4492008-10-10 22:39:19 +020049void ide_fix_driveid(u16 *id)
Linus Torvalds1da177e2005-04-16 15:20:36 -070050{
51#ifndef __LITTLE_ENDIAN
52# ifdef __BIG_ENDIAN
53 int i;
Linus Torvalds1da177e2005-04-16 15:20:36 -070054
Bartlomiej Zolnierkiewicz48fb2682008-10-10 22:39:19 +020055 for (i = 0; i < 256; i++)
Bartlomiej Zolnierkiewicz5b90e992008-10-10 22:39:18 +020056 id[i] = __le16_to_cpu(id[i]);
Linus Torvalds1da177e2005-04-16 15:20:36 -070057# else
58# error "Please fix <asm/byteorder.h>"
59# endif
60#endif
61}
62
Bartlomiej Zolnierkiewicz01745112007-11-05 21:42:29 +010063/*
64 * ide_fixstring() cleans up and (optionally) byte-swaps a text string,
65 * removing leading/trailing blanks and compressing internal blanks.
66 * It is primarily used to tidy up the model name/number fields as
Bartlomiej Zolnierkiewiczaaaade32008-10-10 22:39:21 +020067 * returned by the ATA_CMD_ID_ATA[PI] commands.
Bartlomiej Zolnierkiewicz01745112007-11-05 21:42:29 +010068 */
69
Bartlomiej Zolnierkiewicz122f06f2009-03-24 23:22:47 +010070void ide_fixstring(u8 *s, const int bytecount, const int byteswap)
Linus Torvalds1da177e2005-04-16 15:20:36 -070071{
Linus Torvalds1a7809e2008-10-10 22:39:22 +020072 u8 *p, *end = &s[bytecount & ~1]; /* bytecount must be even */
Linus Torvalds1da177e2005-04-16 15:20:36 -070073
74 if (byteswap) {
75 /* convert from big-endian to host byte order */
Linus Torvalds1a7809e2008-10-10 22:39:22 +020076 for (p = s ; p != end ; p += 2)
77 be16_to_cpus((u16 *) p);
Linus Torvalds1da177e2005-04-16 15:20:36 -070078 }
Linus Torvalds1a7809e2008-10-10 22:39:22 +020079
Linus Torvalds1da177e2005-04-16 15:20:36 -070080 /* strip leading blanks */
Linus Torvalds1a7809e2008-10-10 22:39:22 +020081 p = s;
Linus Torvalds1da177e2005-04-16 15:20:36 -070082 while (s != end && *s == ' ')
83 ++s;
84 /* compress internal blanks and strip trailing blanks */
85 while (s != end && *s) {
86 if (*s++ != ' ' || (s != end && *s && *s != ' '))
87 *p++ = *(s-1);
88 }
89 /* wipe out trailing garbage */
90 while (p != end)
91 *p++ = '\0';
92}
Linus Torvalds1da177e2005-04-16 15:20:36 -070093EXPORT_SYMBOL(ide_fixstring);
94
Linus Torvalds1da177e2005-04-16 15:20:36 -070095/*
Linus Torvalds1da177e2005-04-16 15:20:36 -070096 * This routine busy-waits for the drive status to be not "busy".
97 * It then checks the status for all of the "good" bits and none
98 * of the "bad" bits, and if all is okay it returns 0. All other
Bartlomiej Zolnierkiewicz74af21c2007-10-13 17:47:49 +020099 * cases return error -- caller may then invoke ide_error().
Linus Torvalds1da177e2005-04-16 15:20:36 -0700100 *
101 * This routine should get fixed to not hog the cpu during extra long waits..
102 * That could be done by busy-waiting for the first jiffy or two, and then
103 * setting a timer to wake up at half second intervals thereafter,
104 * until timeout is achieved, before timing out.
105 */
Bartlomiej Zolnierkiewiczfa56d4c2009-06-23 11:29:11 +0000106int __ide_wait_stat(ide_drive_t *drive, u8 good, u8 bad,
107 unsigned long timeout, u8 *rstat)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700108{
Bartlomiej Zolnierkiewiczb73c7ee2008-07-23 19:55:52 +0200109 ide_hwif_t *hwif = drive->hwif;
Bartlomiej Zolnierkiewicz374e0422008-07-23 19:55:56 +0200110 const struct ide_tp_ops *tp_ops = hwif->tp_ops;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700111 unsigned long flags;
Sebastian Andrzej Siewior47b82e82018-05-04 16:24:46 +0200112 bool irqs_threaded = force_irqthreads;
Bartlomiej Zolnierkiewicz74af21c2007-10-13 17:47:49 +0200113 int i;
114 u8 stat;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700115
116 udelay(1); /* spec allows drive 400ns to assert "BUSY" */
Bartlomiej Zolnierkiewicz374e0422008-07-23 19:55:56 +0200117 stat = tp_ops->read_status(hwif);
Bartlomiej Zolnierkiewiczc47137a2008-02-06 02:57:51 +0100118
Bartlomiej Zolnierkiewicz3a7d2482008-10-10 22:39:21 +0200119 if (stat & ATA_BUSY) {
Sebastian Andrzej Siewior47b82e82018-05-04 16:24:46 +0200120 if (!irqs_threaded) {
121 local_save_flags(flags);
122 local_irq_enable_in_hardirq();
123 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700124 timeout += jiffies;
Bartlomiej Zolnierkiewicz3a7d2482008-10-10 22:39:21 +0200125 while ((stat = tp_ops->read_status(hwif)) & ATA_BUSY) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700126 if (time_after(jiffies, timeout)) {
127 /*
128 * One last read after the timeout in case
129 * heavy interrupt load made us not make any
130 * progress during the timeout..
131 */
Bartlomiej Zolnierkiewicz374e0422008-07-23 19:55:56 +0200132 stat = tp_ops->read_status(hwif);
Bartlomiej Zolnierkiewicz3a7d2482008-10-10 22:39:21 +0200133 if ((stat & ATA_BUSY) == 0)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700134 break;
135
Sebastian Andrzej Siewior47b82e82018-05-04 16:24:46 +0200136 if (!irqs_threaded)
137 local_irq_restore(flags);
Bartlomiej Zolnierkiewicz74af21c2007-10-13 17:47:49 +0200138 *rstat = stat;
139 return -EBUSY;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700140 }
141 }
Sebastian Andrzej Siewior47b82e82018-05-04 16:24:46 +0200142 if (!irqs_threaded)
143 local_irq_restore(flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700144 }
145 /*
146 * Allow status to settle, then read it again.
147 * A few rare drives vastly violate the 400ns spec here,
148 * so we'll wait up to 10usec for a "good" status
149 * rather than expensively fail things immediately.
150 * This fix courtesy of Matthew Faupel & Niccolo Rigacci.
151 */
152 for (i = 0; i < 10; i++) {
153 udelay(1);
Bartlomiej Zolnierkiewicz374e0422008-07-23 19:55:56 +0200154 stat = tp_ops->read_status(hwif);
Bartlomiej Zolnierkiewiczc47137a2008-02-06 02:57:51 +0100155
156 if (OK_STAT(stat, good, bad)) {
Bartlomiej Zolnierkiewicz74af21c2007-10-13 17:47:49 +0200157 *rstat = stat;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700158 return 0;
Bartlomiej Zolnierkiewicz74af21c2007-10-13 17:47:49 +0200159 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700160 }
Bartlomiej Zolnierkiewicz74af21c2007-10-13 17:47:49 +0200161 *rstat = stat;
162 return -EFAULT;
163}
164
165/*
166 * In case of error returns error value after doing "*startstop = ide_error()".
167 * The caller should return the updated value of "startstop" in this case,
168 * "startstop" is unchanged when the function returns 0.
169 */
Bartlomiej Zolnierkiewicz122f06f2009-03-24 23:22:47 +0100170int ide_wait_stat(ide_startstop_t *startstop, ide_drive_t *drive, u8 good,
171 u8 bad, unsigned long timeout)
Bartlomiej Zolnierkiewicz74af21c2007-10-13 17:47:49 +0200172{
173 int err;
174 u8 stat;
175
176 /* bail early if we've exceeded max_failures */
177 if (drive->max_failures && (drive->failures > drive->max_failures)) {
178 *startstop = ide_stopped;
179 return 1;
180 }
181
182 err = __ide_wait_stat(drive, good, bad, timeout, &stat);
183
184 if (err) {
185 char *s = (err == -EBUSY) ? "status timeout" : "status error";
186 *startstop = ide_error(drive, s, stat);
187 }
188
189 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700190}
Linus Torvalds1da177e2005-04-16 15:20:36 -0700191EXPORT_SYMBOL(ide_wait_stat);
192
Bartlomiej Zolnierkiewicza5b7e702007-08-20 22:42:56 +0200193/**
194 * ide_in_drive_list - look for drive in black/white list
195 * @id: drive identifier
Bartlomiej Zolnierkiewicz4dde4492008-10-10 22:39:19 +0200196 * @table: list to inspect
Bartlomiej Zolnierkiewicza5b7e702007-08-20 22:42:56 +0200197 *
198 * Look for a drive in the blacklist and the whitelist tables
199 * Returns 1 if the drive is found in the table.
200 */
201
Bartlomiej Zolnierkiewicz4dde4492008-10-10 22:39:19 +0200202int ide_in_drive_list(u16 *id, const struct drive_list_entry *table)
Bartlomiej Zolnierkiewicza5b7e702007-08-20 22:42:56 +0200203{
Bartlomiej Zolnierkiewicz4dde4492008-10-10 22:39:19 +0200204 for ( ; table->id_model; table++)
205 if ((!strcmp(table->id_model, (char *)&id[ATA_ID_PROD])) &&
206 (!table->id_firmware ||
207 strstr((char *)&id[ATA_ID_FW_REV], table->id_firmware)))
Bartlomiej Zolnierkiewicza5b7e702007-08-20 22:42:56 +0200208 return 1;
209 return 0;
210}
Bartlomiej Zolnierkiewiczb0244a02007-08-20 22:42:57 +0200211EXPORT_SYMBOL_GPL(ide_in_drive_list);
212
Bartlomiej Zolnierkiewicza5b7e702007-08-20 22:42:56 +0200213/*
214 * Early UDMA66 devices don't set bit14 to 1, only bit13 is valid.
Bartlomiej Zolnierkiewicz8588a2b72007-10-26 20:31:16 +0200215 * Some optical devices with the buggy firmwares have the same problem.
Bartlomiej Zolnierkiewicza5b7e702007-08-20 22:42:56 +0200216 */
217static const struct drive_list_entry ivb_list[] = {
218 { "QUANTUM FIREBALLlct10 05" , "A03.0900" },
Bartlomiej Zolnierkiewiczba9413b2009-06-23 16:11:10 -0700219 { "QUANTUM FIREBALLlct20 30" , "APL.0900" },
Bartlomiej Zolnierkiewicz8588a2b72007-10-26 20:31:16 +0200220 { "TSSTcorp CDDVDW SH-S202J" , "SB00" },
Peter Missele97564f2007-11-27 21:35:57 +0100221 { "TSSTcorp CDDVDW SH-S202J" , "SB01" },
222 { "TSSTcorp CDDVDW SH-S202N" , "SB00" },
223 { "TSSTcorp CDDVDW SH-S202N" , "SB01" },
Alexander Smal3ced5c42008-04-28 23:44:43 +0200224 { "TSSTcorp CDDVDW SH-S202H" , "SB00" },
225 { "TSSTcorp CDDVDW SH-S202H" , "SB01" },
Bartlomiej Zolnierkiewiczc7b997b2008-12-02 20:40:03 +0100226 { "SAMSUNG SP0822N" , "WA100-10" },
Bartlomiej Zolnierkiewicza5b7e702007-08-20 22:42:56 +0200227 { NULL , NULL }
228};
229
Linus Torvalds1da177e2005-04-16 15:20:36 -0700230/*
231 * All hosts that use the 80c ribbon must use!
232 * The name is derived from upper byte of word 93 and the 80c ribbon.
233 */
Bartlomiej Zolnierkiewicz122f06f2009-03-24 23:22:47 +0100234u8 eighty_ninty_three(ide_drive_t *drive)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700235{
Bartlomiej Zolnierkiewicz7f8f48a2007-05-10 00:01:10 +0200236 ide_hwif_t *hwif = drive->hwif;
Bartlomiej Zolnierkiewicz4dde4492008-10-10 22:39:19 +0200237 u16 *id = drive->id;
Bartlomiej Zolnierkiewicza5b7e702007-08-20 22:42:56 +0200238 int ivb = ide_in_drive_list(id, ivb_list);
Bartlomiej Zolnierkiewicz7f8f48a2007-05-10 00:01:10 +0200239
Bartlomiej Zolnierkiewicz76937fa72010-01-18 07:19:44 +0000240 if (hwif->cbl == ATA_CBL_SATA || hwif->cbl == ATA_CBL_PATA40_SHORT)
Bartlomiej Zolnierkiewicz49521f92007-07-09 23:17:58 +0200241 return 1;
242
Bartlomiej Zolnierkiewicza5b7e702007-08-20 22:42:56 +0200243 if (ivb)
244 printk(KERN_DEBUG "%s: skipping word 93 validity check\n",
245 drive->name);
246
Bartlomiej Zolnierkiewicz367d7e72008-10-10 22:39:30 +0200247 if (ata_id_is_sata(id) && !ivb)
George Kibardinb98f8802008-01-10 23:03:42 +0100248 return 1;
249
Bartlomiej Zolnierkiewicza5b7e702007-08-20 22:42:56 +0200250 if (hwif->cbl != ATA_CBL_PATA80 && !ivb)
Bartlomiej Zolnierkiewicz7f8f48a2007-05-10 00:01:10 +0200251 goto no_80w;
Alan Cox1a1276e2006-06-28 04:26:58 -0700252
Bartlomiej Zolnierkiewiczf68d9322007-03-26 23:03:18 +0200253 /*
254 * FIXME:
Bartlomiej Zolnierkiewiczf367bed2008-03-29 19:48:21 +0100255 * - change master/slave IDENTIFY order
Bartlomiej Zolnierkiewicza5b7e702007-08-20 22:42:56 +0200256 * - force bit13 (80c cable present) check also for !ivb devices
Bartlomiej Zolnierkiewiczf68d9322007-03-26 23:03:18 +0200257 * (unless the slave device is pre-ATA3)
258 */
Bartlomiej Zolnierkiewicz8369d5f2009-05-22 16:23:36 +0200259 if (id[ATA_ID_HW_CONFIG] & 0x4000)
Bartlomiej Zolnierkiewicz7f8f48a2007-05-10 00:01:10 +0200260 return 1;
261
Bartlomiej Zolnierkiewicz8369d5f2009-05-22 16:23:36 +0200262 if (ivb) {
263 const char *model = (char *)&id[ATA_ID_PROD];
264
265 if (strstr(model, "TSSTcorp CDDVDW SH-S202")) {
266 /*
267 * These ATAPI devices always report 80c cable
268 * so we have to depend on the host in this case.
269 */
270 if (hwif->cbl == ATA_CBL_PATA80)
271 return 1;
272 } else {
273 /* Depend on the device side cable detection. */
274 if (id[ATA_ID_HW_CONFIG] & 0x2000)
275 return 1;
276 }
277 }
Bartlomiej Zolnierkiewicz7f8f48a2007-05-10 00:01:10 +0200278no_80w:
Bartlomiej Zolnierkiewicz97100fc2008-10-13 21:39:36 +0200279 if (drive->dev_flags & IDE_DFLAG_UDMA33_WARNED)
Bartlomiej Zolnierkiewicz7f8f48a2007-05-10 00:01:10 +0200280 return 0;
281
282 printk(KERN_WARNING "%s: %s side 80-wire cable detection failed, "
283 "limiting max speed to UDMA33\n",
Bartlomiej Zolnierkiewicz49521f92007-07-09 23:17:58 +0200284 drive->name,
285 hwif->cbl == ATA_CBL_PATA80 ? "drive" : "host");
Bartlomiej Zolnierkiewicz7f8f48a2007-05-10 00:01:10 +0200286
Bartlomiej Zolnierkiewicz97100fc2008-10-13 21:39:36 +0200287 drive->dev_flags |= IDE_DFLAG_UDMA33_WARNED;
Bartlomiej Zolnierkiewicz7f8f48a2007-05-10 00:01:10 +0200288
289 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700290}
291
Bartlomiej Zolnierkiewicz8bc1e5a2009-06-07 15:37:09 +0200292static const char *nien_quirk_list[] = {
293 "QUANTUM FIREBALLlct08 08",
294 "QUANTUM FIREBALLP KA6.4",
295 "QUANTUM FIREBALLP KA9.1",
296 "QUANTUM FIREBALLP KX13.6",
297 "QUANTUM FIREBALLP KX20.5",
298 "QUANTUM FIREBALLP KX27.3",
299 "QUANTUM FIREBALLP LM20.4",
300 "QUANTUM FIREBALLP LM20.5",
Wu Zhangjina2d10562009-09-15 01:36:25 -0700301 "FUJITSU MHZ2160BH G2",
Bartlomiej Zolnierkiewicz8bc1e5a2009-06-07 15:37:09 +0200302 NULL
303};
304
305void ide_check_nien_quirk_list(ide_drive_t *drive)
306{
307 const char **list, *m = (char *)&drive->id[ATA_ID_PROD];
308
309 for (list = nien_quirk_list; *list != NULL; list++)
310 if (strstr(m, *list) != NULL) {
Bartlomiej Zolnierkiewicz734affd2009-06-07 15:37:10 +0200311 drive->dev_flags |= IDE_DFLAG_NIEN_QUIRK;
Bartlomiej Zolnierkiewicz8bc1e5a2009-06-07 15:37:09 +0200312 return;
313 }
Bartlomiej Zolnierkiewicz8bc1e5a2009-06-07 15:37:09 +0200314}
315
Bartlomiej Zolnierkiewicz8a455132007-10-20 00:32:36 +0200316int ide_driveid_update(ide_drive_t *drive)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700317{
Bartlomiej Zolnierkiewicz4dde4492008-10-10 22:39:19 +0200318 u16 *id;
Bartlomiej Zolnierkiewicz2ebe1d92009-03-24 23:22:59 +0100319 int rc;
Bartlomiej Zolnierkiewicz2f40c9b2009-03-24 23:22:54 +0100320
321 id = kmalloc(SECTOR_SIZE, GFP_ATOMIC);
322 if (id == NULL)
323 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700324
Linus Torvalds1da177e2005-04-16 15:20:36 -0700325 SELECT_MASK(drive, 1);
Bartlomiej Zolnierkiewiczfa56d4c2009-06-23 11:29:11 +0000326 rc = ide_dev_read_id(drive, ATA_CMD_ID_ATA, id, 1);
Bartlomiej Zolnierkiewiczf323b802009-03-24 23:22:58 +0100327 SELECT_MASK(drive, 0);
328
Bartlomiej Zolnierkiewicz2ebe1d92009-03-24 23:22:59 +0100329 if (rc)
330 goto out_err;
331
Bartlomiej Zolnierkiewicz4dde4492008-10-10 22:39:19 +0200332 drive->id[ATA_ID_UDMA_MODES] = id[ATA_ID_UDMA_MODES];
333 drive->id[ATA_ID_MWDMA_MODES] = id[ATA_ID_MWDMA_MODES];
334 drive->id[ATA_ID_SWDMA_MODES] = id[ATA_ID_SWDMA_MODES];
Sergei Shtylyov74638c82009-03-31 20:15:28 +0200335 drive->id[ATA_ID_CFA_MODES] = id[ATA_ID_CFA_MODES];
Bartlomiej Zolnierkiewicz4dde4492008-10-10 22:39:19 +0200336 /* anything more ? */
337
338 kfree(id);
339
Linus Torvalds1da177e2005-04-16 15:20:36 -0700340 return 1;
Bartlomiej Zolnierkiewicz2f40c9b2009-03-24 23:22:54 +0100341out_err:
Bartlomiej Zolnierkiewicz2f40c9b2009-03-24 23:22:54 +0100342 if (rc == 2)
343 printk(KERN_ERR "%s: %s: bad status\n", drive->name, __func__);
344 kfree(id);
345 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700346}
347
Bartlomiej Zolnierkiewicz74af21c2007-10-13 17:47:49 +0200348int ide_config_drive_speed(ide_drive_t *drive, u8 speed)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700349{
Bartlomiej Zolnierkiewicz74af21c2007-10-13 17:47:49 +0200350 ide_hwif_t *hwif = drive->hwif;
Bartlomiej Zolnierkiewicz374e0422008-07-23 19:55:56 +0200351 const struct ide_tp_ops *tp_ops = hwif->tp_ops;
Sergei Shtylyovc9ff9e72009-04-08 14:13:03 +0200352 struct ide_taskfile tf;
Bartlomiej Zolnierkiewicz4dde4492008-10-10 22:39:19 +0200353 u16 *id = drive->id, i;
Sergei Shtylyov89613e662007-11-27 21:35:52 +0100354 int error = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700355 u8 stat;
356
Linus Torvalds1da177e2005-04-16 15:20:36 -0700357#ifdef CONFIG_BLK_DEV_IDEDMA
Bartlomiej Zolnierkiewicz5e37bdc2008-04-26 22:25:24 +0200358 if (hwif->dma_ops) /* check if host supports DMA */
359 hwif->dma_ops->dma_host_set(drive, 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700360#endif
361
Sergei Shtylyov89613e662007-11-27 21:35:52 +0100362 /* Skip setting PIO flow-control modes on pre-EIDE drives */
Bartlomiej Zolnierkiewicz48fb2682008-10-10 22:39:19 +0200363 if ((speed & 0xf8) == XFER_PIO_0 && ata_id_has_iordy(drive->id) == 0)
Sergei Shtylyov89613e662007-11-27 21:35:52 +0100364 goto skip;
365
Linus Torvalds1da177e2005-04-16 15:20:36 -0700366 /*
367 * Don't use ide_wait_cmd here - it will
368 * attempt to set_geometry and recalibrate,
369 * but for some reason these don't work at
370 * this point (lost interrupt).
371 */
Bartlomiej Zolnierkiewiczee1b1cc2009-03-24 23:22:47 +0100372
Linus Torvalds1da177e2005-04-16 15:20:36 -0700373 udelay(1);
Sergei Shtylyovfdd88f02009-03-31 20:15:33 +0200374 tp_ops->dev_select(drive);
Sergei Shtylyove5403bf2008-10-17 18:09:15 +0200375 SELECT_MASK(drive, 1);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700376 udelay(1);
Sergei Shtylyovecf3a312009-03-31 20:15:30 +0200377 tp_ops->write_devctl(hwif, ATA_NIEN | ATA_DEVCTL_OBS);
Bartlomiej Zolnierkiewicz59be2c82008-07-23 19:55:52 +0200378
Sergei Shtylyovc9ff9e72009-04-08 14:13:03 +0200379 memset(&tf, 0, sizeof(tf));
380 tf.feature = SETFEATURES_XFER;
381 tf.nsect = speed;
Bartlomiej Zolnierkiewicz59be2c82008-07-23 19:55:52 +0200382
Sergei Shtylyovc9ff9e72009-04-08 14:13:03 +0200383 tp_ops->tf_load(drive, &tf, IDE_VALID_FEATURE | IDE_VALID_NSECT);
Bartlomiej Zolnierkiewicz59be2c82008-07-23 19:55:52 +0200384
Bartlomiej Zolnierkiewiczaaaade32008-10-10 22:39:21 +0200385 tp_ops->exec_command(hwif, ATA_CMD_SET_FEATURES);
Bartlomiej Zolnierkiewicz59be2c82008-07-23 19:55:52 +0200386
Bartlomiej Zolnierkiewicz734affd2009-06-07 15:37:10 +0200387 if (drive->dev_flags & IDE_DFLAG_NIEN_QUIRK)
Sergei Shtylyovecf3a312009-03-31 20:15:30 +0200388 tp_ops->write_devctl(hwif, ATA_DEVCTL_OBS);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700389
Bartlomiej Zolnierkiewicz74af21c2007-10-13 17:47:49 +0200390 error = __ide_wait_stat(drive, drive->ready_stat,
Bartlomiej Zolnierkiewicz3a7d2482008-10-10 22:39:21 +0200391 ATA_BUSY | ATA_DRQ | ATA_ERR,
Bartlomiej Zolnierkiewicz74af21c2007-10-13 17:47:49 +0200392 WAIT_CMD, &stat);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700393
394 SELECT_MASK(drive, 0);
395
Linus Torvalds1da177e2005-04-16 15:20:36 -0700396 if (error) {
397 (void) ide_dump_status(drive, "set_drive_speed_status", stat);
398 return error;
399 }
400
Sergei Shtylyovc4199932009-03-31 20:15:27 +0200401 if (speed >= XFER_SW_DMA_0) {
402 id[ATA_ID_UDMA_MODES] &= ~0xFF00;
403 id[ATA_ID_MWDMA_MODES] &= ~0x0700;
404 id[ATA_ID_SWDMA_MODES] &= ~0x0700;
Sergei Shtylyov74638c82009-03-31 20:15:28 +0200405 if (ata_id_is_cfa(id))
406 id[ATA_ID_CFA_MODES] &= ~0x0E00;
407 } else if (ata_id_is_cfa(id))
408 id[ATA_ID_CFA_MODES] &= ~0x01C0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700409
Sergei Shtylyov89613e662007-11-27 21:35:52 +0100410 skip:
Linus Torvalds1da177e2005-04-16 15:20:36 -0700411#ifdef CONFIG_BLK_DEV_IDEDMA
Bartlomiej Zolnierkiewicz97100fc2008-10-13 21:39:36 +0200412 if (speed >= XFER_SW_DMA_0 && (drive->dev_flags & IDE_DFLAG_USING_DMA))
Bartlomiej Zolnierkiewicz5e37bdc2008-04-26 22:25:24 +0200413 hwif->dma_ops->dma_host_set(drive, 1);
414 else if (hwif->dma_ops) /* check if host supports DMA */
Bartlomiej Zolnierkiewicz4a546e02008-01-26 20:13:01 +0100415 ide_dma_off_quietly(drive);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700416#endif
417
Bartlomiej Zolnierkiewicz4dde4492008-10-10 22:39:19 +0200418 if (speed >= XFER_UDMA_0) {
419 i = 1 << (speed - XFER_UDMA_0);
420 id[ATA_ID_UDMA_MODES] |= (i << 8 | i);
Sergei Shtylyov74638c82009-03-31 20:15:28 +0200421 } else if (ata_id_is_cfa(id) && speed >= XFER_MW_DMA_3) {
422 i = speed - XFER_MW_DMA_2;
423 id[ATA_ID_CFA_MODES] |= i << 9;
Bartlomiej Zolnierkiewicz4dde4492008-10-10 22:39:19 +0200424 } else if (speed >= XFER_MW_DMA_0) {
425 i = 1 << (speed - XFER_MW_DMA_0);
426 id[ATA_ID_MWDMA_MODES] |= (i << 8 | i);
427 } else if (speed >= XFER_SW_DMA_0) {
428 i = 1 << (speed - XFER_SW_DMA_0);
429 id[ATA_ID_SWDMA_MODES] |= (i << 8 | i);
Sergei Shtylyov74638c82009-03-31 20:15:28 +0200430 } else if (ata_id_is_cfa(id) && speed >= XFER_PIO_5) {
431 i = speed - XFER_PIO_4;
432 id[ATA_ID_CFA_MODES] |= i << 6;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700433 }
Bartlomiej Zolnierkiewicz4dde4492008-10-10 22:39:19 +0200434
Linus Torvalds1da177e2005-04-16 15:20:36 -0700435 if (!drive->init_speed)
436 drive->init_speed = speed;
437 drive->current_speed = speed;
438 return error;
439}
440
Linus Torvalds1da177e2005-04-16 15:20:36 -0700441/*
442 * This should get invoked any time we exit the driver to
443 * wait for an interrupt response from a drive. handler() points
444 * at the appropriate code to handle the next interrupt, and a
445 * timer is started to prevent us from waiting forever in case
446 * something goes wrong (see the ide_timer_expiry() handler later on).
447 *
448 * See also ide_execute_command
449 */
Bartlomiej Zolnierkiewicz327fa1c2009-03-24 23:22:47 +0100450void __ide_set_handler(ide_drive_t *drive, ide_handler_t *handler,
Bartlomiej Zolnierkiewicz60c0cd02009-03-27 12:46:46 +0100451 unsigned int timeout)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700452{
Bartlomiej Zolnierkiewiczb65fac32009-01-06 17:20:50 +0100453 ide_hwif_t *hwif = drive->hwif;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700454
Bartlomiej Zolnierkiewiczb65fac32009-01-06 17:20:50 +0100455 BUG_ON(hwif->handler);
456 hwif->handler = handler;
Bartlomiej Zolnierkiewiczb65fac32009-01-06 17:20:50 +0100457 hwif->timer.expires = jiffies + timeout;
458 hwif->req_gen_timer = hwif->req_gen;
459 add_timer(&hwif->timer);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700460}
461
Bartlomiej Zolnierkiewicz60c0cd02009-03-27 12:46:46 +0100462void ide_set_handler(ide_drive_t *drive, ide_handler_t *handler,
463 unsigned int timeout)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700464{
Bartlomiej Zolnierkiewiczb65fac32009-01-06 17:20:50 +0100465 ide_hwif_t *hwif = drive->hwif;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700466 unsigned long flags;
Bartlomiej Zolnierkiewicz2a2ca6a2008-12-29 20:27:31 +0100467
Bartlomiej Zolnierkiewiczb65fac32009-01-06 17:20:50 +0100468 spin_lock_irqsave(&hwif->lock, flags);
Bartlomiej Zolnierkiewicz60c0cd02009-03-27 12:46:46 +0100469 __ide_set_handler(drive, handler, timeout);
Bartlomiej Zolnierkiewiczb65fac32009-01-06 17:20:50 +0100470 spin_unlock_irqrestore(&hwif->lock, flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700471}
Linus Torvalds1da177e2005-04-16 15:20:36 -0700472EXPORT_SYMBOL(ide_set_handler);
Bartlomiej Zolnierkiewicz122f06f2009-03-24 23:22:47 +0100473
Linus Torvalds1da177e2005-04-16 15:20:36 -0700474/**
475 * ide_execute_command - execute an IDE command
476 * @drive: IDE drive to issue the command against
Bartlomiej Zolnierkiewicz35b5d0b2009-03-27 12:46:47 +0100477 * @cmd: command
Linus Torvalds1da177e2005-04-16 15:20:36 -0700478 * @handler: handler for next phase
479 * @timeout: timeout for command
Linus Torvalds1da177e2005-04-16 15:20:36 -0700480 *
481 * Helper function to issue an IDE command. This handles the
Bartlomiej Zolnierkiewicz122f06f2009-03-24 23:22:47 +0100482 * atomicity requirements, command timing and ensures that the
Linus Torvalds1da177e2005-04-16 15:20:36 -0700483 * handler and IRQ setup do not race. All IDE command kick off
484 * should go via this function or do equivalent locking.
485 */
Bartlomiej Zolnierkiewiczcd2a2d92008-01-25 22:17:06 +0100486
Bartlomiej Zolnierkiewicz35b5d0b2009-03-27 12:46:47 +0100487void ide_execute_command(ide_drive_t *drive, struct ide_cmd *cmd,
488 ide_handler_t *handler, unsigned timeout)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700489{
Bartlomiej Zolnierkiewicz2a2ca6a2008-12-29 20:27:31 +0100490 ide_hwif_t *hwif = drive->hwif;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700491 unsigned long flags;
Bartlomiej Zolnierkiewicz629f9442008-02-02 19:56:46 +0100492
Bartlomiej Zolnierkiewiczb65fac32009-01-06 17:20:50 +0100493 spin_lock_irqsave(&hwif->lock, flags);
Bartlomiej Zolnierkiewicz35b5d0b2009-03-27 12:46:47 +0100494 if ((cmd->protocol != ATAPI_PROT_DMA &&
495 cmd->protocol != ATAPI_PROT_PIO) ||
496 (drive->atapi_flags & IDE_AFLAG_DRQ_INTERRUPT))
497 __ide_set_handler(drive, handler, timeout);
498 hwif->tp_ops->exec_command(hwif, cmd->tf.command);
Bartlomiej Zolnierkiewicz629f9442008-02-02 19:56:46 +0100499 /*
500 * Drive takes 400nS to respond, we must avoid the IRQ being
501 * serviced before that.
502 *
503 * FIXME: we could skip this delay with care on non shared devices
504 */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700505 ndelay(400);
Bartlomiej Zolnierkiewiczb65fac32009-01-06 17:20:50 +0100506 spin_unlock_irqrestore(&hwif->lock, flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700507}
Linus Torvalds1da177e2005-04-16 15:20:36 -0700508
Linus Torvalds1da177e2005-04-16 15:20:36 -0700509/*
510 * ide_wait_not_busy() waits for the currently selected device on the hwif
Bartlomiej Zolnierkiewicz9d501522008-02-01 23:09:36 +0100511 * to report a non-busy status, see comments in ide_probe_port().
Linus Torvalds1da177e2005-04-16 15:20:36 -0700512 */
513int ide_wait_not_busy(ide_hwif_t *hwif, unsigned long timeout)
514{
515 u8 stat = 0;
516
Bartlomiej Zolnierkiewicz122f06f2009-03-24 23:22:47 +0100517 while (timeout--) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700518 /*
519 * Turn this into a schedule() sleep once I'm sure
520 * about locking issues (2.5 work ?).
521 */
522 mdelay(1);
Bartlomiej Zolnierkiewicz374e0422008-07-23 19:55:56 +0200523 stat = hwif->tp_ops->read_status(hwif);
Bartlomiej Zolnierkiewicz3a7d2482008-10-10 22:39:21 +0200524 if ((stat & ATA_BUSY) == 0)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700525 return 0;
526 /*
527 * Assume a value of 0xff means nothing is connected to
528 * the interface and it doesn't implement the pull-down
529 * resistor on D7.
530 */
531 if (stat == 0xff)
532 return -ENODEV;
Ingo Molnar6842f8c2006-02-03 03:04:55 -0800533 touch_softlockup_watchdog();
Michal Schmidt1e862402006-07-30 03:03:29 -0700534 touch_nmi_watchdog();
Linus Torvalds1da177e2005-04-16 15:20:36 -0700535 }
536 return -EBUSY;
537}