Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
ide-xfer-mode.c
Go to the documentation of this file.
1 #include <linux/types.h>
2 #include <linux/string.h>
3 #include <linux/kernel.h>
4 #include <linux/export.h>
5 #include <linux/interrupt.h>
6 #include <linux/ide.h>
7 #include <linux/bitops.h>
8 
9 static const char *udma_str[] =
10  { "UDMA/16", "UDMA/25", "UDMA/33", "UDMA/44",
11  "UDMA/66", "UDMA/100", "UDMA/133", "UDMA7" };
12 static const char *mwdma_str[] =
13  { "MWDMA0", "MWDMA1", "MWDMA2", "MWDMA3", "MWDMA4" };
14 static const char *swdma_str[] =
15  { "SWDMA0", "SWDMA1", "SWDMA2" };
16 static const char *pio_str[] =
17  { "PIO0", "PIO1", "PIO2", "PIO3", "PIO4", "PIO5", "PIO6" };
18 
27 const char *ide_xfer_verbose(u8 mode)
28 {
29  const char *s;
30  u8 i = mode & 0xf;
31 
32  if (mode >= XFER_UDMA_0 && mode <= XFER_UDMA_7)
33  s = udma_str[i];
34  else if (mode >= XFER_MW_DMA_0 && mode <= XFER_MW_DMA_4)
35  s = mwdma_str[i];
36  else if (mode >= XFER_SW_DMA_0 && mode <= XFER_SW_DMA_2)
37  s = swdma_str[i];
38  else if (mode >= XFER_PIO_0 && mode <= XFER_PIO_6)
39  s = pio_str[i & 0x7];
40  else if (mode == XFER_PIO_SLOW)
41  s = "PIO SLOW";
42  else
43  s = "XFER ERROR";
44 
45  return s;
46 }
48 
62 static u8 ide_get_best_pio_mode(ide_drive_t *drive, u8 mode_wanted, u8 max_mode)
63 {
64  u16 *id = drive->id;
65  int pio_mode = -1, overridden = 0;
66 
67  if (mode_wanted != 255)
68  return min_t(u8, mode_wanted, max_mode);
69 
70  if ((drive->hwif->host_flags & IDE_HFLAG_PIO_NO_BLACKLIST) == 0)
71  pio_mode = ide_scan_pio_blacklist((char *)&id[ATA_ID_PROD]);
72 
73  if (pio_mode != -1) {
74  printk(KERN_INFO "%s: is on PIO blacklist\n", drive->name);
75  } else {
76  pio_mode = id[ATA_ID_OLD_PIO_MODES] >> 8;
77  if (pio_mode > 2) { /* 2 is maximum allowed tPIO value */
78  pio_mode = 2;
79  overridden = 1;
80  }
81 
82  if (id[ATA_ID_FIELD_VALID] & 2) { /* ATA2? */
83  if (ata_id_is_cfa(id) && (id[ATA_ID_CFA_MODES] & 7))
84  pio_mode = 4 + min_t(int, 2,
85  id[ATA_ID_CFA_MODES] & 7);
86  else if (ata_id_has_iordy(id)) {
87  if (id[ATA_ID_PIO_MODES] & 7) {
88  overridden = 0;
89  if (id[ATA_ID_PIO_MODES] & 4)
90  pio_mode = 5;
91  else if (id[ATA_ID_PIO_MODES] & 2)
92  pio_mode = 4;
93  else
94  pio_mode = 3;
95  }
96  }
97  }
98 
99  if (overridden)
100  printk(KERN_INFO "%s: tPIO > 2, assuming tPIO = 2\n",
101  drive->name);
102  }
103 
104  if (pio_mode > max_mode)
105  pio_mode = max_mode;
106 
107  return pio_mode;
108 }
109 
111 {
112  /*
113  * IORDY may lead to controller lock up on certain controllers
114  * if the port is not occupied.
115  */
116  if (pio == 0 && (drive->hwif->port_flags & IDE_PFLAG_PROBING))
117  return 0;
118  return ata_id_pio_need_iordy(drive->id, pio);
119 }
121 
123 {
124  ide_hwif_t *hwif = drive->hwif;
125  const struct ide_port_ops *port_ops = hwif->port_ops;
126 
127  if (hwif->host_flags & IDE_HFLAG_NO_SET_MODE)
128  return 0;
129 
130  if (port_ops == NULL || port_ops->set_pio_mode == NULL)
131  return -1;
132 
133  /*
134  * TODO: temporary hack for some legacy host drivers that didn't
135  * set transfer mode on the device in ->set_pio_mode method...
136  */
137  if (port_ops->set_dma_mode == NULL) {
138  drive->pio_mode = mode;
139  port_ops->set_pio_mode(hwif, drive);
140  return 0;
141  }
142 
143  if (hwif->host_flags & IDE_HFLAG_POST_SET_MODE) {
144  if (ide_config_drive_speed(drive, mode))
145  return -1;
146  drive->pio_mode = mode;
147  port_ops->set_pio_mode(hwif, drive);
148  return 0;
149  } else {
150  drive->pio_mode = mode;
151  port_ops->set_pio_mode(hwif, drive);
152  return ide_config_drive_speed(drive, mode);
153  }
154 }
155 
157 {
158  ide_hwif_t *hwif = drive->hwif;
159  const struct ide_port_ops *port_ops = hwif->port_ops;
160 
161  if (hwif->host_flags & IDE_HFLAG_NO_SET_MODE)
162  return 0;
163 
164  if (port_ops == NULL || port_ops->set_dma_mode == NULL)
165  return -1;
166 
167  if (hwif->host_flags & IDE_HFLAG_POST_SET_MODE) {
168  if (ide_config_drive_speed(drive, mode))
169  return -1;
170  drive->dma_mode = mode;
171  port_ops->set_dma_mode(hwif, drive);
172  return 0;
173  } else {
174  drive->dma_mode = mode;
175  port_ops->set_dma_mode(hwif, drive);
176  return ide_config_drive_speed(drive, mode);
177  }
178 }
180 
181 /* req_pio == "255" for auto-tune */
182 void ide_set_pio(ide_drive_t *drive, u8 req_pio)
183 {
184  ide_hwif_t *hwif = drive->hwif;
185  const struct ide_port_ops *port_ops = hwif->port_ops;
186  u8 host_pio, pio;
187 
188  if (port_ops == NULL || port_ops->set_pio_mode == NULL ||
190  return;
191 
192  BUG_ON(hwif->pio_mask == 0x00);
193 
194  host_pio = fls(hwif->pio_mask) - 1;
195 
196  pio = ide_get_best_pio_mode(drive, req_pio, host_pio);
197 
198  /*
199  * TODO:
200  * - report device max PIO mode
201  * - check req_pio != 255 against device max PIO mode
202  */
203  printk(KERN_DEBUG "%s: host max PIO%d wanted PIO%d%s selected PIO%d\n",
204  drive->name, host_pio, req_pio,
205  req_pio == 255 ? "(auto-tune)" : "", pio);
206 
207  (void)ide_set_pio_mode(drive, XFER_PIO_0 + pio);
208 }
210 
222 static u8 ide_rate_filter(ide_drive_t *drive, u8 speed)
223 {
224  ide_hwif_t *hwif = drive->hwif;
225  u8 mode = ide_find_dma_mode(drive, speed);
226 
227  if (mode == 0) {
228  if (hwif->pio_mask)
229  mode = fls(hwif->pio_mask) - 1 + XFER_PIO_0;
230  else
231  mode = XFER_PIO_4;
232  }
233 
234 /* printk("%s: mode 0x%02x, speed 0x%02x\n", __func__, mode, speed); */
235 
236  return min(speed, mode);
237 }
238 
250 {
251  ide_hwif_t *hwif = drive->hwif;
252  const struct ide_port_ops *port_ops = hwif->port_ops;
253 
254  if (port_ops == NULL || port_ops->set_dma_mode == NULL ||
256  return -1;
257 
258  rate = ide_rate_filter(drive, rate);
259 
260  BUG_ON(rate < XFER_PIO_0);
261 
262  if (rate >= XFER_PIO_0 && rate <= XFER_PIO_6)
263  return ide_set_pio_mode(drive, rate);
264 
265  return ide_set_dma_mode(drive, rate);
266 }