• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
19 /**
20  *	ide_xfer_verbose	-	return IDE mode names
21  *	@mode: transfer mode
22  *
23  *	Returns a constant string giving the name of the mode
24  *	requested.
25  */
26 
ide_xfer_verbose(u8 mode)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 }
47 EXPORT_SYMBOL(ide_xfer_verbose);
48 
49 /**
50  *	ide_get_best_pio_mode	-	get PIO mode from drive
51  *	@drive: drive to consider
52  *	@mode_wanted: preferred mode
53  *	@max_mode: highest allowed mode
54  *
55  *	This routine returns the recommended PIO settings for a given drive,
56  *	based on the drive->id information and the ide_pio_blacklist[].
57  *
58  *	Drive PIO mode is auto-selected if 255 is passed as mode_wanted.
59  *	This is used by most chipset support modules when "auto-tuning".
60  */
61 
ide_get_best_pio_mode(ide_drive_t * drive,u8 mode_wanted,u8 max_mode)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 
ide_pio_need_iordy(ide_drive_t * drive,const u8 pio)110 int ide_pio_need_iordy(ide_drive_t *drive, const u8 pio)
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 }
120 EXPORT_SYMBOL_GPL(ide_pio_need_iordy);
121 
ide_set_pio_mode(ide_drive_t * drive,const u8 mode)122 int ide_set_pio_mode(ide_drive_t *drive, const u8 mode)
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 
ide_set_dma_mode(ide_drive_t * drive,const u8 mode)156 int ide_set_dma_mode(ide_drive_t *drive, const u8 mode)
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 }
179 EXPORT_SYMBOL_GPL(ide_set_dma_mode);
180 
181 /* req_pio == "255" for auto-tune */
ide_set_pio(ide_drive_t * drive,u8 req_pio)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 ||
189 	    (hwif->host_flags & IDE_HFLAG_NO_SET_MODE))
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 }
209 EXPORT_SYMBOL_GPL(ide_set_pio);
210 
211 /**
212  *	ide_rate_filter		-	filter transfer mode
213  *	@drive: IDE device
214  *	@speed: desired speed
215  *
216  *	Given the available transfer modes this function returns
217  *	the best available speed at or below the speed requested.
218  *
219  *	TODO: check device PIO capabilities
220  */
221 
ide_rate_filter(ide_drive_t * drive,u8 speed)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 
239 /**
240  *	ide_set_xfer_rate	-	set transfer rate
241  *	@drive: drive to set
242  *	@rate: speed to attempt to set
243  *
244  *	General helper for setting the speed of an IDE device. This
245  *	function knows about user enforced limits from the configuration
246  *	which ->set_pio_mode/->set_dma_mode does not.
247  */
248 
ide_set_xfer_rate(ide_drive_t * drive,u8 rate)249 int ide_set_xfer_rate(ide_drive_t *drive, u8 rate)
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 ||
255 	    (hwif->host_flags & IDE_HFLAG_NO_SET_MODE))
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 }
267