Blame view
drivers/ide/ide-timings.c
6.5 KB
1da177e4c Linux-2.6.12-rc2 |
1 |
/* |
1da177e4c Linux-2.6.12-rc2 |
2 |
* Copyright (c) 1999-2001 Vojtech Pavlik |
c9d6c1a23 ide: move ide_pio... |
3 |
* Copyright (c) 2007-2008 Bartlomiej Zolnierkiewicz |
2c139e7a7 ide: checkpatch.p... |
4 |
* |
1da177e4c Linux-2.6.12-rc2 |
5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
* This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * Should you need to contact me, the author, you can do so either by * e-mail - mail your message to <vojtech@ucw.cz>, or by paper mail: * Vojtech Pavlik, Simunkova 1594, Prague 8, 182 00 Czech Republic */ |
2665b891c [PATCH] janitor: ... |
23 |
#include <linux/kernel.h> |
f06ab3402 ide: convert ide-... |
24 25 |
#include <linux/ide.h> #include <linux/module.h> |
1da177e4c Linux-2.6.12-rc2 |
26 |
|
1da177e4c Linux-2.6.12-rc2 |
27 28 29 30 |
/* * PIO 0-5, MWDMA 0-2 and UDMA 0-6 timings (in nanoseconds). * These were taken from ATA/ATAPI-6 standard, rev 0a, except * for PIO 5, which is a nonstandard extension and UDMA6, which |
2c139e7a7 ide: checkpatch.p... |
31 |
* is currently supported only by Maxtor drives. |
1da177e4c Linux-2.6.12-rc2 |
32 33 34 35 36 37 38 39 40 41 42 43 |
*/ static struct ide_timing ide_timing[] = { { XFER_UDMA_6, 0, 0, 0, 0, 0, 0, 0, 15 }, { XFER_UDMA_5, 0, 0, 0, 0, 0, 0, 0, 20 }, { XFER_UDMA_4, 0, 0, 0, 0, 0, 0, 0, 30 }, { XFER_UDMA_3, 0, 0, 0, 0, 0, 0, 0, 45 }, { XFER_UDMA_2, 0, 0, 0, 0, 0, 0, 0, 60 }, { XFER_UDMA_1, 0, 0, 0, 0, 0, 0, 0, 80 }, { XFER_UDMA_0, 0, 0, 0, 0, 0, 0, 0, 120 }, |
74638c848 ide: add support ... |
44 45 |
{ XFER_MW_DMA_4, 25, 0, 0, 0, 55, 20, 80, 0 }, { XFER_MW_DMA_3, 25, 0, 0, 0, 65, 25, 100, 0 }, |
1da177e4c Linux-2.6.12-rc2 |
46 47 48 |
{ XFER_MW_DMA_2, 25, 0, 0, 0, 70, 25, 120, 0 }, { XFER_MW_DMA_1, 45, 0, 0, 0, 80, 50, 150, 0 }, { XFER_MW_DMA_0, 60, 0, 0, 0, 215, 215, 480, 0 }, |
f0ffc9872 ide: remove unuse... |
49 |
|
1da177e4c Linux-2.6.12-rc2 |
50 51 52 |
{ XFER_SW_DMA_2, 60, 0, 0, 0, 120, 120, 240, 0 }, { XFER_SW_DMA_1, 90, 0, 0, 0, 240, 240, 480, 0 }, { XFER_SW_DMA_0, 120, 0, 0, 0, 480, 480, 960, 0 }, |
74638c848 ide: add support ... |
53 54 |
{ XFER_PIO_6, 10, 55, 20, 80, 55, 20, 80, 0 }, { XFER_PIO_5, 15, 65, 25, 100, 65, 25, 100, 0 }, |
1da177e4c Linux-2.6.12-rc2 |
55 56 57 58 59 60 61 62 |
{ XFER_PIO_4, 25, 70, 25, 120, 70, 25, 120, 0 }, { XFER_PIO_3, 30, 80, 70, 180, 80, 70, 180, 0 }, { XFER_PIO_2, 30, 290, 40, 330, 100, 90, 240, 0 }, { XFER_PIO_1, 50, 290, 93, 383, 125, 100, 383, 0 }, { XFER_PIO_0, 70, 290, 240, 600, 165, 150, 600, 0 }, { XFER_PIO_SLOW, 120, 290, 240, 960, 290, 240, 960, 0 }, |
71d516142 ide: use u8 for x... |
63 |
{ 0xff } |
1da177e4c Linux-2.6.12-rc2 |
64 |
}; |
f06ab3402 ide: convert ide-... |
65 66 67 68 69 70 71 72 73 74 |
struct ide_timing *ide_timing_find_mode(u8 speed) { struct ide_timing *t; for (t = ide_timing; t->mode != speed; t++) if (t->mode == 0xff) return NULL; return t; } EXPORT_SYMBOL_GPL(ide_timing_find_mode); |
c9d6c1a23 ide: move ide_pio... |
75 76 |
u16 ide_pio_cycle_time(ide_drive_t *drive, u8 pio) { |
4dde4492d ide: make drive->... |
77 |
u16 *id = drive->id; |
c9d6c1a23 ide: move ide_pio... |
78 79 |
struct ide_timing *t = ide_timing_find_mode(XFER_PIO_0 + pio); u16 cycle = 0; |
4dde4492d ide: make drive->... |
80 |
if (id[ATA_ID_FIELD_VALID] & 2) { |
48fb2688a ide: remove drive... |
81 |
if (ata_id_has_iordy(drive->id)) |
4dde4492d ide: make drive->... |
82 |
cycle = id[ATA_ID_EIDE_PIO_IORDY]; |
c9d6c1a23 ide: move ide_pio... |
83 |
else |
4dde4492d ide: make drive->... |
84 |
cycle = id[ATA_ID_EIDE_PIO]; |
c9d6c1a23 ide: move ide_pio... |
85 86 87 88 |
/* conservative "downgrade" for all pre-ATA2 drives */ if (pio < 3 && cycle < t->cycle) cycle = 0; /* use standard timing */ |
74638c848 ide: add support ... |
89 90 91 92 |
/* Use the standard timing for the CF specific modes too */ if (pio > 4 && ata_id_is_cfa(id)) cycle = 0; |
c9d6c1a23 ide: move ide_pio... |
93 94 95 96 97 |
} return cycle ? cycle : t->cycle; } EXPORT_SYMBOL_GPL(ide_pio_cycle_time); |
2c139e7a7 ide: checkpatch.p... |
98 99 |
#define ENOUGH(v, unit) (((v) - 1) / (unit) + 1) #define EZ(v, unit) ((v) ? ENOUGH(v, unit) : 0) |
1da177e4c Linux-2.6.12-rc2 |
100 |
|
2c139e7a7 ide: checkpatch.p... |
101 102 |
static void ide_timing_quantize(struct ide_timing *t, struct ide_timing *q, int T, int UT) |
1da177e4c Linux-2.6.12-rc2 |
103 104 105 106 107 108 109 110 111 112 |
{ q->setup = EZ(t->setup * 1000, T); q->act8b = EZ(t->act8b * 1000, T); q->rec8b = EZ(t->rec8b * 1000, T); q->cyc8b = EZ(t->cyc8b * 1000, T); q->active = EZ(t->active * 1000, T); q->recover = EZ(t->recover * 1000, T); q->cycle = EZ(t->cycle * 1000, T); q->udma = EZ(t->udma * 1000, UT); } |
f06ab3402 ide: convert ide-... |
113 114 |
void ide_timing_merge(struct ide_timing *a, struct ide_timing *b, struct ide_timing *m, unsigned int what) |
1da177e4c Linux-2.6.12-rc2 |
115 |
{ |
2c139e7a7 ide: checkpatch.p... |
116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 |
if (what & IDE_TIMING_SETUP) m->setup = max(a->setup, b->setup); if (what & IDE_TIMING_ACT8B) m->act8b = max(a->act8b, b->act8b); if (what & IDE_TIMING_REC8B) m->rec8b = max(a->rec8b, b->rec8b); if (what & IDE_TIMING_CYC8B) m->cyc8b = max(a->cyc8b, b->cyc8b); if (what & IDE_TIMING_ACTIVE) m->active = max(a->active, b->active); if (what & IDE_TIMING_RECOVER) m->recover = max(a->recover, b->recover); if (what & IDE_TIMING_CYCLE) m->cycle = max(a->cycle, b->cycle); if (what & IDE_TIMING_UDMA) m->udma = max(a->udma, b->udma); |
1da177e4c Linux-2.6.12-rc2 |
132 |
} |
f06ab3402 ide: convert ide-... |
133 |
EXPORT_SYMBOL_GPL(ide_timing_merge); |
1da177e4c Linux-2.6.12-rc2 |
134 |
|
f06ab3402 ide: convert ide-... |
135 136 |
int ide_timing_compute(ide_drive_t *drive, u8 speed, struct ide_timing *t, int T, int UT) |
1da177e4c Linux-2.6.12-rc2 |
137 |
{ |
4dde4492d ide: make drive->... |
138 |
u16 *id = drive->id; |
1da177e4c Linux-2.6.12-rc2 |
139 |
struct ide_timing *s, p; |
2c139e7a7 ide: checkpatch.p... |
140 141 142 143 144 |
/* * Find the mode. */ s = ide_timing_find_mode(speed); if (s == NULL) |
1da177e4c Linux-2.6.12-rc2 |
145 |
return -EINVAL; |
2c139e7a7 ide: checkpatch.p... |
146 147 148 |
/* * Copy the timing from the table. */ |
17c1033d3 [PATCH] ide: actu... |
149 |
*t = *s; |
2c139e7a7 ide: checkpatch.p... |
150 151 152 153 |
/* * If the drive is an EIDE drive, it can tell us it needs extended * PIO/MWDMA cycle timing. */ |
4dde4492d ide: make drive->... |
154 |
if (id[ATA_ID_FIELD_VALID] & 2) { /* EIDE drive */ |
1da177e4c Linux-2.6.12-rc2 |
155 |
memset(&p, 0, sizeof(p)); |
3dabcfef3 ide: ide_timing_c... |
156 |
if (speed >= XFER_PIO_0 && speed < XFER_SW_DMA_0) { |
2b7d03a5c ide: use standard... |
157 158 159 160 161 162 |
if (speed <= XFER_PIO_2) p.cycle = p.cyc8b = id[ATA_ID_EIDE_PIO]; else if ((speed <= XFER_PIO_4) || (speed == XFER_PIO_5 && !ata_id_is_cfa(id))) p.cycle = p.cyc8b = id[ATA_ID_EIDE_PIO_IORDY]; } else if (speed >= XFER_MW_DMA_0 && speed <= XFER_MW_DMA_2) |
4dde4492d ide: make drive->... |
163 |
p.cycle = id[ATA_ID_EIDE_DMA_MIN]; |
1da177e4c Linux-2.6.12-rc2 |
164 165 166 |
ide_timing_merge(&p, t, t, IDE_TIMING_CYCLE | IDE_TIMING_CYC8B); } |
2c139e7a7 ide: checkpatch.p... |
167 168 169 |
/* * Convert the timing to bus clock counts. */ |
17c1033d3 [PATCH] ide: actu... |
170 |
ide_timing_quantize(t, t, T, UT); |
1da177e4c Linux-2.6.12-rc2 |
171 |
|
2c139e7a7 ide: checkpatch.p... |
172 173 174 |
/* * Even in DMA/UDMA modes we still use PIO access for IDENTIFY, * S.M.A.R.T and some other commands. We have to ensure that the |
8e714a074 ide-timings: use ... |
175 |
* DMA cycle timing is slower/equal than the current PIO timing. |
2c139e7a7 ide: checkpatch.p... |
176 |
*/ |
bd887f72d ide: remove XFER_... |
177 |
if (speed >= XFER_SW_DMA_0) { |
8e714a074 ide-timings: use ... |
178 |
ide_timing_compute(drive, drive->pio_mode, &p, T, UT); |
1da177e4c Linux-2.6.12-rc2 |
179 180 |
ide_timing_merge(&p, t, t, IDE_TIMING_ALL); } |
2c139e7a7 ide: checkpatch.p... |
181 182 183 |
/* * Lengthen active & recovery time so that cycle time is correct. */ |
1da177e4c Linux-2.6.12-rc2 |
184 185 186 187 188 189 190 191 192 193 194 195 |
if (t->act8b + t->rec8b < t->cyc8b) { t->act8b += (t->cyc8b - (t->act8b + t->rec8b)) / 2; t->rec8b = t->cyc8b - t->act8b; } if (t->active + t->recover < t->cycle) { t->active += (t->cycle - (t->active + t->recover)) / 2; t->recover = t->cycle - t->active; } return 0; } |
f06ab3402 ide: convert ide-... |
196 |
EXPORT_SYMBOL_GPL(ide_timing_compute); |