File: | obj-scan-build/../linux/src/drivers/block/ide.c |
Location: | line 2388, column 1 |
Description: | Address of stack memory associated with local variable 'rq' is still referred to by the global variable 'blk_dev' upon returning to the caller. This will be a dangling reference |
1 | /* | |||
2 | * linux/drivers/block/ide.c Version 5.53 Jun 24, 1997 | |||
3 | * | |||
4 | * Copyright (C) 1994-1996 Linus Torvalds & authors (see below) | |||
5 | */ | |||
6 | #define _IDE_C /* needed by <linux/blk.h> */ | |||
7 | ||||
8 | /* | |||
9 | * Maintained by Mark Lord <mlord@pobox.com> | |||
10 | * and Gadi Oxman <gadio@netvision.net.il> | |||
11 | * | |||
12 | * This is the multiple IDE interface driver, as evolved from hd.c. | |||
13 | * It supports up to four IDE interfaces, on one or more IRQs (usually 14 & 15). | |||
14 | * There can be up to two drives per interface, as per the ATA-2 spec. | |||
15 | * | |||
16 | * Primary: ide0, port 0x1f0; major=3; hda is minor=0; hdb is minor=64 | |||
17 | * Secondary: ide1, port 0x170; major=22; hdc is minor=0; hdd is minor=64 | |||
18 | * Tertiary: ide2, port 0x???; major=33; hde is minor=0; hdf is minor=64 | |||
19 | * Quaternary: ide3, port 0x???; major=34; hdg is minor=0; hdh is minor=64 | |||
20 | * | |||
21 | * It is easy to extend ide.c to handle more than four interfaces: | |||
22 | * | |||
23 | * Change the MAX_HWIFS constant in ide.h. | |||
24 | * | |||
25 | * Define some new major numbers (in major.h), and insert them into | |||
26 | * the ide_hwif_to_major table in ide.c. | |||
27 | * | |||
28 | * Fill in the extra values for the new interfaces into the two tables | |||
29 | * inside ide.c: default_io_base[] and default_irqs[]. | |||
30 | * | |||
31 | * Create the new request handlers by cloning "do_ide3_request()" | |||
32 | * for each new interface, and add them to the switch statement | |||
33 | * in the ide_init() function in ide.c. | |||
34 | * | |||
35 | * Recompile, create the new /dev/ entries, and it will probably work. | |||
36 | * | |||
37 | * From hd.c: | |||
38 | * | | |||
39 | * | It traverses the request-list, using interrupts to jump between functions. | |||
40 | * | As nearly all functions can be called within interrupts, we may not sleep. | |||
41 | * | Special care is recommended. Have Fun! | |||
42 | * | | |||
43 | * | modified by Drew Eckhardt to check nr of hd's from the CMOS. | |||
44 | * | | |||
45 | * | Thanks to Branko Lankester, lankeste@fwi.uva.nl, who found a bug | |||
46 | * | in the early extended-partition checks and added DM partitions. | |||
47 | * | | |||
48 | * | Early work on error handling by Mika Liljeberg (liljeber@cs.Helsinki.FI). | |||
49 | * | | |||
50 | * | IRQ-unmask, drive-id, multiple-mode, support for ">16 heads", | |||
51 | * | and general streamlining by Mark Lord (mlord@pobox.com). | |||
52 | * | |||
53 | * October, 1994 -- Complete line-by-line overhaul for linux 1.1.x, by: | |||
54 | * | |||
55 | * Mark Lord (mlord@pobox.com) (IDE Perf.Pkg) | |||
56 | * Delman Lee (delman@mipg.upenn.edu) ("Mr. atdisk2") | |||
57 | * Scott Snyder (snyder@fnald0.fnal.gov) (ATAPI IDE cd-rom) | |||
58 | * | |||
59 | * This was a rewrite of just about everything from hd.c, though some original | |||
60 | * code is still sprinkled about. Think of it as a major evolution, with | |||
61 | * inspiration from lots of linux users, esp. hamish@zot.apana.org.au | |||
62 | * | |||
63 | * Version 1.0 ALPHA initial code, primary i/f working okay | |||
64 | * Version 1.3 BETA dual i/f on shared irq tested & working! | |||
65 | * Version 1.4 BETA added auto probing for irq(s) | |||
66 | * Version 1.5 BETA added ALPHA (untested) support for IDE cd-roms, | |||
67 | * ... | |||
68 | * Version 3.5 correct the bios_cyl field if it's too small | |||
69 | * (linux 1.1.76) (to help fdisk with brain-dead BIOSs) | |||
70 | * Version 3.6 cosmetic corrections to comments and stuff | |||
71 | * (linux 1.1.77) reorganise probing code to make it understandable | |||
72 | * added halfway retry to probing for drive identification | |||
73 | * added "hdx=noprobe" command line option | |||
74 | * allow setting multmode even when identification fails | |||
75 | * Version 3.7 move set_geometry=1 from do_identify() to ide_init() | |||
76 | * increase DRQ_WAIT to eliminate nuisance messages | |||
77 | * wait for DRQ_STAT instead of DATA_READY during probing | |||
78 | * (courtesy of Gary Thomas gary@efland.UU.NET) | |||
79 | * Version 3.8 fixed byte-swapping for confused Mitsumi cdrom drives | |||
80 | * update of ide-cd.c from Scott, allows blocksize=1024 | |||
81 | * cdrom probe fixes, inspired by jprang@uni-duisburg.de | |||
82 | * Version 3.9 don't use LBA if lba_capacity looks funny | |||
83 | * correct the drive capacity calculations | |||
84 | * fix probing for old Seagates without IDE_ALTSTATUS_REG | |||
85 | * fix byte-ordering for some NEC cdrom drives | |||
86 | * Version 3.10 disable multiple mode by default; was causing trouble | |||
87 | * Version 3.11 fix mis-identification of old WD disks as cdroms | |||
88 | * Version 3,12 simplify logic for selecting initial mult_count | |||
89 | * (fixes problems with buggy WD drives) | |||
90 | * Version 3.13 remove excess "multiple mode disabled" messages | |||
91 | * Version 3.14 fix ide_error() handling of BUSY_STAT | |||
92 | * fix byte-swapped cdrom strings (again.. arghh!) | |||
93 | * ignore INDEX bit when checking the ALTSTATUS reg | |||
94 | * Version 3.15 add SINGLE_THREADED flag for use with dual-CMD i/f | |||
95 | * ignore WRERR_STAT for non-write operations | |||
96 | * added vlb_sync support for DC-2000A & others, | |||
97 | * (incl. some Promise chips), courtesy of Frank Gockel | |||
98 | * Version 3.16 convert vlb_32bit and vlb_sync into runtime flags | |||
99 | * add ioctls to get/set VLB flags (HDIO_[SG]ET_CHIPSET) | |||
100 | * rename SINGLE_THREADED to SUPPORT_SERIALIZE, | |||
101 | * add boot flag to "serialize" operation for CMD i/f | |||
102 | * add optional support for DTC2278 interfaces, | |||
103 | * courtesy of andy@cercle.cts.com (Dyan Wile). | |||
104 | * add boot flag to enable "dtc2278" probe | |||
105 | * add probe to avoid EATA (SCSI) interfaces, | |||
106 | * courtesy of neuffer@goofy.zdv.uni-mainz.de. | |||
107 | * Version 4.00 tidy up verify_area() calls - heiko@colossus.escape.de | |||
108 | * add flag to ignore WRERR_STAT for some drives | |||
109 | * courtesy of David.H.West@um.cc.umich.edu | |||
110 | * assembly syntax tweak to vlb_sync | |||
111 | * removable drive support from scuba@cs.tu-berlin.de | |||
112 | * add transparent support for DiskManager-6.0x "Dynamic | |||
113 | * Disk Overlay" (DDO), most of this is in genhd.c | |||
114 | * eliminate "multiple mode turned off" message at boot | |||
115 | * Version 4.10 fix bug in ioctl for "hdparm -c3" | |||
116 | * fix DM6:DDO support -- now works with LILO, fdisk, ... | |||
117 | * don't treat some naughty WD drives as removable | |||
118 | * Version 4.11 updated DM6 support using info provided by OnTrack | |||
119 | * Version 5.00 major overhaul, multmode setting fixed, vlb_sync fixed | |||
120 | * added support for 3rd/4th/alternative IDE ports | |||
121 | * created ide.h; ide-cd.c now compiles separate from ide.c | |||
122 | * hopefully fixed infinite "unexpected_intr" from cdroms | |||
123 | * zillions of other changes and restructuring | |||
124 | * somehow reduced overall memory usage by several kB | |||
125 | * probably slowed things down slightly, but worth it | |||
126 | * Version 5.01 AT LAST!! Finally understood why "unexpected_intr" | |||
127 | * was happening at various times/places: whenever the | |||
128 | * ide-interface's ctl_port was used to "mask" the irq, | |||
129 | * it also would trigger an edge in the process of masking | |||
130 | * which would result in a self-inflicted interrupt!! | |||
131 | * (such a stupid way to build a hardware interrupt mask). | |||
132 | * This is now fixed (after a year of head-scratching). | |||
133 | * Version 5.02 got rid of need for {enable,disable}_irq_list() | |||
134 | * Version 5.03 tune-ups, comments, remove "busy wait" from drive resets | |||
135 | * removed PROBE_FOR_IRQS option -- no longer needed | |||
136 | * OOOPS! fixed "bad access" bug for 2nd drive on an i/f | |||
137 | * Version 5.04 changed "ira %d" to "irq %d" in DEBUG message | |||
138 | * added more comments, cleaned up unexpected_intr() | |||
139 | * OOOPS! fixed null pointer problem in ide reset code | |||
140 | * added autodetect for Triton chipset -- no effect yet | |||
141 | * Version 5.05 OOOPS! fixed bug in revalidate_disk() | |||
142 | * OOOPS! fixed bug in ide_do_request() | |||
143 | * added ATAPI reset sequence for cdroms | |||
144 | * Version 5.10 added Bus-Mastered DMA support for Triton Chipset | |||
145 | * some (mostly) cosmetic changes | |||
146 | * Version 5.11 added ht6560b support by malafoss@snakemail.hut.fi | |||
147 | * reworked PCI scanning code | |||
148 | * added automatic RZ1000 detection/support | |||
149 | * added automatic PCI CMD640 detection/support | |||
150 | * added option for VLB CMD640 support | |||
151 | * tweaked probe to find cdrom on hdb with disks on hda,hdc | |||
152 | * Version 5.12 some performance tuning | |||
153 | * added message to alert user to bad /dev/hd[cd] entries | |||
154 | * OOOPS! fixed bug in atapi reset | |||
155 | * driver now forces "serialize" again for all cmd640 chips | |||
156 | * noticed REALLY_SLOW_IO had no effect, moved it to ide.c | |||
157 | * made do_drive_cmd() into public ide_do_drive_cmd() | |||
158 | * Version 5.13 fixed typo ('B'), thanks to houston@boyd.geog.mcgill.ca | |||
159 | * fixed ht6560b support | |||
160 | * Version 5.13b (sss) fix problem in calling ide_cdrom_setup() | |||
161 | * don't bother invalidating nonexistent partitions | |||
162 | * Version 5.14 fixes to cmd640 support.. maybe it works now(?) | |||
163 | * added & tested full EZ-DRIVE support -- don't use LILO! | |||
164 | * don't enable 2nd CMD640 PCI port during init - conflict | |||
165 | * Version 5.15 bug fix in init_cmd640_vlb() | |||
166 | * bug fix in interrupt sharing code | |||
167 | * Version 5.16 ugh.. fix "serialize" support, broken in 5.15 | |||
168 | * remove "Huh?" from cmd640 code | |||
169 | * added qd6580 interface speed select from Colten Edwards | |||
170 | * Version 5.17 kludge around bug in BIOS32 on Intel triton motherboards | |||
171 | * Version 5.18 new CMD640 code, moved to cmd640.c, #include'd for now | |||
172 | * new UMC8672 code, moved to umc8672.c, #include'd for now | |||
173 | * disallow turning on DMA when h/w not capable of DMA | |||
174 | * Version 5.19 fix potential infinite timeout on resets | |||
175 | * extend reset poll into a general purpose polling scheme | |||
176 | * add atapi tape drive support from Gadi Oxman | |||
177 | * simplify exit from _intr routines -- no IDE_DO_REQUEST | |||
178 | * Version 5.20 leave current rq on blkdev request list during I/O | |||
179 | * generalized ide_do_drive_cmd() for tape/cdrom driver use | |||
180 | * Version 5.21 fix nasty cdrom/tape bug (ide_preempt was messed up) | |||
181 | * Version 5.22 fix ide_xlate_1024() to work with/without drive->id | |||
182 | * Version 5.23 miscellaneous touch-ups | |||
183 | * Version 5.24 fix #if's for SUPPORT_CMD640 | |||
184 | * Version 5.25 more touch-ups, fix cdrom resets, ... | |||
185 | * cmd640.c now configs/compiles separate from ide.c | |||
186 | * Version 5.26 keep_settings now maintains the using_dma flag | |||
187 | * fix [EZD] remap message to only output at boot time | |||
188 | * fix "bad /dev/ entry" message to say hdc, not hdc0 | |||
189 | * fix ide_xlate_1024() to respect user specified CHS | |||
190 | * use CHS from partn table if it looks translated | |||
191 | * re-merged flags chipset,vlb_32bit,vlb_sync into io_32bit | |||
192 | * keep track of interface chipset type, when known | |||
193 | * add generic PIO mode "tuneproc" mechanism | |||
194 | * fix cmd640_vlb option | |||
195 | * fix ht6560b support (was completely broken) | |||
196 | * umc8672.c now configures/compiles separate from ide.c | |||
197 | * move dtc2278 support to dtc2278.c | |||
198 | * move ht6560b support to ht6560b.c | |||
199 | * move qd6580 support to qd6580.c | |||
200 | * add ali14xx support in ali14xx.c | |||
201 | * Version 5.27 add [no]autotune parameters to help cmd640 | |||
202 | * move rz1000 support to rz1000.c | |||
203 | * Version 5.28 #include "ide_modes.h" | |||
204 | * fix disallow_unmask: now per-interface "no_unmask" bit | |||
205 | * force io_32bit to be the same on drive pairs of dtc2278 | |||
206 | * improved IDE tape error handling, and tape DMA support | |||
207 | * bugfix in ide_do_drive_cmd() for cdroms + serialize | |||
208 | * Version 5.29 fixed non-IDE check for too many physical heads | |||
209 | * don't use LBA if capacity is smaller than CHS | |||
210 | * Version 5.30 remove real_devices kludge, formerly used by genhd.c | |||
211 | * Version 5.32 change "KB" to "kB" | |||
212 | * fix serialize (was broken in kernel 1.3.72) | |||
213 | * add support for "hdparm -I" | |||
214 | * use common code for disk/tape/cdrom IDE_DRIVE_CMDs | |||
215 | * add support for Promise DC4030VL caching card | |||
216 | * improved serialize support | |||
217 | * put partition check back into alphabetical order | |||
218 | * add config option for PCMCIA baggage | |||
219 | * try to make PCMCIA support safer to use | |||
220 | * improve security on ioctls(): all are suser() only | |||
221 | * Version 5.33 improve handling of HDIO_DRIVE_CMDs that read data | |||
222 | * Version 5.34 fix irq-sharing problem from 5.33 | |||
223 | * fix cdrom ioctl problem from 5.33 | |||
224 | * Version 5.35 cosmetic changes | |||
225 | * fix cli() problem in try_to_identify() | |||
226 | * Version 5.36 fixes to optional PCMCIA support | |||
227 | * Version 5.37 don't use DMA when "noautotune" is specified | |||
228 | * Version 5.37a (go) fix shared irq probing (was broken in kernel 1.3.72) | |||
229 | * call unplug_device() from ide_do_drive_cmd() | |||
230 | * Version 5.38 add "hdx=none" option, courtesy of Joel Maslak | |||
231 | * mask drive irq after use, if sharing with another hwif | |||
232 | * add code to help debug weird cmd640 problems | |||
233 | * Version 5.39 fix horrible error in earlier irq sharing "fix" | |||
234 | * Version 5.40 fix serialization -- was broken in 5.39 | |||
235 | * help sharing by masking device irq after probing | |||
236 | * Version 5.41 more fixes to irq sharing/serialize detection | |||
237 | * disable io_32bit by default on drive reset | |||
238 | * Version 5.42 simplify irq-masking after probe | |||
239 | * fix NULL pointer deref in save_match() | |||
240 | * Version 5.43 Ugh.. unexpected_intr is back: try to exterminate it | |||
241 | * Version 5.44 Fix for "irq probe failed" on cmd640 | |||
242 | * change path on message regarding MAKEDEV.ide | |||
243 | * add a throttle to the unexpected_intr() messages | |||
244 | * Version 5.45 fix ugly parameter parsing bugs (thanks Derek) | |||
245 | * include Gadi's magic fix for cmd640 unexpected_intr | |||
246 | * include mc68000 patches from Geert Uytterhoeven | |||
247 | * add Gadi's fix for PCMCIA cdroms | |||
248 | * Version 5.46 remove the mc68000 #ifdefs for 2.0.x | |||
249 | * Version 5.47 fix set_tune race condition | |||
250 | * fix bug in earlier PCMCIA cdrom update | |||
251 | * Version 5.48 if def'd, invoke CMD640_DUMP_REGS when irq probe fails | |||
252 | * lengthen the do_reset1() pulse, for laptops | |||
253 | * add idebus=xx parameter for cmd640 and ali chipsets | |||
254 | * no_unmask flag now per-drive instead of per-hwif | |||
255 | * fix tune_req so that it gets done immediately | |||
256 | * fix missing restore_flags() in ide_ioctl | |||
257 | * prevent use of io_32bit on cmd640 with no prefetch | |||
258 | * Version 5.49 fix minor quirks in probing routines | |||
259 | * Version 5.50 allow values as small as 20 for idebus= | |||
260 | * Version 5.51 force non io_32bit in drive_cmd_intr() | |||
261 | * change delay_10ms() to delay_50ms() to fix problems | |||
262 | * Version 5.52 fix incorrect invalidation of removable devices | |||
263 | * add "hdx=slow" command line option | |||
264 | * Version 5.53 add ATAPI floppy drive support | |||
265 | * change default media for type 0 to floppy | |||
266 | * add support for Exabyte Nest | |||
267 | * add missing set_blocksize() in revalidate_disk() | |||
268 | * handle bad status bit sequencing in ide_wait_stat() | |||
269 | * support partition table translations with 255 heads | |||
270 | * probe all interfaces by default | |||
271 | * add probe for the i82371AB chipset | |||
272 | * acknowledge media change on removable drives | |||
273 | * add work-around for BMI drives | |||
274 | * remove "LBA" from boot messages | |||
275 | * Version 5.53.1 add UDMA "CRC retry" support | |||
276 | * Version 5.53.2 add Promise/33 auto-detection and DMA support | |||
277 | * fix MC_ERR handling | |||
278 | * fix mis-detection of NEC cdrom as floppy | |||
279 | * issue ATAPI reset and re-probe after "no response" | |||
280 | * | |||
281 | * Some additional driver compile-time options are in ide.h | |||
282 | * | |||
283 | * To do, in likely order of completion: | |||
284 | * - modify kernel to obtain BIOS geometry for drives on 2nd/3rd/4th i/f | |||
285 | */ | |||
286 | ||||
287 | #undef REALLY_SLOW_IO /* most systems can safely undef this */ | |||
288 | ||||
289 | #include <linux/config.h> | |||
290 | #include <linux/types.h> | |||
291 | #include <linux/string.h> | |||
292 | #include <linux/kernel.h> | |||
293 | #include <linux/delay.h> | |||
294 | #include <linux/timer.h> | |||
295 | #include <linux/mm.h> | |||
296 | #include <linux/ioport.h> | |||
297 | #include <linux/interrupt.h> | |||
298 | #include <linux/major.h> | |||
299 | #include <linux/blkdev.h> | |||
300 | #include <linux/errno.h> | |||
301 | #include <linux/hdreg.h> | |||
302 | #include <linux/genhd.h> | |||
303 | #include <linux/malloc.h> | |||
304 | ||||
305 | #include <ahci.h> | |||
306 | ||||
307 | #include <asm/byteorder.h> | |||
308 | #include <asm/irq.h> | |||
309 | #include <asm/segment.h> | |||
310 | #include <asm/io.h> | |||
311 | ||||
312 | #ifdef CONFIG_PCI1 | |||
313 | #include <linux/bios32.h> | |||
314 | #include <linux/pci.h> | |||
315 | #endif /* CONFIG_PCI */ | |||
316 | ||||
317 | #include "ide.h" | |||
318 | #include "ide_modes.h" | |||
319 | ||||
320 | #ifdef CONFIG_BLK_DEV_PROMISE | |||
321 | #include "promise.h" | |||
322 | #define IS_PROMISE_DRIVE(0) (HWIF(drive)((ide_hwif_t *)((drive)->hwif))->chipset == ide_promise) | |||
323 | #else | |||
324 | #define IS_PROMISE_DRIVE(0) (0) /* auto-NULLs out Promise code */ | |||
325 | #endif /* CONFIG_BLK_DEV_PROMISE */ | |||
326 | ||||
327 | static const byte ide_hwif_to_major[MAX_HWIFS4] = {IDE0_MAJOR3, IDE1_MAJOR22, IDE2_MAJOR33, IDE3_MAJOR34}; | |||
328 | static const unsigned short default_io_base[MAX_HWIFS4] = {0x1f0, 0x170, 0x1e8, 0x168}; | |||
329 | static const byte default_irqs[MAX_HWIFS4] = {14, 15, 11, 10}; | |||
330 | static int idebus_parameter; /* holds the "idebus=" parameter */ | |||
331 | static int system_bus_speed; /* holds what we think is VESA/PCI bus speed */ | |||
332 | ||||
333 | /* | |||
334 | * This is declared extern in ide.h, for access by other IDE modules: | |||
335 | */ | |||
336 | ide_hwif_t ide_hwifs[MAX_HWIFS4]; /* master data repository */ | |||
337 | ||||
338 | #if (DISK_RECOVERY_TIME0 > 0) | |||
339 | /* | |||
340 | * For really screwy hardware (hey, at least it *can* be used with Linux) | |||
341 | * we can enforce a minimum delay time between successive operations. | |||
342 | */ | |||
343 | static unsigned long read_timer(void) | |||
344 | { | |||
345 | unsigned long t, flags; | |||
346 | int i; | |||
347 | ||||
348 | save_flags(flags)__asm__ __volatile__("pushf ; pop %0" : "=r" (flags): :"memory" ); | |||
349 | cli()__asm__ __volatile__ ("cli": : :"memory"); | |||
350 | t = jiffies * 11932; | |||
351 | outb_p(0, 0x43)((__builtin_constant_p((0x43)) && (0x43) < 256) ? __outbc_p ((0),(0x43)) : __outb_p((0),(0x43))); | |||
352 | i = inb_p(0x40)((__builtin_constant_p((0x40)) && (0x40) < 256) ? __inbc_p (0x40) : __inb_p(0x40)); | |||
353 | i |= inb(0x40)((__builtin_constant_p((0x40)) && (0x40) < 256) ? __inbc (0x40) : __inb(0x40)) << 8; | |||
354 | restore_flags(flags)__asm__ __volatile__("push %0 ; popf": :"g" (flags):"memory"); | |||
355 | return (t - i); | |||
356 | } | |||
357 | ||||
358 | static void set_recovery_timer (ide_hwif_t *hwif) | |||
359 | { | |||
360 | hwif->last_time = read_timer(); | |||
361 | } | |||
362 | #define SET_RECOVERY_TIMER(drive) set_recovery_timer (drive) | |||
363 | ||||
364 | #else | |||
365 | ||||
366 | #define SET_RECOVERY_TIMER(drive) | |||
367 | ||||
368 | #endif /* DISK_RECOVERY_TIME */ | |||
369 | ||||
370 | ||||
371 | /* | |||
372 | * Do not even *think* about calling this! | |||
373 | */ | |||
374 | static void init_hwif_data (unsigned int index) | |||
375 | { | |||
376 | byte *p; | |||
377 | unsigned int unit; | |||
378 | ide_hwif_t *hwif = &ide_hwifs[index]; | |||
379 | ||||
380 | /* bulk initialize hwif & drive info with zeros */ | |||
381 | p = ((byte *) hwif) + sizeof(ide_hwif_t); | |||
382 | do { | |||
383 | *--p = 0; | |||
384 | } while (p > (byte *) hwif); | |||
385 | ||||
386 | /* fill in any non-zero initial values */ | |||
387 | hwif->index = index; | |||
388 | hwif->io_base = default_io_base[index]; | |||
389 | hwif->ctl_port = hwif->io_base ? hwif->io_base+0x206 : 0x000; | |||
390 | #ifdef CONFIG_BLK_DEV_HD | |||
391 | if (hwif->io_base == HD_DATA0x1f0) | |||
392 | hwif->noprobe = 1; /* may be overridden by ide_setup() */ | |||
393 | #endif /* CONFIG_BLK_DEV_HD */ | |||
394 | hwif->major = ide_hwif_to_major[index]; | |||
395 | hwif->name[0] = 'i'; | |||
396 | hwif->name[1] = 'd'; | |||
397 | hwif->name[2] = 'e'; | |||
398 | hwif->name[3] = '0' + index; | |||
399 | #ifdef CONFIG_BLK_DEV_IDETAPE | |||
400 | hwif->tape_drive = NULL((void *) 0); | |||
401 | #endif /* CONFIG_BLK_DEV_IDETAPE */ | |||
402 | for (unit = 0; unit < MAX_DRIVES2; ++unit) { | |||
403 | ide_drive_t *drive = &hwif->drives[unit]; | |||
404 | ||||
405 | drive->select.all = (unit<<4)|0xa0; | |||
406 | drive->hwif = hwif; | |||
407 | drive->ctl = 0x08; | |||
408 | drive->ready_stat = READY_STAT0x40; | |||
409 | drive->bad_wstat = BAD_W_STAT((0x80 | 0x01) | 0x20); | |||
410 | drive->special.b.recalibrate = 1; | |||
411 | drive->special.b.set_geometry = 1; | |||
412 | drive->name[0] = 'h'; | |||
413 | drive->name[1] = 'd'; | |||
414 | #ifdef MACH1 | |||
415 | drive->name[2] = '0' + (index * MAX_DRIVES2) + unit; | |||
416 | #else | |||
417 | drive->name[2] = 'a' + (index * MAX_DRIVES2) + unit; | |||
418 | #endif | |||
419 | } | |||
420 | } | |||
421 | ||||
422 | /* | |||
423 | * init_ide_data() sets reasonable default values into all fields | |||
424 | * of all instances of the hwifs and drives, but only on the first call. | |||
425 | * Subsequent calls have no effect (they don't wipe out anything). | |||
426 | * | |||
427 | * This routine is normally called at driver initialization time, | |||
428 | * but may also be called MUCH earlier during kernel "command-line" | |||
429 | * parameter processing. As such, we cannot depend on any other parts | |||
430 | * of the kernel (such as memory allocation) to be functioning yet. | |||
431 | * | |||
432 | * This is too bad, as otherwise we could dynamically allocate the | |||
433 | * ide_drive_t structs as needed, rather than always consuming memory | |||
434 | * for the max possible number (MAX_HWIFS * MAX_DRIVES) of them. | |||
435 | */ | |||
436 | #define MAGIC_COOKIE0x12345678 0x12345678 | |||
437 | static void init_ide_data (void) | |||
438 | { | |||
439 | unsigned int index; | |||
440 | static unsigned long magic_cookie = MAGIC_COOKIE0x12345678; | |||
441 | ||||
442 | if (magic_cookie != MAGIC_COOKIE0x12345678) | |||
443 | return; /* already initialized */ | |||
444 | magic_cookie = 0; | |||
445 | ||||
446 | for (index = 0; index < MAX_HWIFS4; ++index) | |||
447 | init_hwif_data(index); | |||
448 | ||||
449 | idebus_parameter = 0; | |||
450 | system_bus_speed = 0; | |||
451 | } | |||
452 | ||||
453 | /* | |||
454 | * ide_system_bus_speed() returns what we think is the system VESA/PCI | |||
455 | * bus speed (in Mhz). This is used for calculating interface PIO timings. | |||
456 | * The default is 40 for known PCI systems, 50 otherwise. | |||
457 | * The "idebus=xx" parameter can be used to override this value. | |||
458 | * The actual value to be used is computed/displayed the first time through. | |||
459 | */ | |||
460 | int ide_system_bus_speed (void) | |||
461 | { | |||
462 | if (!system_bus_speed) { | |||
463 | if (idebus_parameter) | |||
464 | system_bus_speed = idebus_parameter; /* user supplied value */ | |||
465 | #ifdef CONFIG_PCI1 | |||
466 | else if (pcibios_present()) | |||
467 | system_bus_speed = 40; /* safe default value for PCI */ | |||
468 | #endif /* CONFIG_PCI */ | |||
469 | else | |||
470 | system_bus_speed = 50; /* safe default value for VESA and PCI */ | |||
471 | printk("ide: Assuming %dMhz system bus speed for PIO modes; override with idebus=xx\n", system_bus_speed); | |||
472 | } | |||
473 | return system_bus_speed; | |||
474 | } | |||
475 | ||||
476 | #if SUPPORT_VLB_SYNC1 | |||
477 | /* | |||
478 | * Some localbus EIDE interfaces require a special access sequence | |||
479 | * when using 32-bit I/O instructions to transfer data. We call this | |||
480 | * the "vlb_sync" sequence, which consists of three successive reads | |||
481 | * of the sector count register location, with interrupts disabled | |||
482 | * to ensure that the reads all happen together. | |||
483 | */ | |||
484 | static inlineinline __attribute__((always_inline)) void do_vlb_sync (unsigned short port) { | |||
485 | (void) inb (port)((__builtin_constant_p((port)) && (port) < 256) ? __inbc (port) : __inb(port)); | |||
486 | (void) inb (port)((__builtin_constant_p((port)) && (port) < 256) ? __inbc (port) : __inb(port)); | |||
487 | (void) inb (port)((__builtin_constant_p((port)) && (port) < 256) ? __inbc (port) : __inb(port)); | |||
488 | } | |||
489 | #endif /* SUPPORT_VLB_SYNC */ | |||
490 | ||||
491 | /* | |||
492 | * This is used for most PIO data transfers *from* the IDE interface | |||
493 | */ | |||
494 | void ide_input_data (ide_drive_t *drive, void *buffer, unsigned int wcount) | |||
495 | { | |||
496 | unsigned short io_base = HWIF(drive)((ide_hwif_t *)((drive)->hwif))->io_base; | |||
497 | unsigned short data_reg = io_base+IDE_DATA_OFFSET(0); | |||
498 | byte io_32bit = drive->io_32bit; | |||
499 | ||||
500 | if (io_32bit) { | |||
501 | #if SUPPORT_VLB_SYNC1 | |||
502 | if (io_32bit & 2) { | |||
503 | cli()__asm__ __volatile__ ("cli": : :"memory"); | |||
504 | do_vlb_sync(io_base+IDE_NSECTOR_OFFSET(2)); | |||
505 | insl(data_reg, buffer, wcount); | |||
506 | if (drive->unmask) | |||
507 | sti()__asm__ __volatile__ ("sti": : :"memory"); | |||
508 | } else | |||
509 | #endif /* SUPPORT_VLB_SYNC */ | |||
510 | insl(data_reg, buffer, wcount); | |||
511 | } else { | |||
512 | #if SUPPORT_SLOW_DATA_PORTS1 | |||
513 | if (drive->slow) { | |||
514 | unsigned short *ptr = (unsigned short *) buffer; | |||
515 | while (wcount--) { | |||
516 | *ptr++ = inw_p(data_reg)((__builtin_constant_p((data_reg)) && (data_reg) < 256) ? __inwc_p(data_reg) : __inw_p(data_reg)); | |||
517 | *ptr++ = inw_p(data_reg)((__builtin_constant_p((data_reg)) && (data_reg) < 256) ? __inwc_p(data_reg) : __inw_p(data_reg)); | |||
518 | } | |||
519 | } else | |||
520 | #endif /* SUPPORT_SLOW_DATA_PORTS */ | |||
521 | insw(data_reg, buffer, wcount<<1); | |||
522 | } | |||
523 | } | |||
524 | ||||
525 | /* | |||
526 | * This is used for most PIO data transfers *to* the IDE interface | |||
527 | */ | |||
528 | void ide_output_data (ide_drive_t *drive, void *buffer, unsigned int wcount) | |||
529 | { | |||
530 | unsigned short io_base = HWIF(drive)((ide_hwif_t *)((drive)->hwif))->io_base; | |||
531 | unsigned short data_reg = io_base+IDE_DATA_OFFSET(0); | |||
532 | byte io_32bit = drive->io_32bit; | |||
533 | ||||
534 | if (io_32bit) { | |||
535 | #if SUPPORT_VLB_SYNC1 | |||
536 | if (io_32bit & 2) { | |||
537 | cli()__asm__ __volatile__ ("cli": : :"memory"); | |||
538 | do_vlb_sync(io_base+IDE_NSECTOR_OFFSET(2)); | |||
539 | outsl(data_reg, buffer, wcount); | |||
540 | if (drive->unmask) | |||
541 | sti()__asm__ __volatile__ ("sti": : :"memory"); | |||
542 | } else | |||
543 | #endif /* SUPPORT_VLB_SYNC */ | |||
544 | outsl(data_reg, buffer, wcount); | |||
545 | } else { | |||
546 | #if SUPPORT_SLOW_DATA_PORTS1 | |||
547 | if (drive->slow) { | |||
548 | unsigned short *ptr = (unsigned short *) buffer; | |||
549 | while (wcount--) { | |||
550 | outw_p(*ptr++, data_reg)((__builtin_constant_p((data_reg)) && (data_reg) < 256) ? __outwc_p((*ptr++),(data_reg)) : __outw_p((*ptr++),(data_reg ))); | |||
551 | outw_p(*ptr++, data_reg)((__builtin_constant_p((data_reg)) && (data_reg) < 256) ? __outwc_p((*ptr++),(data_reg)) : __outw_p((*ptr++),(data_reg ))); | |||
552 | } | |||
553 | } else | |||
554 | #endif /* SUPPORT_SLOW_DATA_PORTS */ | |||
555 | outsw(data_reg, buffer, wcount<<1); | |||
556 | } | |||
557 | } | |||
558 | ||||
559 | /* | |||
560 | * The following routines are mainly used by the ATAPI drivers. | |||
561 | * | |||
562 | * These routines will round up any request for an odd number of bytes, | |||
563 | * so if an odd bytecount is specified, be sure that there's at least one | |||
564 | * extra byte allocated for the buffer. | |||
565 | */ | |||
566 | void atapi_input_bytes (ide_drive_t *drive, void *buffer, unsigned int bytecount) | |||
567 | { | |||
568 | ++bytecount; | |||
569 | ide_input_data (drive, buffer, bytecount / 4); | |||
570 | if ((bytecount & 0x03) >= 2) | |||
571 | insw (IDE_DATA_REG(((ide_hwif_t *)((drive)->hwif))->io_base+(0)), ((byte *)buffer) + (bytecount & ~0x03), 1); | |||
572 | } | |||
573 | ||||
574 | void atapi_output_bytes (ide_drive_t *drive, void *buffer, unsigned int bytecount) | |||
575 | { | |||
576 | ++bytecount; | |||
577 | ide_output_data (drive, buffer, bytecount / 4); | |||
578 | if ((bytecount & 0x03) >= 2) | |||
579 | outsw (IDE_DATA_REG(((ide_hwif_t *)((drive)->hwif))->io_base+(0)), ((byte *)buffer) + (bytecount & ~0x03), 1); | |||
580 | } | |||
581 | ||||
582 | /* | |||
583 | * This should get invoked any time we exit the driver to | |||
584 | * wait for an interrupt response from a drive. handler() points | |||
585 | * at the appropriate code to handle the next interrupt, and a | |||
586 | * timer is started to prevent us from waiting forever in case | |||
587 | * something goes wrong (see the timer_expiry() handler later on). | |||
588 | */ | |||
589 | void ide_set_handler (ide_drive_t *drive, ide_handler_t *handler, unsigned int timeout) | |||
590 | { | |||
591 | ide_hwgroup_t *hwgroup = HWGROUP(drive)((ide_hwgroup_t *)(((ide_hwif_t *)((drive)->hwif))->hwgroup )); | |||
592 | #ifdef DEBUG | |||
593 | if (hwgroup->handler != NULL((void *) 0)) { | |||
594 | printk("%s: ide_set_handler: handler not null; old=%p, new=%p\n", | |||
595 | drive->name, hwgroup->handler, handler); | |||
596 | } | |||
597 | #endif | |||
598 | hwgroup->handler = handler; | |||
599 | hwgroup->timer.expires = jiffies + timeout; | |||
600 | add_timer(&(hwgroup->timer)); | |||
601 | } | |||
602 | ||||
603 | /* | |||
604 | * lba_capacity_is_ok() performs a sanity check on the claimed "lba_capacity" | |||
605 | * value for this drive (from its reported identification information). | |||
606 | * | |||
607 | * Returns: 1 if lba_capacity looks sensible | |||
608 | * 0 otherwise | |||
609 | * | |||
610 | * Note: we must not change id->cyls here, otherwise a second call | |||
611 | * of this routine might no longer find lba_capacity ok. | |||
612 | */ | |||
613 | static int lba_capacity_is_ok (struct hd_driveid *id) | |||
614 | { | |||
615 | unsigned long lba_sects = id->lba_capacity; | |||
616 | unsigned long chs_sects = id->cyls * id->heads * id->sectors; | |||
617 | unsigned long _10_percent = chs_sects / 10; | |||
618 | ||||
619 | /* | |||
620 | * The ATA spec tells large drives to return | |||
621 | * C/H/S = 16383/16/63 independent of their size. | |||
622 | * Some drives can be jumpered to use 15 heads instead of 16. | |||
623 | */ | |||
624 | if (id->cyls == 16383 && id->sectors == 63 && | |||
625 | (id->heads == 15 || id->heads == 16) && | |||
626 | id->lba_capacity >= 16383*63*id->heads) | |||
627 | return 1; /* lba_capacity is our only option */ | |||
628 | ||||
629 | /* perform a rough sanity check on lba_sects: within 10% is "okay" */ | |||
630 | if ((lba_sects - chs_sects) < _10_percent) | |||
631 | return 1; /* lba_capacity is good */ | |||
632 | ||||
633 | /* some drives have the word order reversed */ | |||
634 | lba_sects = (lba_sects << 16) | (lba_sects >> 16); | |||
635 | if ((lba_sects - chs_sects) < _10_percent) { | |||
636 | id->lba_capacity = lba_sects; /* fix it */ | |||
637 | return 1; /* lba_capacity is (now) good */ | |||
638 | } | |||
639 | return 0; /* lba_capacity value is bad */ | |||
640 | } | |||
641 | ||||
642 | /* | |||
643 | * current_capacity() returns the capacity (in sectors) of a drive | |||
644 | * according to its current geometry/LBA settings. | |||
645 | * | |||
646 | * It also sets select.b.lba. | |||
647 | */ | |||
648 | static unsigned long current_capacity (ide_drive_t *drive) | |||
649 | { | |||
650 | struct hd_driveid *id = drive->id; | |||
651 | unsigned long capacity; | |||
652 | ||||
653 | if (!drive->present) | |||
654 | return 0; | |||
655 | #ifdef CONFIG_BLK_DEV_IDEFLOPPY | |||
656 | if (drive->media == ide_floppy) | |||
657 | return idefloppy_capacity(drive); | |||
658 | #endif /* CONFIG_BLK_DEV_IDEFLOPPY */ | |||
659 | if (drive->media != ide_disk) | |||
660 | return 0x7fffffff; /* cdrom or tape */ | |||
661 | ||||
662 | drive->select.b.lba = 0; | |||
663 | /* Determine capacity, and use LBA if the drive properly supports it */ | |||
664 | capacity = drive->cyl * drive->head * drive->sect; | |||
665 | if (id != NULL((void *) 0) && (id->capability & 2) && lba_capacity_is_ok(id)) { | |||
666 | if (id->lba_capacity >= capacity) { | |||
667 | capacity = id->lba_capacity; | |||
668 | drive->select.b.lba = 1; | |||
669 | } | |||
670 | } | |||
671 | return (capacity - drive->sect0); | |||
672 | } | |||
673 | ||||
674 | /* | |||
675 | * ide_geninit() is called exactly *once* for each major, from genhd.c, | |||
676 | * at the beginning of the initial partition check for the drives. | |||
677 | */ | |||
678 | static void ide_geninit (struct gendisk *gd) | |||
679 | { | |||
680 | unsigned int unit; | |||
681 | ide_hwif_t *hwif = gd->real_devices; | |||
682 | ||||
683 | for (unit = 0; unit < gd->nr_real; ++unit) { | |||
684 | ide_drive_t *drive = &hwif->drives[unit]; | |||
685 | #ifdef CONFIG_BLK_DEV_IDECD1 | |||
686 | if (drive->present && drive->media == ide_cdrom) | |||
687 | ide_cdrom_setup(drive); | |||
688 | #endif /* CONFIG_BLK_DEV_IDECD */ | |||
689 | #ifdef CONFIG_BLK_DEV_IDETAPE | |||
690 | if (drive->present && drive->media == ide_tape) | |||
691 | idetape_setup(drive); | |||
692 | #endif /* CONFIG_BLK_DEV_IDETAPE */ | |||
693 | #ifdef CONFIG_BLK_DEV_IDEFLOPPY | |||
694 | if (drive->present && drive->media == ide_floppy) | |||
695 | idefloppy_setup(drive); | |||
696 | #endif /* CONFIG_BLK_DEV_IDEFLOPPY */ | |||
697 | drive->part[0].nr_sects = current_capacity(drive); | |||
698 | if (!drive->present || (drive->media != ide_disk && drive->media != ide_floppy) || | |||
699 | !drive->part[0].nr_sects) { | |||
700 | drive->part[0].start_sect = -1; /* skip partition check */ | |||
701 | } | |||
702 | } | |||
703 | } | |||
704 | ||||
705 | /* | |||
706 | * init_gendisk() (as opposed to ide_geninit) is called for each major device, | |||
707 | * after probing for drives, to allocate partition tables and other data | |||
708 | * structures needed for the routines in genhd.c. ide_geninit() gets called | |||
709 | * somewhat later, during the partition check. | |||
710 | */ | |||
711 | static void init_gendisk (ide_hwif_t *hwif) | |||
712 | { | |||
713 | struct gendisk *gd, **gdp; | |||
714 | unsigned int unit, units, minors; | |||
715 | int *bs; | |||
716 | ||||
717 | /* figure out maximum drive number on the interface */ | |||
718 | for (units = MAX_DRIVES2; units > 0; --units) { | |||
719 | if (hwif->drives[units-1].present) | |||
720 | break; | |||
721 | } | |||
722 | minors = units * (1<<PARTN_BITS6); | |||
723 | gd = kmalloclinux_kmalloc (sizeof(struct gendisk), GFP_KERNEL0x03); | |||
724 | gd->sizes = kmalloclinux_kmalloc (minors * sizeof(int), GFP_KERNEL0x03); | |||
725 | gd->part = kmalloclinux_kmalloc (minors * sizeof(struct hd_struct), GFP_KERNEL0x03); | |||
726 | bs = kmalloclinux_kmalloc (minors*sizeof(int), GFP_KERNEL0x03); | |||
727 | ||||
728 | memset(gd->part, 0, minors * sizeof(struct hd_struct))(__builtin_constant_p(0) ? (__builtin_constant_p((minors * sizeof (struct hd_struct))) ? __constant_c_and_count_memset(((gd-> part)),((0x01010101UL*(unsigned char)(0))),((minors * sizeof( struct hd_struct)))) : __constant_c_memset(((gd->part)),(( 0x01010101UL*(unsigned char)(0))),((minors * sizeof(struct hd_struct ))))) : (__builtin_constant_p((minors * sizeof(struct hd_struct ))) ? __memset_generic((((gd->part))),(((0))),(((minors * sizeof (struct hd_struct))))) : __memset_generic(((gd->part)),((0 )),((minors * sizeof(struct hd_struct)))))); | |||
729 | ||||
730 | /* cdroms and msdos f/s are examples of non-1024 blocksizes */ | |||
731 | blksize_size[hwif->major] = bs; | |||
732 | for (unit = 0; unit < minors; ++unit) | |||
733 | *bs++ = BLOCK_SIZE1024; | |||
734 | ||||
735 | for (unit = 0; unit < units; ++unit) | |||
736 | hwif->drives[unit].part = &gd->part[unit << PARTN_BITS6]; | |||
737 | ||||
738 | gd->major = hwif->major; /* our major device number */ | |||
739 | gd->major_name = IDE_MAJOR_NAME"ide"; /* treated special in genhd.c */ | |||
740 | gd->minor_shift = PARTN_BITS6; /* num bits for partitions */ | |||
741 | gd->max_p = 1<<PARTN_BITS6; /* 1 + max partitions / drive */ | |||
742 | gd->max_nr = units; /* max num real drives */ | |||
743 | gd->nr_real = units; /* current num real drives */ | |||
744 | gd->init = ide_geninit; /* initialization function */ | |||
745 | gd->real_devices= hwif; /* ptr to internal data */ | |||
746 | gd->next = NULL((void *) 0); /* linked list of major devs */ | |||
747 | ||||
748 | for (gdp = &gendisk_head; *gdp; gdp = &((*gdp)->next)) ; | |||
749 | hwif->gd = *gdp = gd; /* link onto tail of list */ | |||
750 | } | |||
751 | ||||
752 | static void do_reset1 (ide_drive_t *, int); /* needed below */ | |||
753 | ||||
754 | #ifdef CONFIG_BLK_DEV_IDEATAPI1 | |||
755 | /* | |||
756 | * atapi_reset_pollfunc() gets invoked to poll the interface for completion every 50ms | |||
757 | * during an atapi drive reset operation. If the drive has not yet responded, | |||
758 | * and we have not yet hit our maximum waiting time, then the timer is restarted | |||
759 | * for another 50ms. | |||
760 | */ | |||
761 | static void atapi_reset_pollfunc (ide_drive_t *drive) | |||
762 | { | |||
763 | ide_hwgroup_t *hwgroup = HWGROUP(drive)((ide_hwgroup_t *)(((ide_hwif_t *)((drive)->hwif))->hwgroup )); | |||
764 | byte stat; | |||
765 | ||||
766 | OUT_BYTE (drive->select.all, IDE_SELECT_REG)((__builtin_constant_p((((((ide_hwif_t *)((drive)->hwif))-> io_base+(6))))) && (((((ide_hwif_t *)((drive)->hwif ))->io_base+(6)))) < 256) ? __outbc_p(((drive->select .all)),(((((ide_hwif_t *)((drive)->hwif))->io_base+(6)) ))) : __outb_p(((drive->select.all)),(((((ide_hwif_t *)((drive )->hwif))->io_base+(6)))))); | |||
767 | udelay (10)(__builtin_constant_p(10) ? __const_udelay((10) * 0x10c6ul) : __udelay(10)); | |||
768 | ||||
769 | if (OK_STAT(stat=GET_STAT(), 0, BUSY_STAT)(((stat=(byte)((__builtin_constant_p(((((ide_hwif_t *)((drive )->hwif))->io_base+(7)))) && ((((ide_hwif_t *)( (drive)->hwif))->io_base+(7))) < 256) ? __inbc_p(((( ide_hwif_t *)((drive)->hwif))->io_base+(7))) : __inb_p( (((ide_hwif_t *)((drive)->hwif))->io_base+(7)))))&( (0)|(0x80)))==(0))) { | |||
770 | printk("%s: ATAPI reset complete\n", drive->name); | |||
771 | } else { | |||
772 | if (jiffies < hwgroup->poll_timeout) { | |||
773 | ide_set_handler (drive, &atapi_reset_pollfunc, HZ100/20); | |||
774 | return; /* continue polling */ | |||
775 | } | |||
776 | hwgroup->poll_timeout = 0; /* end of polling */ | |||
777 | printk("%s: ATAPI reset timed-out, status=0x%02x\n", drive->name, stat); | |||
778 | do_reset1 (drive, 1); /* do it the old fashioned way */ | |||
779 | return; | |||
780 | } | |||
781 | hwgroup->poll_timeout = 0; /* done polling */ | |||
782 | } | |||
783 | #endif /* CONFIG_BLK_DEV_IDEATAPI */ | |||
784 | ||||
785 | /* | |||
786 | * reset_pollfunc() gets invoked to poll the interface for completion every 50ms | |||
787 | * during an ide reset operation. If the drives have not yet responded, | |||
788 | * and we have not yet hit our maximum waiting time, then the timer is restarted | |||
789 | * for another 50ms. | |||
790 | */ | |||
791 | static void reset_pollfunc (ide_drive_t *drive) | |||
792 | { | |||
793 | ide_hwgroup_t *hwgroup = HWGROUP(drive)((ide_hwgroup_t *)(((ide_hwif_t *)((drive)->hwif))->hwgroup )); | |||
794 | ide_hwif_t *hwif = HWIF(drive)((ide_hwif_t *)((drive)->hwif)); | |||
795 | byte tmp; | |||
796 | ||||
797 | if (!OK_STAT(tmp=GET_STAT(), 0, BUSY_STAT)(((tmp=(byte)((__builtin_constant_p(((((ide_hwif_t *)((drive) ->hwif))->io_base+(7)))) && ((((ide_hwif_t *)(( drive)->hwif))->io_base+(7))) < 256) ? __inbc_p((((ide_hwif_t *)((drive)->hwif))->io_base+(7))) : __inb_p((((ide_hwif_t *)((drive)->hwif))->io_base+(7)))))&((0)|(0x80)))== (0))) { | |||
798 | if (jiffies < hwgroup->poll_timeout) { | |||
799 | ide_set_handler (drive, &reset_pollfunc, HZ100/20); | |||
800 | return; /* continue polling */ | |||
801 | } | |||
802 | printk("%s: reset timed-out, status=0x%02x\n", hwif->name, tmp); | |||
803 | } else { | |||
804 | printk("%s: reset: ", hwif->name); | |||
805 | if ((tmp = GET_ERR()(byte)((__builtin_constant_p(((((ide_hwif_t *)((drive)->hwif ))->io_base+(1)))) && ((((ide_hwif_t *)((drive)-> hwif))->io_base+(1))) < 256) ? __inbc_p((((ide_hwif_t * )((drive)->hwif))->io_base+(1))) : __inb_p((((ide_hwif_t *)((drive)->hwif))->io_base+(1))))) == 1) | |||
806 | printk("success\n"); | |||
807 | else { | |||
808 | #if FANCY_STATUS_DUMPS1 | |||
809 | printk("master: "); | |||
810 | switch (tmp & 0x7f) { | |||
811 | case 1: printk("passed"); | |||
812 | break; | |||
813 | case 2: printk("formatter device error"); | |||
814 | break; | |||
815 | case 3: printk("sector buffer error"); | |||
816 | break; | |||
817 | case 4: printk("ECC circuitry error"); | |||
818 | break; | |||
819 | case 5: printk("controlling MPU error"); | |||
820 | break; | |||
821 | default:printk("error (0x%02x?)", tmp); | |||
822 | } | |||
823 | if (tmp & 0x80) | |||
824 | printk("; slave: failed"); | |||
825 | printk("\n"); | |||
826 | #else | |||
827 | printk("failed\n"); | |||
828 | #endif /* FANCY_STATUS_DUMPS */ | |||
829 | } | |||
830 | } | |||
831 | hwgroup->poll_timeout = 0; /* done polling */ | |||
832 | } | |||
833 | ||||
834 | /* | |||
835 | * do_reset1() attempts to recover a confused drive by resetting it. | |||
836 | * Unfortunately, resetting a disk drive actually resets all devices on | |||
837 | * the same interface, so it can really be thought of as resetting the | |||
838 | * interface rather than resetting the drive. | |||
839 | * | |||
840 | * ATAPI devices have their own reset mechanism which allows them to be | |||
841 | * individually reset without clobbering other devices on the same interface. | |||
842 | * | |||
843 | * Unfortunately, the IDE interface does not generate an interrupt to let | |||
844 | * us know when the reset operation has finished, so we must poll for this. | |||
845 | * Equally poor, though, is the fact that this may a very long time to complete, | |||
846 | * (up to 30 seconds worstcase). So, instead of busy-waiting here for it, | |||
847 | * we set a timer to poll at 50ms intervals. | |||
848 | */ | |||
849 | static void do_reset1 (ide_drive_t *drive, int do_not_try_atapi) | |||
850 | { | |||
851 | unsigned int unit; | |||
852 | unsigned long flags; | |||
853 | ide_hwif_t *hwif = HWIF(drive)((ide_hwif_t *)((drive)->hwif)); | |||
854 | ide_hwgroup_t *hwgroup = HWGROUP(drive)((ide_hwgroup_t *)(((ide_hwif_t *)((drive)->hwif))->hwgroup )); | |||
855 | ||||
856 | save_flags(flags)__asm__ __volatile__("pushf ; pop %0" : "=r" (flags): :"memory" ); | |||
857 | cli()__asm__ __volatile__ ("cli": : :"memory"); /* Why ? */ | |||
858 | ||||
859 | #ifdef CONFIG_BLK_DEV_IDEATAPI1 | |||
860 | /* For an ATAPI device, first try an ATAPI SRST. */ | |||
861 | if (drive->media != ide_disk) { | |||
862 | if (!do_not_try_atapi) { | |||
863 | if (!drive->keep_settings) { | |||
864 | drive->unmask = 0; | |||
865 | drive->io_32bit = 0; | |||
866 | } | |||
867 | OUT_BYTE (drive->select.all, IDE_SELECT_REG)((__builtin_constant_p((((((ide_hwif_t *)((drive)->hwif))-> io_base+(6))))) && (((((ide_hwif_t *)((drive)->hwif ))->io_base+(6)))) < 256) ? __outbc_p(((drive->select .all)),(((((ide_hwif_t *)((drive)->hwif))->io_base+(6)) ))) : __outb_p(((drive->select.all)),(((((ide_hwif_t *)((drive )->hwif))->io_base+(6)))))); | |||
868 | udelay (20)(__builtin_constant_p(20) ? __const_udelay((20) * 0x10c6ul) : __udelay(20)); | |||
869 | OUT_BYTE (WIN_SRST, IDE_COMMAND_REG)((__builtin_constant_p((((((ide_hwif_t *)((drive)->hwif))-> io_base+(7))))) && (((((ide_hwif_t *)((drive)->hwif ))->io_base+(7)))) < 256) ? __outbc_p(((0x08)),(((((ide_hwif_t *)((drive)->hwif))->io_base+(7))))) : __outb_p(((0x08) ),(((((ide_hwif_t *)((drive)->hwif))->io_base+(7)))))); | |||
870 | hwgroup->poll_timeout = jiffies + WAIT_WORSTCASE(30*100); | |||
871 | ide_set_handler (drive, &atapi_reset_pollfunc, HZ100/20); | |||
872 | restore_flags (flags)__asm__ __volatile__("push %0 ; popf": :"g" (flags):"memory"); | |||
873 | return; | |||
874 | } | |||
875 | } | |||
876 | #endif /* CONFIG_BLK_DEV_IDEATAPI */ | |||
877 | ||||
878 | /* | |||
879 | * First, reset any device state data we were maintaining | |||
880 | * for any of the drives on this interface. | |||
881 | */ | |||
882 | for (unit = 0; unit < MAX_DRIVES2; ++unit) { | |||
883 | ide_drive_t *rdrive = &hwif->drives[unit]; | |||
884 | #ifdef CONFIG_BLK_DEV_IDETAPE | |||
885 | if (rdrive->media == ide_tape) | |||
886 | rdrive->tape.reset_issued = 1; | |||
887 | #endif /* CONFIG_BLK_DEV_IDETAPE */ | |||
888 | rdrive->special.all = 0; | |||
889 | rdrive->special.b.set_geometry = 1; | |||
890 | rdrive->special.b.recalibrate = 1; | |||
891 | if (OK_TO_RESET_CONTROLLER1) | |||
892 | rdrive->mult_count = 0; | |||
893 | if (!rdrive->keep_settings) { | |||
894 | rdrive->mult_req = 0; | |||
895 | rdrive->unmask = 0; | |||
896 | rdrive->io_32bit = 0; | |||
897 | if (rdrive->using_dma) { | |||
898 | rdrive->using_dma = 0; | |||
899 | printk("%s: disabled DMA\n", rdrive->name); | |||
900 | } | |||
901 | } | |||
902 | if (rdrive->mult_req != rdrive->mult_count) | |||
903 | rdrive->special.b.set_multmode = 1; | |||
904 | } | |||
905 | ||||
906 | #if OK_TO_RESET_CONTROLLER1 | |||
907 | /* | |||
908 | * Note that we also set nIEN while resetting the device, | |||
909 | * to mask unwanted interrupts from the interface during the reset. | |||
910 | * However, due to the design of PC hardware, this will cause an | |||
911 | * immediate interrupt due to the edge transition it produces. | |||
912 | * This single interrupt gives us a "fast poll" for drives that | |||
913 | * recover from reset very quickly, saving us the first 50ms wait time. | |||
914 | */ | |||
915 | OUT_BYTE(drive->ctl|6,IDE_CONTROL_REG)((__builtin_constant_p((((((ide_hwif_t *)((drive)->hwif))-> ctl_port)))) && (((((ide_hwif_t *)((drive)->hwif)) ->ctl_port))) < 256) ? __outbc_p(((drive->ctl|6)),(( (((ide_hwif_t *)((drive)->hwif))->ctl_port)))) : __outb_p (((drive->ctl|6)),(((((ide_hwif_t *)((drive)->hwif))-> ctl_port))))); /* set SRST and nIEN */ | |||
916 | udelay(10)(__builtin_constant_p(10) ? __const_udelay((10) * 0x10c6ul) : __udelay(10)); /* more than enough time */ | |||
917 | OUT_BYTE(drive->ctl|2,IDE_CONTROL_REG)((__builtin_constant_p((((((ide_hwif_t *)((drive)->hwif))-> ctl_port)))) && (((((ide_hwif_t *)((drive)->hwif)) ->ctl_port))) < 256) ? __outbc_p(((drive->ctl|2)),(( (((ide_hwif_t *)((drive)->hwif))->ctl_port)))) : __outb_p (((drive->ctl|2)),(((((ide_hwif_t *)((drive)->hwif))-> ctl_port))))); /* clear SRST, leave nIEN */ | |||
918 | udelay(10)(__builtin_constant_p(10) ? __const_udelay((10) * 0x10c6ul) : __udelay(10)); /* more than enough time */ | |||
919 | hwgroup->poll_timeout = jiffies + WAIT_WORSTCASE(30*100); | |||
920 | ide_set_handler (drive, &reset_pollfunc, HZ100/20); | |||
921 | #endif /* OK_TO_RESET_CONTROLLER */ | |||
922 | ||||
923 | restore_flags (flags)__asm__ __volatile__("push %0 ; popf": :"g" (flags):"memory"); | |||
924 | } | |||
925 | ||||
926 | /* | |||
927 | * ide_do_reset() is the entry point to the drive/interface reset code. | |||
928 | */ | |||
929 | void ide_do_reset (ide_drive_t *drive) | |||
930 | { | |||
931 | do_reset1 (drive, 0); | |||
932 | #ifdef CONFIG_BLK_DEV_IDETAPE | |||
933 | if (drive->media == ide_tape) | |||
934 | drive->tape.reset_issued=1; | |||
935 | #endif /* CONFIG_BLK_DEV_IDETAPE */ | |||
936 | } | |||
937 | ||||
938 | /* | |||
939 | * Clean up after success/failure of an explicit drive cmd | |||
940 | */ | |||
941 | void ide_end_drive_cmd (ide_drive_t *drive, byte stat, byte err) | |||
942 | { | |||
943 | unsigned long flags; | |||
944 | struct request *rq = HWGROUP(drive)((ide_hwgroup_t *)(((ide_hwif_t *)((drive)->hwif))->hwgroup ))->rq; | |||
945 | ||||
946 | if (rq->cmd == IDE_DRIVE_CMD99) { | |||
947 | byte *args = (byte *) rq->buffer; | |||
948 | rq->errors = !OK_STAT(stat,READY_STAT,BAD_STAT)(((stat)&((0x40)|(((0x80 | 0x01) | 0x08))))==(0x40)); | |||
949 | if (args) { | |||
950 | args[0] = stat; | |||
951 | args[1] = err; | |||
952 | args[2] = IN_BYTE(IDE_NSECTOR_REG)(byte)((__builtin_constant_p(((((ide_hwif_t *)((drive)->hwif ))->io_base+(2)))) && ((((ide_hwif_t *)((drive)-> hwif))->io_base+(2))) < 256) ? __inbc_p((((ide_hwif_t * )((drive)->hwif))->io_base+(2))) : __inb_p((((ide_hwif_t *)((drive)->hwif))->io_base+(2)))); | |||
953 | } | |||
954 | } | |||
955 | save_flags(flags)__asm__ __volatile__("pushf ; pop %0" : "=r" (flags): :"memory" ); | |||
956 | cli()__asm__ __volatile__ ("cli": : :"memory"); | |||
957 | blk_dev[MAJOR(rq->rq_dev)((rq->rq_dev) >> 8)].current_request = rq->next; | |||
958 | HWGROUP(drive)((ide_hwgroup_t *)(((ide_hwif_t *)((drive)->hwif))->hwgroup ))->rq = NULL((void *) 0); | |||
959 | rq->rq_status = RQ_INACTIVE(-1); | |||
960 | if (rq->sem != NULL((void *) 0)) | |||
961 | up(rq->sem); | |||
962 | restore_flags(flags)__asm__ __volatile__("push %0 ; popf": :"g" (flags):"memory"); | |||
963 | } | |||
964 | ||||
965 | /* | |||
966 | * Error reporting, in human readable form (luxurious, but a memory hog). | |||
967 | */ | |||
968 | byte ide_dump_status (ide_drive_t *drive, const char *msg, byte stat) | |||
969 | { | |||
970 | unsigned long flags; | |||
971 | byte err = 0; | |||
972 | ||||
973 | save_flags (flags)__asm__ __volatile__("pushf ; pop %0" : "=r" (flags): :"memory" ); | |||
974 | sti()__asm__ __volatile__ ("sti": : :"memory"); | |||
975 | printk("%s: %s: status=0x%02x", drive->name, msg, stat); | |||
976 | #if FANCY_STATUS_DUMPS1 | |||
977 | if (drive->media == ide_disk) { | |||
978 | printk(" { "); | |||
979 | if (stat & BUSY_STAT0x80) | |||
980 | printk("Busy "); | |||
981 | else { | |||
982 | if (stat & READY_STAT0x40) printk("DriveReady "); | |||
983 | if (stat & WRERR_STAT0x20) printk("DeviceFault "); | |||
984 | if (stat & SEEK_STAT0x10) printk("SeekComplete "); | |||
985 | if (stat & DRQ_STAT0x08) printk("DataRequest "); | |||
986 | if (stat & ECC_STAT0x04) printk("CorrectedError "); | |||
987 | if (stat & INDEX_STAT0x02) printk("Index "); | |||
988 | if (stat & ERR_STAT0x01) printk("Error "); | |||
989 | } | |||
990 | printk("}"); | |||
991 | } | |||
992 | #endif /* FANCY_STATUS_DUMPS */ | |||
993 | printk("\n"); | |||
994 | if ((stat & (BUSY_STAT0x80|ERR_STAT0x01)) == ERR_STAT0x01) { | |||
995 | err = GET_ERR()(byte)((__builtin_constant_p(((((ide_hwif_t *)((drive)->hwif ))->io_base+(1)))) && ((((ide_hwif_t *)((drive)-> hwif))->io_base+(1))) < 256) ? __inbc_p((((ide_hwif_t * )((drive)->hwif))->io_base+(1))) : __inb_p((((ide_hwif_t *)((drive)->hwif))->io_base+(1)))); | |||
996 | printk("%s: %s: error=0x%02x", drive->name, msg, err); | |||
997 | #if FANCY_STATUS_DUMPS1 | |||
998 | if (drive->media == ide_disk) { | |||
999 | printk(" { "); | |||
1000 | if (err & ICRC_ERR0x80) printk((err & ABRT_ERR0x04) ? "BadCRC " : "BadSector "); | |||
1001 | if (err & ECC_ERR0x40) printk("UncorrectableError "); | |||
1002 | if (err & ID_ERR0x10) printk("SectorIdNotFound "); | |||
1003 | if (err & ABRT_ERR0x04) printk("DriveStatusError "); | |||
1004 | if (err & TRK0_ERR0x02) printk("TrackZeroNotFound "); | |||
1005 | if (err & MARK_ERR0x01) printk("AddrMarkNotFound "); | |||
1006 | printk("}"); | |||
1007 | if (err & (BBD_ERR0x80|ECC_ERR0x40|ID_ERR0x10|MARK_ERR0x01)) { | |||
1008 | byte cur = IN_BYTE(IDE_SELECT_REG)(byte)((__builtin_constant_p(((((ide_hwif_t *)((drive)->hwif ))->io_base+(6)))) && ((((ide_hwif_t *)((drive)-> hwif))->io_base+(6))) < 256) ? __inbc_p((((ide_hwif_t * )((drive)->hwif))->io_base+(6))) : __inb_p((((ide_hwif_t *)((drive)->hwif))->io_base+(6)))); | |||
1009 | if (cur & 0x40) { /* using LBA? */ | |||
1010 | printk(", LBAsect=%ld", (unsigned long) | |||
1011 | ((cur&0xf)<<24) | |||
1012 | |(IN_BYTE(IDE_HCYL_REG)(byte)((__builtin_constant_p(((((ide_hwif_t *)((drive)->hwif ))->io_base+(5)))) && ((((ide_hwif_t *)((drive)-> hwif))->io_base+(5))) < 256) ? __inbc_p((((ide_hwif_t * )((drive)->hwif))->io_base+(5))) : __inb_p((((ide_hwif_t *)((drive)->hwif))->io_base+(5))))<<16) | |||
1013 | |(IN_BYTE(IDE_LCYL_REG)(byte)((__builtin_constant_p(((((ide_hwif_t *)((drive)->hwif ))->io_base+(4)))) && ((((ide_hwif_t *)((drive)-> hwif))->io_base+(4))) < 256) ? __inbc_p((((ide_hwif_t * )((drive)->hwif))->io_base+(4))) : __inb_p((((ide_hwif_t *)((drive)->hwif))->io_base+(4))))<<8) | |||
1014 | | IN_BYTE(IDE_SECTOR_REG)(byte)((__builtin_constant_p(((((ide_hwif_t *)((drive)->hwif ))->io_base+(3)))) && ((((ide_hwif_t *)((drive)-> hwif))->io_base+(3))) < 256) ? __inbc_p((((ide_hwif_t * )((drive)->hwif))->io_base+(3))) : __inb_p((((ide_hwif_t *)((drive)->hwif))->io_base+(3))))); | |||
1015 | } else { | |||
1016 | printk(", CHS=%d/%d/%d", | |||
1017 | (IN_BYTE(IDE_HCYL_REG)(byte)((__builtin_constant_p(((((ide_hwif_t *)((drive)->hwif ))->io_base+(5)))) && ((((ide_hwif_t *)((drive)-> hwif))->io_base+(5))) < 256) ? __inbc_p((((ide_hwif_t * )((drive)->hwif))->io_base+(5))) : __inb_p((((ide_hwif_t *)((drive)->hwif))->io_base+(5))))<<8) + | |||
1018 | IN_BYTE(IDE_LCYL_REG)(byte)((__builtin_constant_p(((((ide_hwif_t *)((drive)->hwif ))->io_base+(4)))) && ((((ide_hwif_t *)((drive)-> hwif))->io_base+(4))) < 256) ? __inbc_p((((ide_hwif_t * )((drive)->hwif))->io_base+(4))) : __inb_p((((ide_hwif_t *)((drive)->hwif))->io_base+(4)))), | |||
1019 | cur & 0xf, | |||
1020 | IN_BYTE(IDE_SECTOR_REG)(byte)((__builtin_constant_p(((((ide_hwif_t *)((drive)->hwif ))->io_base+(3)))) && ((((ide_hwif_t *)((drive)-> hwif))->io_base+(3))) < 256) ? __inbc_p((((ide_hwif_t * )((drive)->hwif))->io_base+(3))) : __inb_p((((ide_hwif_t *)((drive)->hwif))->io_base+(3))))); | |||
1021 | } | |||
1022 | if (HWGROUP(drive)((ide_hwgroup_t *)(((ide_hwif_t *)((drive)->hwif))->hwgroup ))->rq) | |||
1023 | printk(", sector=%ld", HWGROUP(drive)((ide_hwgroup_t *)(((ide_hwif_t *)((drive)->hwif))->hwgroup ))->rq->sector); | |||
1024 | } | |||
1025 | } | |||
1026 | #endif /* FANCY_STATUS_DUMPS */ | |||
1027 | printk("\n"); | |||
1028 | } | |||
1029 | restore_flags (flags)__asm__ __volatile__("push %0 ; popf": :"g" (flags):"memory"); | |||
1030 | return err; | |||
1031 | } | |||
1032 | ||||
1033 | /* | |||
1034 | * try_to_flush_leftover_data() is invoked in response to a drive | |||
1035 | * unexpectedly having its DRQ_STAT bit set. As an alternative to | |||
1036 | * resetting the drive, this routine tries to clear the condition | |||
1037 | * by read a sector's worth of data from the drive. Of course, | |||
1038 | * this may not help if the drive is *waiting* for data from *us*. | |||
1039 | */ | |||
1040 | static void try_to_flush_leftover_data (ide_drive_t *drive) | |||
1041 | { | |||
1042 | int i = (drive->mult_count ? drive->mult_count : 1) * SECTOR_WORDS(512 / 4); | |||
1043 | ||||
1044 | while (i > 0) { | |||
1045 | unsigned long buffer[16]; | |||
1046 | unsigned int wcount = (i > 16) ? 16 : i; | |||
1047 | i -= wcount; | |||
1048 | ide_input_data (drive, buffer, wcount); | |||
1049 | } | |||
1050 | } | |||
1051 | ||||
1052 | /* | |||
1053 | * ide_error() takes action based on the error returned by the controller. | |||
1054 | */ | |||
1055 | void ide_error (ide_drive_t *drive, const char *msg, byte stat) | |||
1056 | { | |||
1057 | struct request *rq; | |||
1058 | byte err; | |||
1059 | ||||
1060 | err = ide_dump_status(drive, msg, stat); | |||
1061 | if ((rq = HWGROUP(drive)((ide_hwgroup_t *)(((ide_hwif_t *)((drive)->hwif))->hwgroup ))->rq) == NULL((void *) 0) || drive == NULL((void *) 0)) | |||
1062 | return; | |||
1063 | /* retry only "normal" I/O: */ | |||
1064 | if (rq->cmd == IDE_DRIVE_CMD99) { | |||
1065 | rq->errors = 1; | |||
1066 | ide_end_drive_cmd(drive, stat, err); | |||
1067 | return; | |||
1068 | } | |||
1069 | if (stat & BUSY_STAT0x80) { /* other bits are useless when BUSY */ | |||
1070 | rq->errors |= ERROR_RESET3; | |||
1071 | } else { | |||
1072 | if (drive->media == ide_disk && (stat & ERR_STAT0x01)) { | |||
1073 | /* err has different meaning on cdrom and tape */ | |||
1074 | if (err == ABRT_ERR0x04) { | |||
1075 | if (drive->select.b.lba && IN_BYTE(IDE_COMMAND_REG)(byte)((__builtin_constant_p(((((ide_hwif_t *)((drive)->hwif ))->io_base+(7)))) && ((((ide_hwif_t *)((drive)-> hwif))->io_base+(7))) < 256) ? __inbc_p((((ide_hwif_t * )((drive)->hwif))->io_base+(7))) : __inb_p((((ide_hwif_t *)((drive)->hwif))->io_base+(7)))) == WIN_SPECIFY0x91) | |||
1076 | return; /* some newer drives don't support WIN_SPECIFY */ | |||
1077 | } else if ((err & (ABRT_ERR0x04 | ICRC_ERR0x80)) == (ABRT_ERR0x04 | ICRC_ERR0x80)) | |||
1078 | ; /* UDMA crc error -- just retry the operation */ | |||
1079 | else if (err & (BBD_ERR0x80 | ECC_ERR0x40)) /* retries won't help these */ | |||
1080 | rq->errors = ERROR_MAX8; | |||
1081 | else if (err & TRK0_ERR0x02) /* help it find track zero */ | |||
1082 | rq->errors |= ERROR_RECAL1; | |||
1083 | else if (err & MC_ERR0x20) | |||
1084 | drive->special.b.mc = 1; | |||
1085 | } | |||
1086 | if ((stat & DRQ_STAT0x08) && rq->cmd != WRITE1) | |||
1087 | try_to_flush_leftover_data(drive); | |||
1088 | } | |||
1089 | if (GET_STAT()(byte)((__builtin_constant_p(((((ide_hwif_t *)((drive)->hwif ))->io_base+(7)))) && ((((ide_hwif_t *)((drive)-> hwif))->io_base+(7))) < 256) ? __inbc_p((((ide_hwif_t * )((drive)->hwif))->io_base+(7))) : __inb_p((((ide_hwif_t *)((drive)->hwif))->io_base+(7)))) & (BUSY_STAT0x80|DRQ_STAT0x08)) | |||
1090 | rq->errors |= ERROR_RESET3; /* Mmmm.. timing problem */ | |||
1091 | ||||
1092 | if (rq->errors >= ERROR_MAX8) { | |||
1093 | #ifdef CONFIG_BLK_DEV_IDETAPE | |||
1094 | if (drive->media == ide_tape) { | |||
1095 | rq->errors = 0; | |||
1096 | idetape_end_request(0, HWGROUP(drive)((ide_hwgroup_t *)(((ide_hwif_t *)((drive)->hwif))->hwgroup ))); | |||
1097 | } else | |||
1098 | #endif /* CONFIG_BLK_DEV_IDETAPE */ | |||
1099 | #ifdef CONFIG_BLK_DEV_IDEFLOPPY | |||
1100 | if (drive->media == ide_floppy) { | |||
1101 | rq->errors = 0; | |||
1102 | idefloppy_end_request(0, HWGROUP(drive)((ide_hwgroup_t *)(((ide_hwif_t *)((drive)->hwif))->hwgroup ))); | |||
1103 | } else | |||
1104 | #endif /* CONFIG_BLK_DEV_IDEFLOPPY */ | |||
1105 | #ifdef CONFIG_BLK_DEV_IDESCSI | |||
1106 | if (drive->media == ide_scsi) { | |||
1107 | rq->errors = 0; | |||
1108 | idescsi_end_request(0, HWGROUP(drive)((ide_hwgroup_t *)(((ide_hwif_t *)((drive)->hwif))->hwgroup ))); | |||
1109 | } else | |||
1110 | #endif /* CONFIG_BLK_DEV_IDESCSI */ | |||
1111 | ide_end_request(0, HWGROUP(drive)((ide_hwgroup_t *)(((ide_hwif_t *)((drive)->hwif))->hwgroup ))); | |||
1112 | } | |||
1113 | else { | |||
1114 | if ((rq->errors & ERROR_RESET3) == ERROR_RESET3) { | |||
1115 | ++rq->errors; | |||
1116 | ide_do_reset(drive); | |||
1117 | return; | |||
1118 | } else if ((rq->errors & ERROR_RECAL1) == ERROR_RECAL1) | |||
1119 | drive->special.b.recalibrate = 1; | |||
1120 | ++rq->errors; | |||
1121 | } | |||
1122 | } | |||
1123 | ||||
1124 | /* | |||
1125 | * read_intr() is the handler for disk read/multread interrupts | |||
1126 | */ | |||
1127 | static void read_intr (ide_drive_t *drive) | |||
1128 | { | |||
1129 | byte stat; | |||
1130 | int i; | |||
1131 | unsigned int msect, nsect; | |||
1132 | struct request *rq; | |||
1133 | ||||
1134 | if (!OK_STAT(stat=GET_STAT(),DATA_READY,BAD_R_STAT)(((stat=(byte)((__builtin_constant_p(((((ide_hwif_t *)((drive )->hwif))->io_base+(7)))) && ((((ide_hwif_t *)( (drive)->hwif))->io_base+(7))) < 256) ? __inbc_p(((( ide_hwif_t *)((drive)->hwif))->io_base+(7))) : __inb_p( (((ide_hwif_t *)((drive)->hwif))->io_base+(7)))))&( ((0x08))|((0x80 | 0x01))))==((0x08)))) { | |||
1135 | ide_error(drive, "read_intr", stat); | |||
1136 | return; | |||
1137 | } | |||
1138 | msect = drive->mult_count; | |||
1139 | read_next: | |||
1140 | rq = HWGROUP(drive)((ide_hwgroup_t *)(((ide_hwif_t *)((drive)->hwif))->hwgroup ))->rq; | |||
1141 | if (msect) { | |||
1142 | if ((nsect = rq->current_nr_sectors) > msect) | |||
1143 | nsect = msect; | |||
1144 | msect -= nsect; | |||
1145 | } else | |||
1146 | nsect = 1; | |||
1147 | i = rq->nr_sectors - nsect; | |||
1148 | if (i > 0 && !msect) | |||
1149 | ide_set_handler (drive, &read_intr, WAIT_CMD(10*100)); | |||
1150 | ide_input_data(drive, rq->buffer, nsect * SECTOR_WORDS(512 / 4)); | |||
1151 | #ifdef DEBUG | |||
1152 | printk("%s: read: sectors(%ld-%ld), buffer=0x%08lx, remaining=%ld\n", | |||
1153 | drive->name, rq->sector, rq->sector+nsect-1, | |||
1154 | (unsigned long) rq->buffer+(nsect<<9), rq->nr_sectors-nsect); | |||
1155 | #endif | |||
1156 | rq->sector += nsect; | |||
1157 | rq->buffer += nsect<<9; | |||
1158 | rq->errors = 0; | |||
1159 | rq->nr_sectors = i; | |||
1160 | if ((rq->current_nr_sectors -= nsect) <= 0) | |||
1161 | ide_end_request(1, HWGROUP(drive)((ide_hwgroup_t *)(((ide_hwif_t *)((drive)->hwif))->hwgroup ))); | |||
1162 | if (i > 0 && msect) | |||
1163 | goto read_next; | |||
1164 | } | |||
1165 | ||||
1166 | /* | |||
1167 | * write_intr() is the handler for disk write interrupts | |||
1168 | */ | |||
1169 | static void write_intr (ide_drive_t *drive) | |||
1170 | { | |||
1171 | byte stat; | |||
1172 | int i; | |||
1173 | ide_hwgroup_t *hwgroup = HWGROUP(drive)((ide_hwgroup_t *)(((ide_hwif_t *)((drive)->hwif))->hwgroup )); | |||
1174 | struct request *rq = hwgroup->rq; | |||
1175 | ||||
1176 | if (OK_STAT(stat=GET_STAT(),DRIVE_READY,drive->bad_wstat)(((stat=(byte)((__builtin_constant_p(((((ide_hwif_t *)((drive )->hwif))->io_base+(7)))) && ((((ide_hwif_t *)( (drive)->hwif))->io_base+(7))) < 256) ? __inbc_p(((( ide_hwif_t *)((drive)->hwif))->io_base+(7))) : __inb_p( (((ide_hwif_t *)((drive)->hwif))->io_base+(7)))))&( ((0x40 | 0x10))|(drive->bad_wstat)))==((0x40 | 0x10)))) { | |||
1177 | #ifdef DEBUG | |||
1178 | printk("%s: write: sector %ld, buffer=0x%08lx, remaining=%ld\n", | |||
1179 | drive->name, rq->sector, (unsigned long) rq->buffer, | |||
1180 | rq->nr_sectors-1); | |||
1181 | #endif | |||
1182 | if ((rq->nr_sectors == 1) ^ ((stat & DRQ_STAT0x08) != 0)) { | |||
1183 | rq->sector++; | |||
1184 | rq->buffer += 512; | |||
1185 | rq->errors = 0; | |||
1186 | i = --rq->nr_sectors; | |||
1187 | --rq->current_nr_sectors; | |||
1188 | if (rq->current_nr_sectors <= 0) | |||
1189 | ide_end_request(1, hwgroup); | |||
1190 | if (i > 0) { | |||
1191 | ide_set_handler (drive, &write_intr, WAIT_CMD(10*100)); | |||
1192 | ide_output_data (drive, rq->buffer, SECTOR_WORDS(512 / 4)); | |||
1193 | } | |||
1194 | return; | |||
1195 | } | |||
1196 | } | |||
1197 | ide_error(drive, "write_intr", stat); | |||
1198 | } | |||
1199 | ||||
1200 | /* | |||
1201 | * ide_multwrite() transfers a block of up to mcount sectors of data | |||
1202 | * to a drive as part of a disk multiple-sector write operation. | |||
1203 | */ | |||
1204 | void ide_multwrite (ide_drive_t *drive, unsigned int mcount) | |||
1205 | { | |||
1206 | struct request *rq = &HWGROUP(drive)((ide_hwgroup_t *)(((ide_hwif_t *)((drive)->hwif))->hwgroup ))->wrq; | |||
1207 | ||||
1208 | do { | |||
1209 | unsigned int nsect = rq->current_nr_sectors; | |||
1210 | if (nsect > mcount) | |||
1211 | nsect = mcount; | |||
1212 | mcount -= nsect; | |||
1213 | ||||
1214 | ide_output_data(drive, rq->buffer, nsect<<7); | |||
1215 | #ifdef DEBUG | |||
1216 | printk("%s: multwrite: sector %ld, buffer=0x%08lx, count=%d, remaining=%ld\n", | |||
1217 | drive->name, rq->sector, (unsigned long) rq->buffer, | |||
1218 | nsect, rq->nr_sectors - nsect); | |||
1219 | #endif | |||
1220 | if ((rq->nr_sectors -= nsect) <= 0) | |||
1221 | break; | |||
1222 | if ((rq->current_nr_sectors -= nsect) == 0) { | |||
1223 | if ((rq->bh = rq->bh->b_reqnext) != NULL((void *) 0)) { | |||
1224 | rq->current_nr_sectors = rq->bh->b_size>>9; | |||
1225 | rq->buffer = rq->bh->b_data; | |||
1226 | } else { | |||
1227 | panic("%s: buffer list corrupted\n", drive->name); | |||
1228 | break; | |||
1229 | } | |||
1230 | } else { | |||
1231 | rq->buffer += nsect << 9; | |||
1232 | } | |||
1233 | } while (mcount); | |||
1234 | } | |||
1235 | ||||
1236 | /* | |||
1237 | * multwrite_intr() is the handler for disk multwrite interrupts | |||
1238 | */ | |||
1239 | static void multwrite_intr (ide_drive_t *drive) | |||
1240 | { | |||
1241 | byte stat; | |||
1242 | int i; | |||
1243 | ide_hwgroup_t *hwgroup = HWGROUP(drive)((ide_hwgroup_t *)(((ide_hwif_t *)((drive)->hwif))->hwgroup )); | |||
1244 | struct request *rq = &hwgroup->wrq; | |||
1245 | ||||
1246 | if (OK_STAT(stat=GET_STAT(),DRIVE_READY,drive->bad_wstat)(((stat=(byte)((__builtin_constant_p(((((ide_hwif_t *)((drive )->hwif))->io_base+(7)))) && ((((ide_hwif_t *)( (drive)->hwif))->io_base+(7))) < 256) ? __inbc_p(((( ide_hwif_t *)((drive)->hwif))->io_base+(7))) : __inb_p( (((ide_hwif_t *)((drive)->hwif))->io_base+(7)))))&( ((0x40 | 0x10))|(drive->bad_wstat)))==((0x40 | 0x10)))) { | |||
1247 | if (stat & DRQ_STAT0x08) { | |||
1248 | if (rq->nr_sectors) { | |||
1249 | ide_set_handler (drive, &multwrite_intr, WAIT_CMD(10*100)); | |||
1250 | ide_multwrite(drive, drive->mult_count); | |||
1251 | return; | |||
1252 | } | |||
1253 | } else { | |||
1254 | if (!rq->nr_sectors) { /* all done? */ | |||
1255 | rq = hwgroup->rq; | |||
1256 | for (i = rq->nr_sectors; i > 0;){ | |||
1257 | i -= rq->current_nr_sectors; | |||
1258 | ide_end_request(1, hwgroup); | |||
1259 | } | |||
1260 | return; | |||
1261 | } | |||
1262 | } | |||
1263 | } | |||
1264 | ide_error(drive, "multwrite_intr", stat); | |||
1265 | } | |||
1266 | ||||
1267 | /* | |||
1268 | * Issue a simple drive command | |||
1269 | * The drive must be selected beforehand. | |||
1270 | */ | |||
1271 | static void ide_cmd(ide_drive_t *drive, byte cmd, byte nsect, ide_handler_t *handler) | |||
1272 | { | |||
1273 | ide_set_handler (drive, handler, WAIT_CMD(10*100)); | |||
1274 | OUT_BYTE(drive->ctl,IDE_CONTROL_REG)((__builtin_constant_p((((((ide_hwif_t *)((drive)->hwif))-> ctl_port)))) && (((((ide_hwif_t *)((drive)->hwif)) ->ctl_port))) < 256) ? __outbc_p(((drive->ctl)),(((( (ide_hwif_t *)((drive)->hwif))->ctl_port)))) : __outb_p (((drive->ctl)),(((((ide_hwif_t *)((drive)->hwif))-> ctl_port))))); | |||
1275 | OUT_BYTE(nsect,IDE_NSECTOR_REG)((__builtin_constant_p((((((ide_hwif_t *)((drive)->hwif))-> io_base+(2))))) && (((((ide_hwif_t *)((drive)->hwif ))->io_base+(2)))) < 256) ? __outbc_p(((nsect)),(((((ide_hwif_t *)((drive)->hwif))->io_base+(2))))) : __outb_p(((nsect )),(((((ide_hwif_t *)((drive)->hwif))->io_base+(2)))))); | |||
1276 | OUT_BYTE(cmd,IDE_COMMAND_REG)((__builtin_constant_p((((((ide_hwif_t *)((drive)->hwif))-> io_base+(7))))) && (((((ide_hwif_t *)((drive)->hwif ))->io_base+(7)))) < 256) ? __outbc_p(((cmd)),(((((ide_hwif_t *)((drive)->hwif))->io_base+(7))))) : __outb_p(((cmd)) ,(((((ide_hwif_t *)((drive)->hwif))->io_base+(7)))))); | |||
1277 | } | |||
1278 | ||||
1279 | /* | |||
1280 | * set_multmode_intr() is invoked on completion of a WIN_SETMULT cmd. | |||
1281 | */ | |||
1282 | static void set_multmode_intr (ide_drive_t *drive) | |||
1283 | { | |||
1284 | byte stat = GET_STAT()(byte)((__builtin_constant_p(((((ide_hwif_t *)((drive)->hwif ))->io_base+(7)))) && ((((ide_hwif_t *)((drive)-> hwif))->io_base+(7))) < 256) ? __inbc_p((((ide_hwif_t * )((drive)->hwif))->io_base+(7))) : __inb_p((((ide_hwif_t *)((drive)->hwif))->io_base+(7)))); | |||
1285 | ||||
1286 | sti()__asm__ __volatile__ ("sti": : :"memory"); | |||
1287 | if (OK_STAT(stat,READY_STAT,BAD_STAT)(((stat)&((0x40)|(((0x80 | 0x01) | 0x08))))==(0x40))) { | |||
1288 | drive->mult_count = drive->mult_req; | |||
1289 | } else { | |||
1290 | drive->mult_req = drive->mult_count = 0; | |||
1291 | drive->special.b.recalibrate = 1; | |||
1292 | (void) ide_dump_status(drive, "set_multmode", stat); | |||
1293 | } | |||
1294 | } | |||
1295 | ||||
1296 | /* | |||
1297 | * set_geometry_intr() is invoked on completion of a WIN_SPECIFY cmd. | |||
1298 | */ | |||
1299 | static void set_geometry_intr (ide_drive_t *drive) | |||
1300 | { | |||
1301 | byte stat = GET_STAT()(byte)((__builtin_constant_p(((((ide_hwif_t *)((drive)->hwif ))->io_base+(7)))) && ((((ide_hwif_t *)((drive)-> hwif))->io_base+(7))) < 256) ? __inbc_p((((ide_hwif_t * )((drive)->hwif))->io_base+(7))) : __inb_p((((ide_hwif_t *)((drive)->hwif))->io_base+(7)))); | |||
1302 | ||||
1303 | sti()__asm__ __volatile__ ("sti": : :"memory"); | |||
1304 | if (!OK_STAT(stat,READY_STAT,BAD_STAT)(((stat)&((0x40)|(((0x80 | 0x01) | 0x08))))==(0x40))) | |||
1305 | ide_error(drive, "set_geometry_intr", stat); | |||
1306 | } | |||
1307 | ||||
1308 | /* | |||
1309 | * recal_intr() is invoked on completion of a WIN_RESTORE (recalibrate) cmd. | |||
1310 | */ | |||
1311 | static void recal_intr (ide_drive_t *drive) | |||
1312 | { | |||
1313 | byte stat = GET_STAT()(byte)((__builtin_constant_p(((((ide_hwif_t *)((drive)->hwif ))->io_base+(7)))) && ((((ide_hwif_t *)((drive)-> hwif))->io_base+(7))) < 256) ? __inbc_p((((ide_hwif_t * )((drive)->hwif))->io_base+(7))) : __inb_p((((ide_hwif_t *)((drive)->hwif))->io_base+(7)))); | |||
1314 | ||||
1315 | sti()__asm__ __volatile__ ("sti": : :"memory"); | |||
1316 | if (!OK_STAT(stat,READY_STAT,BAD_STAT)(((stat)&((0x40)|(((0x80 | 0x01) | 0x08))))==(0x40))) | |||
1317 | ide_error(drive, "recal_intr", stat); | |||
1318 | } | |||
1319 | ||||
1320 | /* | |||
1321 | * mc_intr() is invoked on completion of a WIN_ACKMC cmd. | |||
1322 | */ | |||
1323 | static void mc_intr (ide_drive_t *drive) | |||
1324 | { | |||
1325 | byte stat = GET_STAT()(byte)((__builtin_constant_p(((((ide_hwif_t *)((drive)->hwif ))->io_base+(7)))) && ((((ide_hwif_t *)((drive)-> hwif))->io_base+(7))) < 256) ? __inbc_p((((ide_hwif_t * )((drive)->hwif))->io_base+(7))) : __inb_p((((ide_hwif_t *)((drive)->hwif))->io_base+(7)))); | |||
1326 | ||||
1327 | sti()__asm__ __volatile__ ("sti": : :"memory"); | |||
1328 | if (!OK_STAT(stat,READY_STAT,BAD_STAT)(((stat)&((0x40)|(((0x80 | 0x01) | 0x08))))==(0x40))) | |||
1329 | ide_error(drive, "mc_intr", stat); | |||
1330 | drive->special.b.mc = 0; | |||
1331 | } | |||
1332 | ||||
1333 | /* | |||
1334 | * drive_cmd_intr() is invoked on completion of a special DRIVE_CMD. | |||
1335 | */ | |||
1336 | static void drive_cmd_intr (ide_drive_t *drive) | |||
1337 | { | |||
1338 | struct request *rq = HWGROUP(drive)((ide_hwgroup_t *)(((ide_hwif_t *)((drive)->hwif))->hwgroup ))->rq; | |||
1339 | byte *args = (byte *) rq->buffer; | |||
1340 | byte stat = GET_STAT()(byte)((__builtin_constant_p(((((ide_hwif_t *)((drive)->hwif ))->io_base+(7)))) && ((((ide_hwif_t *)((drive)-> hwif))->io_base+(7))) < 256) ? __inbc_p((((ide_hwif_t * )((drive)->hwif))->io_base+(7))) : __inb_p((((ide_hwif_t *)((drive)->hwif))->io_base+(7)))); | |||
1341 | ||||
1342 | sti()__asm__ __volatile__ ("sti": : :"memory"); | |||
1343 | if ((stat & DRQ_STAT0x08) && args && args[3]) { | |||
1344 | byte io_32bit = drive->io_32bit; | |||
1345 | drive->io_32bit = 0; | |||
1346 | ide_input_data(drive, &args[4], args[3] * SECTOR_WORDS(512 / 4)); | |||
1347 | drive->io_32bit = io_32bit; | |||
1348 | stat = GET_STAT()(byte)((__builtin_constant_p(((((ide_hwif_t *)((drive)->hwif ))->io_base+(7)))) && ((((ide_hwif_t *)((drive)-> hwif))->io_base+(7))) < 256) ? __inbc_p((((ide_hwif_t * )((drive)->hwif))->io_base+(7))) : __inb_p((((ide_hwif_t *)((drive)->hwif))->io_base+(7)))); | |||
1349 | } | |||
1350 | if (OK_STAT(stat,READY_STAT,BAD_STAT)(((stat)&((0x40)|(((0x80 | 0x01) | 0x08))))==(0x40))) | |||
1351 | ide_end_drive_cmd (drive, stat, GET_ERR()(byte)((__builtin_constant_p(((((ide_hwif_t *)((drive)->hwif ))->io_base+(1)))) && ((((ide_hwif_t *)((drive)-> hwif))->io_base+(1))) < 256) ? __inbc_p((((ide_hwif_t * )((drive)->hwif))->io_base+(1))) : __inb_p((((ide_hwif_t *)((drive)->hwif))->io_base+(1))))); | |||
1352 | else | |||
1353 | ide_error(drive, "drive_cmd", stat); /* calls ide_end_drive_cmd */ | |||
1354 | } | |||
1355 | ||||
1356 | /* | |||
1357 | * do_special() is used to issue WIN_SPECIFY, WIN_RESTORE, and WIN_SETMULT | |||
1358 | * commands to a drive. It used to do much more, but has been scaled back. | |||
1359 | */ | |||
1360 | static inlineinline __attribute__((always_inline)) void do_special (ide_drive_t *drive) | |||
1361 | { | |||
1362 | special_t *s = &drive->special; | |||
1363 | ||||
1364 | #ifdef DEBUG | |||
1365 | printk("%s: do_special: 0x%02x\n", drive->name, s->all); | |||
1366 | #endif | |||
1367 | if (s->b.set_geometry) { | |||
1368 | s->b.set_geometry = 0; | |||
1369 | if (drive->media == ide_disk && !drive->no_geom) { | |||
1370 | OUT_BYTE(drive->sect,IDE_SECTOR_REG)((__builtin_constant_p((((((ide_hwif_t *)((drive)->hwif))-> io_base+(3))))) && (((((ide_hwif_t *)((drive)->hwif ))->io_base+(3)))) < 256) ? __outbc_p(((drive->sect) ),(((((ide_hwif_t *)((drive)->hwif))->io_base+(3))))) : __outb_p(((drive->sect)),(((((ide_hwif_t *)((drive)->hwif ))->io_base+(3)))))); | |||
1371 | OUT_BYTE(drive->cyl,IDE_LCYL_REG)((__builtin_constant_p((((((ide_hwif_t *)((drive)->hwif))-> io_base+(4))))) && (((((ide_hwif_t *)((drive)->hwif ))->io_base+(4)))) < 256) ? __outbc_p(((drive->cyl)) ,(((((ide_hwif_t *)((drive)->hwif))->io_base+(4))))) : __outb_p (((drive->cyl)),(((((ide_hwif_t *)((drive)->hwif))-> io_base+(4)))))); | |||
1372 | OUT_BYTE(drive->cyl>>8,IDE_HCYL_REG)((__builtin_constant_p((((((ide_hwif_t *)((drive)->hwif))-> io_base+(5))))) && (((((ide_hwif_t *)((drive)->hwif ))->io_base+(5)))) < 256) ? __outbc_p(((drive->cyl>> 8)),(((((ide_hwif_t *)((drive)->hwif))->io_base+(5))))) : __outb_p(((drive->cyl>>8)),(((((ide_hwif_t *)((drive )->hwif))->io_base+(5)))))); | |||
1373 | OUT_BYTE(((drive->head-1)|drive->select.all)&0xBF,IDE_SELECT_REG)((__builtin_constant_p((((((ide_hwif_t *)((drive)->hwif))-> io_base+(6))))) && (((((ide_hwif_t *)((drive)->hwif ))->io_base+(6)))) < 256) ? __outbc_p(((((drive->head -1)|drive->select.all)&0xBF)),(((((ide_hwif_t *)((drive )->hwif))->io_base+(6))))) : __outb_p(((((drive->head -1)|drive->select.all)&0xBF)),(((((ide_hwif_t *)((drive )->hwif))->io_base+(6)))))); | |||
1374 | if (!IS_PROMISE_DRIVE(0)) | |||
1375 | ide_cmd(drive, WIN_SPECIFY0x91, drive->sect, &set_geometry_intr); | |||
1376 | } | |||
1377 | } else if (s->b.recalibrate) { | |||
1378 | s->b.recalibrate = 0; | |||
1379 | if (drive->media == ide_disk && !IS_PROMISE_DRIVE(0)) | |||
1380 | ide_cmd(drive, WIN_RESTORE0x10, drive->sect, &recal_intr); | |||
1381 | } else if (s->b.set_tune) { | |||
1382 | ide_tuneproc_t *tuneproc = HWIF(drive)((ide_hwif_t *)((drive)->hwif))->tuneproc; | |||
1383 | s->b.set_tune = 0; | |||
1384 | if (tuneproc != NULL((void *) 0)) | |||
1385 | tuneproc(drive, drive->tune_req); | |||
1386 | } else if (s->b.set_multmode) { | |||
1387 | s->b.set_multmode = 0; | |||
1388 | if (drive->media == ide_disk) { | |||
1389 | if (drive->id && drive->mult_req > drive->id->max_multsect) | |||
1390 | drive->mult_req = drive->id->max_multsect; | |||
1391 | if (!IS_PROMISE_DRIVE(0)) | |||
1392 | ide_cmd(drive, WIN_SETMULT0xC6, drive->mult_req, &set_multmode_intr); | |||
1393 | } else | |||
1394 | drive->mult_req = 0; | |||
1395 | } else if (s->b.mc) { | |||
1396 | s->b.mc = 0; | |||
1397 | if (drive->media == ide_disk && !IS_PROMISE_DRIVE(0)) | |||
1398 | ide_cmd(drive, WIN_ACKMC0xdb, drive->sect, &mc_intr); | |||
1399 | } else if (s->all) { | |||
1400 | int special = s->all; | |||
1401 | s->all = 0; | |||
1402 | printk("%s: bad special flag: 0x%02x\n", drive->name, special); | |||
1403 | } | |||
1404 | } | |||
1405 | ||||
1406 | /* | |||
1407 | * This routine busy-waits for the drive status to be not "busy". | |||
1408 | * It then checks the status for all of the "good" bits and none | |||
1409 | * of the "bad" bits, and if all is okay it returns 0. All other | |||
1410 | * cases return 1 after invoking ide_error() -- caller should just return. | |||
1411 | * | |||
1412 | * This routine should get fixed to not hog the cpu during extra long waits.. | |||
1413 | * That could be done by busy-waiting for the first jiffy or two, and then | |||
1414 | * setting a timer to wake up at half second intervals thereafter, | |||
1415 | * until timeout is achieved, before timing out. | |||
1416 | */ | |||
1417 | int ide_wait_stat (ide_drive_t *drive, byte good, byte bad, unsigned long timeout) | |||
1418 | { | |||
1419 | byte stat; | |||
1420 | unsigned long flags; | |||
1421 | ||||
1422 | udelay(1)(__builtin_constant_p(1) ? __const_udelay((1) * 0x10c6ul) : __udelay (1)); /* spec allows drive 400ns to assert "BUSY" */ | |||
1423 | if ((stat = GET_STAT()(byte)((__builtin_constant_p(((((ide_hwif_t *)((drive)->hwif ))->io_base+(7)))) && ((((ide_hwif_t *)((drive)-> hwif))->io_base+(7))) < 256) ? __inbc_p((((ide_hwif_t * )((drive)->hwif))->io_base+(7))) : __inb_p((((ide_hwif_t *)((drive)->hwif))->io_base+(7))))) & BUSY_STAT0x80) { | |||
1424 | save_flags(flags)__asm__ __volatile__("pushf ; pop %0" : "=r" (flags): :"memory" ); | |||
1425 | sti()__asm__ __volatile__ ("sti": : :"memory"); | |||
1426 | timeout += jiffies; | |||
1427 | while ((stat = GET_STAT()(byte)((__builtin_constant_p(((((ide_hwif_t *)((drive)->hwif ))->io_base+(7)))) && ((((ide_hwif_t *)((drive)-> hwif))->io_base+(7))) < 256) ? __inbc_p((((ide_hwif_t * )((drive)->hwif))->io_base+(7))) : __inb_p((((ide_hwif_t *)((drive)->hwif))->io_base+(7))))) & BUSY_STAT0x80) { | |||
1428 | if (jiffies > timeout) { | |||
1429 | restore_flags(flags)__asm__ __volatile__("push %0 ; popf": :"g" (flags):"memory"); | |||
1430 | ide_error(drive, "status timeout", stat); | |||
1431 | return 1; | |||
1432 | } | |||
1433 | } | |||
1434 | restore_flags(flags)__asm__ __volatile__("push %0 ; popf": :"g" (flags):"memory"); | |||
1435 | } | |||
1436 | udelay(1)(__builtin_constant_p(1) ? __const_udelay((1) * 0x10c6ul) : __udelay (1)); /* allow status to settle, then read it again */ | |||
1437 | if (OK_STAT((stat = GET_STAT()), good, bad)((((stat = (byte)((__builtin_constant_p(((((ide_hwif_t *)((drive )->hwif))->io_base+(7)))) && ((((ide_hwif_t *)( (drive)->hwif))->io_base+(7))) < 256) ? __inbc_p(((( ide_hwif_t *)((drive)->hwif))->io_base+(7))) : __inb_p( (((ide_hwif_t *)((drive)->hwif))->io_base+(7))))))& ((good)|(bad)))==(good))) | |||
1438 | return 0; | |||
1439 | ide_error(drive, "status error", stat); | |||
1440 | return 1; | |||
1441 | } | |||
1442 | ||||
1443 | /* | |||
1444 | * do_rw_disk() issues READ and WRITE commands to a disk, | |||
1445 | * using LBA if supported, or CHS otherwise, to address sectors. | |||
1446 | * It also takes care of issuing special DRIVE_CMDs. | |||
1447 | */ | |||
1448 | static inlineinline __attribute__((always_inline)) void do_rw_disk (ide_drive_t *drive, struct request *rq, unsigned long block) | |||
1449 | { | |||
1450 | ide_hwif_t *hwif = HWIF(drive)((ide_hwif_t *)((drive)->hwif)); | |||
1451 | unsigned short io_base = hwif->io_base; | |||
1452 | #ifdef CONFIG_BLK_DEV_PROMISE | |||
1453 | int use_promise_io = 0; | |||
1454 | #endif /* CONFIG_BLK_DEV_PROMISE */ | |||
1455 | ||||
1456 | OUT_BYTE(drive->ctl,IDE_CONTROL_REG)((__builtin_constant_p((((((ide_hwif_t *)((drive)->hwif))-> ctl_port)))) && (((((ide_hwif_t *)((drive)->hwif)) ->ctl_port))) < 256) ? __outbc_p(((drive->ctl)),(((( (ide_hwif_t *)((drive)->hwif))->ctl_port)))) : __outb_p (((drive->ctl)),(((((ide_hwif_t *)((drive)->hwif))-> ctl_port))))); | |||
1457 | OUT_BYTE(rq->nr_sectors,io_base+IDE_NSECTOR_OFFSET)((__builtin_constant_p(((io_base+(2)))) && ((io_base+ (2))) < 256) ? __outbc_p(((rq->nr_sectors)),((io_base+( 2)))) : __outb_p(((rq->nr_sectors)),((io_base+(2))))); | |||
1458 | #ifdef CONFIG_BLK_DEV_PROMISE | |||
1459 | if (IS_PROMISE_DRIVE(0)) { | |||
1460 | if (hwif->is_promise2 || rq->cmd == READ0) { | |||
1461 | use_promise_io = 1; | |||
1462 | } | |||
1463 | } | |||
1464 | if (drive->select.b.lba || use_promise_io) { | |||
1465 | #else /* !CONFIG_BLK_DEV_PROMISE */ | |||
1466 | if (drive->select.b.lba) { | |||
1467 | #endif /* CONFIG_BLK_DEV_PROMISE */ | |||
1468 | #ifdef DEBUG | |||
1469 | printk("%s: %sing: LBAsect=%ld, sectors=%ld, buffer=0x%08lx\n", | |||
1470 | drive->name, (rq->cmd==READ0)?"read":"writ", | |||
1471 | block, rq->nr_sectors, (unsigned long) rq->buffer); | |||
1472 | #endif | |||
1473 | OUT_BYTE(block,io_base+IDE_SECTOR_OFFSET)((__builtin_constant_p(((io_base+(3)))) && ((io_base+ (3))) < 256) ? __outbc_p(((block)),((io_base+(3)))) : __outb_p (((block)),((io_base+(3))))); | |||
1474 | OUT_BYTE(block>>=8,io_base+IDE_LCYL_OFFSET)((__builtin_constant_p(((io_base+(4)))) && ((io_base+ (4))) < 256) ? __outbc_p(((block>>=8)),((io_base+(4) ))) : __outb_p(((block>>=8)),((io_base+(4))))); | |||
1475 | OUT_BYTE(block>>=8,io_base+IDE_HCYL_OFFSET)((__builtin_constant_p(((io_base+(5)))) && ((io_base+ (5))) < 256) ? __outbc_p(((block>>=8)),((io_base+(5) ))) : __outb_p(((block>>=8)),((io_base+(5))))); | |||
1476 | OUT_BYTE(((block>>8)&0x0f)|drive->select.all,io_base+IDE_SELECT_OFFSET)((__builtin_constant_p(((io_base+(6)))) && ((io_base+ (6))) < 256) ? __outbc_p(((((block>>8)&0x0f)|drive ->select.all)),((io_base+(6)))) : __outb_p(((((block>> 8)&0x0f)|drive->select.all)),((io_base+(6))))); | |||
1477 | } else { | |||
1478 | unsigned int sect,head,cyl,track; | |||
1479 | track = block / drive->sect; | |||
1480 | sect = block % drive->sect + 1; | |||
1481 | OUT_BYTE(sect,io_base+IDE_SECTOR_OFFSET)((__builtin_constant_p(((io_base+(3)))) && ((io_base+ (3))) < 256) ? __outbc_p(((sect)),((io_base+(3)))) : __outb_p (((sect)),((io_base+(3))))); | |||
1482 | head = track % drive->head; | |||
1483 | cyl = track / drive->head; | |||
1484 | OUT_BYTE(cyl,io_base+IDE_LCYL_OFFSET)((__builtin_constant_p(((io_base+(4)))) && ((io_base+ (4))) < 256) ? __outbc_p(((cyl)),((io_base+(4)))) : __outb_p (((cyl)),((io_base+(4))))); | |||
1485 | OUT_BYTE(cyl>>8,io_base+IDE_HCYL_OFFSET)((__builtin_constant_p(((io_base+(5)))) && ((io_base+ (5))) < 256) ? __outbc_p(((cyl>>8)),((io_base+(5)))) : __outb_p(((cyl>>8)),((io_base+(5))))); | |||
1486 | OUT_BYTE(head|drive->select.all,io_base+IDE_SELECT_OFFSET)((__builtin_constant_p(((io_base+(6)))) && ((io_base+ (6))) < 256) ? __outbc_p(((head|drive->select.all)),((io_base +(6)))) : __outb_p(((head|drive->select.all)),((io_base+(6 ))))); | |||
1487 | #ifdef DEBUG | |||
1488 | printk("%s: %sing: CHS=%d/%d/%d, sectors=%ld, buffer=0x%08lx\n", | |||
1489 | drive->name, (rq->cmd==READ0)?"read":"writ", cyl, | |||
1490 | head, sect, rq->nr_sectors, (unsigned long) rq->buffer); | |||
1491 | #endif | |||
1492 | } | |||
1493 | #ifdef CONFIG_BLK_DEV_PROMISE | |||
1494 | if (use_promise_io) { | |||
1495 | do_promise_io (drive, rq); | |||
1496 | return; | |||
1497 | } | |||
1498 | #endif /* CONFIG_BLK_DEV_PROMISE */ | |||
1499 | if (rq->cmd == READ0) { | |||
1500 | #ifdef CONFIG_BLK_DEV_TRITON1 | |||
1501 | if (drive->using_dma && !(HWIF(drive)((ide_hwif_t *)((drive)->hwif))->dmaproc(ide_dma_read, drive))) | |||
1502 | return; | |||
1503 | #endif /* CONFIG_BLK_DEV_TRITON */ | |||
1504 | ide_set_handler(drive, &read_intr, WAIT_CMD(10*100)); | |||
1505 | OUT_BYTE(drive->mult_count ? WIN_MULTREAD : WIN_READ, io_base+IDE_COMMAND_OFFSET)((__builtin_constant_p(((io_base+(7)))) && ((io_base+ (7))) < 256) ? __outbc_p(((drive->mult_count ? 0xC4 : 0x20 )),((io_base+(7)))) : __outb_p(((drive->mult_count ? 0xC4 : 0x20)),((io_base+(7))))); | |||
1506 | return; | |||
1507 | } | |||
1508 | if (rq->cmd == WRITE1) { | |||
1509 | #ifdef CONFIG_BLK_DEV_TRITON1 | |||
1510 | if (drive->using_dma && !(HWIF(drive)((ide_hwif_t *)((drive)->hwif))->dmaproc(ide_dma_write, drive))) | |||
1511 | return; | |||
1512 | #endif /* CONFIG_BLK_DEV_TRITON */ | |||
1513 | if (drive->mult_count) | |||
1514 | ide_set_handler (drive, &multwrite_intr, WAIT_CMD(10*100)); | |||
1515 | else | |||
1516 | ide_set_handler (drive, &write_intr, WAIT_CMD(10*100)); | |||
1517 | OUT_BYTE(drive->mult_count ? WIN_MULTWRITE : WIN_WRITE, io_base+IDE_COMMAND_OFFSET)((__builtin_constant_p(((io_base+(7)))) && ((io_base+ (7))) < 256) ? __outbc_p(((drive->mult_count ? 0xC5 : 0x30 )),((io_base+(7)))) : __outb_p(((drive->mult_count ? 0xC5 : 0x30)),((io_base+(7))))); | |||
1518 | if (ide_wait_stat(drive, DATA_READY(0x08), drive->bad_wstat, WAIT_DRQ(1*100))) { | |||
1519 | printk("%s: no DRQ after issuing %s\n", drive->name, | |||
1520 | drive->mult_count ? "MULTWRITE" : "WRITE"); | |||
1521 | return; | |||
1522 | } | |||
1523 | if (!drive->unmask) | |||
1524 | cli()__asm__ __volatile__ ("cli": : :"memory"); | |||
1525 | if (drive->mult_count) { | |||
1526 | HWGROUP(drive)((ide_hwgroup_t *)(((ide_hwif_t *)((drive)->hwif))->hwgroup ))->wrq = *rq; /* scratchpad */ | |||
1527 | ide_multwrite(drive, drive->mult_count); | |||
1528 | } else { | |||
1529 | ide_output_data(drive, rq->buffer, SECTOR_WORDS(512 / 4)); | |||
1530 | } | |||
1531 | return; | |||
1532 | } | |||
1533 | printk("%s: bad command: %d\n", drive->name, rq->cmd); | |||
1534 | ide_end_request(0, HWGROUP(drive)((ide_hwgroup_t *)(((ide_hwif_t *)((drive)->hwif))->hwgroup ))); | |||
1535 | } | |||
1536 | ||||
1537 | /* | |||
1538 | * execute_drive_cmd() issues a special drive command, | |||
1539 | * usually initiated by ioctl() from the external hdparm program. | |||
1540 | */ | |||
1541 | static void execute_drive_cmd (ide_drive_t *drive, struct request *rq) | |||
1542 | { | |||
1543 | byte *args = (byte *)rq->buffer; | |||
1544 | if (args) { | |||
1545 | #ifdef DEBUG | |||
1546 | printk("%s: DRIVE_CMD cmd=0x%02x sc=0x%02x fr=0x%02x xx=0x%02x\n", | |||
1547 | drive->name, args[0], args[1], args[2], args[3]); | |||
1548 | #endif | |||
1549 | OUT_BYTE(args[2],IDE_FEATURE_REG)((__builtin_constant_p((((((ide_hwif_t *)((drive)->hwif))-> io_base+(1))))) && (((((ide_hwif_t *)((drive)->hwif ))->io_base+(1)))) < 256) ? __outbc_p(((args[2])),((((( ide_hwif_t *)((drive)->hwif))->io_base+(1))))) : __outb_p (((args[2])),(((((ide_hwif_t *)((drive)->hwif))->io_base +(1)))))); | |||
1550 | ide_cmd(drive, args[0], args[1], &drive_cmd_intr); | |||
1551 | return; | |||
1552 | } else { | |||
1553 | /* | |||
1554 | * NULL is actually a valid way of waiting for | |||
1555 | * all current requests to be flushed from the queue. | |||
1556 | */ | |||
1557 | #ifdef DEBUG | |||
1558 | printk("%s: DRIVE_CMD (null)\n", drive->name); | |||
1559 | #endif | |||
1560 | ide_end_drive_cmd(drive, GET_STAT()(byte)((__builtin_constant_p(((((ide_hwif_t *)((drive)->hwif ))->io_base+(7)))) && ((((ide_hwif_t *)((drive)-> hwif))->io_base+(7))) < 256) ? __inbc_p((((ide_hwif_t * )((drive)->hwif))->io_base+(7))) : __inb_p((((ide_hwif_t *)((drive)->hwif))->io_base+(7)))), GET_ERR()(byte)((__builtin_constant_p(((((ide_hwif_t *)((drive)->hwif ))->io_base+(1)))) && ((((ide_hwif_t *)((drive)-> hwif))->io_base+(1))) < 256) ? __inbc_p((((ide_hwif_t * )((drive)->hwif))->io_base+(1))) : __inb_p((((ide_hwif_t *)((drive)->hwif))->io_base+(1))))); | |||
1561 | return; | |||
1562 | } | |||
1563 | } | |||
1564 | ||||
1565 | /* | |||
1566 | * do_request() initiates handling of a new I/O request | |||
1567 | */ | |||
1568 | static inlineinline __attribute__((always_inline)) void do_request (ide_hwif_t *hwif, struct request *rq) | |||
1569 | { | |||
1570 | unsigned int minor, unit; | |||
1571 | unsigned long block, blockend; | |||
1572 | ide_drive_t *drive; | |||
1573 | ||||
1574 | sti()__asm__ __volatile__ ("sti": : :"memory"); | |||
1575 | #ifdef DEBUG | |||
1576 | printk("%s: do_request: current=0x%08lx\n", hwif->name, (unsigned long) rq); | |||
1577 | #endif | |||
1578 | minor = MINOR(rq->rq_dev)((rq->rq_dev) & ((1<<8) - 1)); | |||
1579 | unit = minor >> PARTN_BITS6; | |||
1580 | if (MAJOR(rq->rq_dev)((rq->rq_dev) >> 8) != hwif->major || unit >= MAX_DRIVES2) { | |||
1581 | printk("%s: bad device number: %s\n", | |||
1582 | hwif->name, kdevname(rq->rq_dev)); | |||
1583 | goto kill_rq; | |||
1584 | } | |||
1585 | drive = &hwif->drives[unit]; | |||
1586 | #ifdef DEBUG | |||
1587 | if (rq->bh && !buffer_locked(rq->bh)) { | |||
1588 | printk("%s: block not locked\n", drive->name); | |||
1589 | goto kill_rq; | |||
1590 | } | |||
1591 | #endif | |||
1592 | block = rq->sector; | |||
1593 | blockend = block + rq->nr_sectors; | |||
1594 | if ((blockend < block) || (blockend > drive->part[minor&PARTN_MASK((1<<6)-1)].nr_sects)) { | |||
1595 | #ifdef MACH1 | |||
1596 | printk ("%s%c: bad access: block=%ld, count=%ld, blockend=%ld, nr_sects%ld\n", | |||
1597 | drive->name, (minor&PARTN_MASK((1<<6)-1))?'0'+(minor&PARTN_MASK((1<<6)-1)):' ', | |||
1598 | block, rq->nr_sectors, blockend, drive->part[minor&PARTN_MASK((1<<6)-1)].nr_sects); | |||
1599 | #else | |||
1600 | printk("%s%c: bad access: block=%ld, count=%ld\n", drive->name, | |||
1601 | (minor&PARTN_MASK((1<<6)-1))?'0'+(minor&PARTN_MASK((1<<6)-1)):' ', block, rq->nr_sectors); | |||
1602 | #endif | |||
1603 | goto kill_rq; | |||
1604 | } | |||
1605 | block += drive->part[minor&PARTN_MASK((1<<6)-1)].start_sect + drive->sect0; | |||
1606 | #if FAKE_FDISK_FOR_EZDRIVE1 | |||
1607 | if (block == 0 && drive->remap_0_to_1) | |||
1608 | block = 1; /* redirect MBR access to EZ-Drive partn table */ | |||
1609 | #endif /* FAKE_FDISK_FOR_EZDRIVE */ | |||
1610 | ((ide_hwgroup_t *)hwif->hwgroup)->drive = drive; | |||
1611 | #if (DISK_RECOVERY_TIME0 > 0) | |||
1612 | while ((read_timer() - hwif->last_time) < DISK_RECOVERY_TIME0); | |||
1613 | #endif | |||
1614 | ||||
1615 | #ifdef CONFIG_BLK_DEV_IDETAPE | |||
1616 | POLL_HWIF_TAPE_DRIVE; /* macro from ide-tape.h */ | |||
1617 | #endif /* CONFIG_BLK_DEV_IDETAPE */ | |||
1618 | ||||
1619 | SELECT_DRIVE(hwif,drive)((__builtin_constant_p(((hwif->io_base+(6)))) && ( (hwif->io_base+(6))) < 256) ? __outbc_p((((drive)->select .all)),((hwif->io_base+(6)))) : __outb_p((((drive)->select .all)),((hwif->io_base+(6)))));; | |||
1620 | if (ide_wait_stat(drive, drive->ready_stat, BUSY_STAT0x80|DRQ_STAT0x08, WAIT_READY(3*100/100))) { | |||
1621 | printk("%s: drive not ready for command\n", drive->name); | |||
1622 | return; | |||
1623 | } | |||
1624 | ||||
1625 | if (!drive->special.all) { | |||
1626 | if (rq->cmd == IDE_DRIVE_CMD99) { | |||
1627 | execute_drive_cmd(drive, rq); | |||
1628 | return; | |||
1629 | } | |||
1630 | #ifdef CONFIG_BLK_DEV_IDEATAPI1 | |||
1631 | switch (drive->media) { | |||
1632 | case ide_disk: | |||
1633 | do_rw_disk (drive, rq, block); | |||
1634 | return; | |||
1635 | #ifdef CONFIG_BLK_DEV_IDECD1 | |||
1636 | case ide_cdrom: | |||
1637 | ide_do_rw_cdrom (drive, block); | |||
1638 | return; | |||
1639 | #endif /* CONFIG_BLK_DEV_IDECD */ | |||
1640 | #ifdef CONFIG_BLK_DEV_IDETAPE | |||
1641 | case ide_tape: | |||
1642 | idetape_do_request (drive, rq, block); | |||
1643 | return; | |||
1644 | #endif /* CONFIG_BLK_DEV_IDETAPE */ | |||
1645 | #ifdef CONFIG_BLK_DEV_IDEFLOPPY | |||
1646 | case ide_floppy: | |||
1647 | idefloppy_do_request (drive, rq, block); | |||
1648 | return; | |||
1649 | #endif /* CONFIG_BLK_DEV_IDEFLOPPY */ | |||
1650 | #ifdef CONFIG_BLK_DEV_IDESCSI | |||
1651 | case ide_scsi: | |||
1652 | idescsi_do_request (drive, rq, block); | |||
1653 | return; | |||
1654 | #endif /* CONFIG_BLK_DEV_IDESCSI */ | |||
1655 | ||||
1656 | default: | |||
1657 | printk("%s: media type %d not supported\n", | |||
1658 | drive->name, drive->media); | |||
1659 | goto kill_rq; | |||
1660 | } | |||
1661 | #else | |||
1662 | do_rw_disk (drive, rq, block); /* simpler and faster */ | |||
1663 | return; | |||
1664 | #endif /* CONFIG_BLK_DEV_IDEATAPI */ | |||
1665 | } | |||
1666 | do_special(drive); | |||
1667 | return; | |||
1668 | kill_rq: | |||
1669 | ide_end_request(0, hwif->hwgroup); | |||
1670 | } | |||
1671 | ||||
1672 | /* | |||
1673 | * The driver enables interrupts as much as possible. In order to do this, | |||
1674 | * (a) the device-interrupt is always masked before entry, and | |||
1675 | * (b) the timeout-interrupt is always disabled before entry. | |||
1676 | * | |||
1677 | * If we enter here from, say irq14, and then start a new request for irq15, | |||
1678 | * (possible with "serialize" option) then we cannot ensure that we exit | |||
1679 | * before the irq15 hits us. So, we must be careful not to let this bother us. | |||
1680 | * | |||
1681 | * Interrupts are still masked (by default) whenever we are exchanging | |||
1682 | * data/cmds with a drive, because some drives seem to have very poor | |||
1683 | * tolerance for latency during I/O. For devices which don't suffer from | |||
1684 | * this problem (most don't), the unmask flag can be set using the "hdparm" | |||
1685 | * utility, to permit other interrupts during data/cmd transfers. | |||
1686 | */ | |||
1687 | void ide_do_request (ide_hwgroup_t *hwgroup) | |||
1688 | { | |||
1689 | cli()__asm__ __volatile__ ("cli": : :"memory"); /* paranoia */ | |||
1690 | if (hwgroup->handler != NULL((void *) 0)) { | |||
1691 | printk("%s: EEeekk!! handler not NULL in ide_do_request()\n", hwgroup->hwif->name); | |||
1692 | return; | |||
1693 | } | |||
1694 | do { | |||
1695 | ide_hwif_t *hwif = hwgroup->hwif; | |||
1696 | struct request *rq; | |||
1697 | if ((rq = hwgroup->rq) == NULL((void *) 0)) { | |||
1698 | if (hwif->sharing_irq && hwgroup->drive) /* set nIEN */ | |||
1699 | OUT_BYTE(hwgroup->drive->ctl|2,hwif->ctl_port)((__builtin_constant_p(((hwif->ctl_port))) && ((hwif ->ctl_port)) < 256) ? __outbc_p(((hwgroup->drive-> ctl|2)),((hwif->ctl_port))) : __outb_p(((hwgroup->drive ->ctl|2)),((hwif->ctl_port)))); | |||
1700 | /* | |||
1701 | * hwgroup->next_hwif is different from hwgroup->hwif | |||
1702 | * only when a request is inserted using "ide_next". | |||
1703 | * This saves wear and tear on IDE tapes. | |||
1704 | */ | |||
1705 | hwif = hwgroup->next_hwif; | |||
1706 | do { | |||
1707 | rq = blk_dev[hwif->major].current_request; | |||
1708 | if (rq != NULL((void *) 0) && rq->rq_status != RQ_INACTIVE(-1)) | |||
1709 | goto got_rq; | |||
1710 | } while ((hwif = hwif->next) != hwgroup->next_hwif); | |||
1711 | hwgroup->active = 0; | |||
1712 | return; /* no work left for this hwgroup */ | |||
1713 | } | |||
1714 | got_rq: | |||
1715 | do_request(hwgroup->hwif = hwgroup->next_hwif = hwif, hwgroup->rq = rq); | |||
1716 | cli()__asm__ __volatile__ ("cli": : :"memory"); | |||
1717 | } while (hwgroup->handler == NULL((void *) 0)); | |||
1718 | } | |||
1719 | ||||
1720 | /* | |||
1721 | * do_hwgroup_request() invokes ide_do_request() after first masking | |||
1722 | * all possible interrupts for the current hwgroup. This prevents race | |||
1723 | * conditions in the event that an unexpected interrupt occurs while | |||
1724 | * we are in the driver. | |||
1725 | * | |||
1726 | * Note that when an interrupt is used to reenter the driver, the first level | |||
1727 | * handler will already have masked the irq that triggered, but any other ones | |||
1728 | * for the hwgroup will still be unmasked. The driver tries to be careful | |||
1729 | * about such things. | |||
1730 | */ | |||
1731 | static void do_hwgroup_request (ide_hwgroup_t *hwgroup) | |||
1732 | { | |||
1733 | if (hwgroup->handler == NULL((void *) 0)) { | |||
1734 | ide_hwif_t *hgif = hwgroup->hwif; | |||
1735 | ide_hwif_t *hwif = hgif; | |||
1736 | hwgroup->active = 1; | |||
1737 | do { | |||
1738 | disable_irq(hwif->irq); | |||
1739 | } while ((hwif = hwif->next) != hgif); | |||
1740 | ide_do_request (hwgroup); | |||
1741 | do { | |||
1742 | enable_irq(hwif->irq); | |||
1743 | } while ((hwif = hwif->next) != hgif); | |||
1744 | } | |||
1745 | } | |||
1746 | ||||
1747 | static void do_ide0_request (void) /* invoked with cli() */ | |||
1748 | { | |||
1749 | do_hwgroup_request (ide_hwifs[0].hwgroup); | |||
1750 | } | |||
1751 | ||||
1752 | #if MAX_HWIFS4 > 1 | |||
1753 | static void do_ide1_request (void) /* invoked with cli() */ | |||
1754 | { | |||
1755 | do_hwgroup_request (ide_hwifs[1].hwgroup); | |||
1756 | } | |||
1757 | #endif | |||
1758 | ||||
1759 | #if MAX_HWIFS4 > 2 | |||
1760 | static void do_ide2_request (void) /* invoked with cli() */ | |||
1761 | { | |||
1762 | do_hwgroup_request (ide_hwifs[2].hwgroup); | |||
1763 | } | |||
1764 | #endif | |||
1765 | ||||
1766 | #if MAX_HWIFS4 > 3 | |||
1767 | static void do_ide3_request (void) /* invoked with cli() */ | |||
1768 | { | |||
1769 | do_hwgroup_request (ide_hwifs[3].hwgroup); | |||
1770 | } | |||
1771 | #endif | |||
1772 | ||||
1773 | static void timer_expiry (unsigned long data) | |||
1774 | { | |||
1775 | ide_hwgroup_t *hwgroup = (ide_hwgroup_t *) data; | |||
1776 | ide_drive_t *drive = hwgroup->drive; | |||
1777 | unsigned long flags; | |||
1778 | ||||
1779 | save_flags(flags)__asm__ __volatile__("pushf ; pop %0" : "=r" (flags): :"memory" ); | |||
1780 | cli()__asm__ __volatile__ ("cli": : :"memory"); | |||
1781 | ||||
1782 | if (hwgroup->poll_timeout != 0) { /* polling in progress? */ | |||
1783 | ide_handler_t *handler = hwgroup->handler; | |||
1784 | hwgroup->handler = NULL((void *) 0); | |||
1785 | handler(drive); | |||
1786 | } else if (hwgroup->handler == NULL((void *) 0)) { /* not waiting for anything? */ | |||
1787 | sti()__asm__ __volatile__ ("sti": : :"memory"); /* drive must have responded just as the timer expired */ | |||
1788 | printk("%s: marginal timeout\n", drive->name); | |||
1789 | } else { | |||
1790 | hwgroup->handler = NULL((void *) 0); /* abort the operation */ | |||
1791 | if (hwgroup->hwif->dmaproc) | |||
1792 | (void) hwgroup->hwif->dmaproc (ide_dma_abort, drive); | |||
1793 | ide_error(drive, "irq timeout", GET_STAT()(byte)((__builtin_constant_p(((((ide_hwif_t *)((drive)->hwif ))->io_base+(7)))) && ((((ide_hwif_t *)((drive)-> hwif))->io_base+(7))) < 256) ? __inbc_p((((ide_hwif_t * )((drive)->hwif))->io_base+(7))) : __inb_p((((ide_hwif_t *)((drive)->hwif))->io_base+(7))))); | |||
1794 | } | |||
1795 | if (hwgroup->handler == NULL((void *) 0)) | |||
1796 | do_hwgroup_request (hwgroup); | |||
1797 | restore_flags(flags)__asm__ __volatile__("push %0 ; popf": :"g" (flags):"memory"); | |||
1798 | } | |||
1799 | ||||
1800 | /* | |||
1801 | * There's nothing really useful we can do with an unexpected interrupt, | |||
1802 | * other than reading the status register (to clear it), and logging it. | |||
1803 | * There should be no way that an irq can happen before we're ready for it, | |||
1804 | * so we needn't worry much about losing an "important" interrupt here. | |||
1805 | * | |||
1806 | * On laptops (and "green" PCs), an unexpected interrupt occurs whenever the | |||
1807 | * drive enters "idle", "standby", or "sleep" mode, so if the status looks | |||
1808 | * "good", we just ignore the interrupt completely. | |||
1809 | * | |||
1810 | * This routine assumes cli() is in effect when called. | |||
1811 | * | |||
1812 | * If an unexpected interrupt happens on irq15 while we are handling irq14 | |||
1813 | * and if the two interfaces are "serialized" (CMD640), then it looks like | |||
1814 | * we could screw up by interfering with a new request being set up for irq15. | |||
1815 | * | |||
1816 | * In reality, this is a non-issue. The new command is not sent unless the | |||
1817 | * drive is ready to accept one, in which case we know the drive is not | |||
1818 | * trying to interrupt us. And ide_set_handler() is always invoked before | |||
1819 | * completing the issuance of any new drive command, so we will not be | |||
1820 | * accidently invoked as a result of any valid command completion interrupt. | |||
1821 | * | |||
1822 | */ | |||
1823 | static void unexpected_intr (int irq, ide_hwgroup_t *hwgroup) | |||
1824 | { | |||
1825 | byte stat; | |||
1826 | unsigned int unit; | |||
1827 | ide_hwif_t *hwif = hwgroup->hwif; | |||
1828 | ||||
1829 | /* | |||
1830 | * handle the unexpected interrupt | |||
1831 | */ | |||
1832 | do { | |||
1833 | if (hwif->irq == irq) { | |||
1834 | for (unit = 0; unit < MAX_DRIVES2; ++unit) { | |||
1835 | ide_drive_t *drive = &hwif->drives[unit]; | |||
1836 | if (!drive->present) | |||
1837 | continue; | |||
1838 | SELECT_DRIVE(hwif,drive)((__builtin_constant_p(((hwif->io_base+(6)))) && ( (hwif->io_base+(6))) < 256) ? __outbc_p((((drive)->select .all)),((hwif->io_base+(6)))) : __outb_p((((drive)->select .all)),((hwif->io_base+(6)))));; | |||
1839 | udelay(100)(__builtin_constant_p(100) ? __const_udelay((100) * 0x10c6ul) : __udelay(100)); /* Ugly, but wait_stat() may not be safe here */ | |||
1840 | if (!OK_STAT(stat=GET_STAT(), drive->ready_stat, BAD_STAT)(((stat=(byte)((__builtin_constant_p(((((ide_hwif_t *)((drive )->hwif))->io_base+(7)))) && ((((ide_hwif_t *)( (drive)->hwif))->io_base+(7))) < 256) ? __inbc_p(((( ide_hwif_t *)((drive)->hwif))->io_base+(7))) : __inb_p( (((ide_hwif_t *)((drive)->hwif))->io_base+(7)))))&( (drive->ready_stat)|(((0x80 | 0x01) | 0x08))))==(drive-> ready_stat))) { | |||
1841 | /* Try to not flood the console with msgs */ | |||
1842 | static unsigned long last_msgtime = 0; | |||
1843 | if ((last_msgtime + (HZ100/2)) < jiffies) { | |||
1844 | last_msgtime = jiffies; | |||
1845 | (void) ide_dump_status(drive, "unexpected_intr", stat); | |||
1846 | } | |||
1847 | } | |||
1848 | if ((stat & DRQ_STAT0x08)) | |||
1849 | try_to_flush_leftover_data(drive); | |||
1850 | } | |||
1851 | } | |||
1852 | } while ((hwif = hwif->next) != hwgroup->hwif); | |||
1853 | SELECT_DRIVE(hwif,hwgroup->drive)((__builtin_constant_p(((hwif->io_base+(6)))) && ( (hwif->io_base+(6))) < 256) ? __outbc_p((((hwgroup-> drive)->select.all)),((hwif->io_base+(6)))) : __outb_p( (((hwgroup->drive)->select.all)),((hwif->io_base+(6) ))));; /* Ugh.. probably interrupts current I/O */ | |||
1854 | udelay(100)(__builtin_constant_p(100) ? __const_udelay((100) * 0x10c6ul) : __udelay(100)); /* Ugly, but wait_stat() may not be safe here */ | |||
1855 | } | |||
1856 | ||||
1857 | /* | |||
1858 | * entry point for all interrupts, caller does cli() for us | |||
1859 | */ | |||
1860 | void ide_intr (int irq, void *dev_id, struct pt_regs *regs) | |||
1861 | { | |||
1862 | ide_hwgroup_t *hwgroup = dev_id; | |||
1863 | ide_handler_t *handler; | |||
1864 | ||||
1865 | if (irq == hwgroup->hwif->irq && (handler = hwgroup->handler) != NULL((void *) 0)) { | |||
1866 | ide_drive_t *drive = hwgroup->drive; | |||
1867 | hwgroup->handler = NULL((void *) 0); | |||
1868 | del_timer(&(hwgroup->timer)); | |||
1869 | if (drive->unmask) | |||
1870 | sti()__asm__ __volatile__ ("sti": : :"memory"); | |||
1871 | handler(drive); | |||
1872 | cli()__asm__ __volatile__ ("cli": : :"memory"); /* this is necessary, as next rq may be different irq */ | |||
1873 | if (hwgroup->handler == NULL((void *) 0)) { | |||
1874 | SET_RECOVERY_TIMER(HWIF(drive)); | |||
1875 | ide_do_request(hwgroup); | |||
1876 | } | |||
1877 | } else { | |||
1878 | unexpected_intr(irq, hwgroup); | |||
1879 | } | |||
1880 | cli()__asm__ __volatile__ ("cli": : :"memory"); | |||
1881 | } | |||
1882 | ||||
1883 | /* | |||
1884 | * get_info_ptr() returns the (ide_drive_t *) for a given device number. | |||
1885 | * It returns NULL if the given device number does not match any present drives. | |||
1886 | */ | |||
1887 | static ide_drive_t *get_info_ptr (kdev_t i_rdev) | |||
1888 | { | |||
1889 | int major = MAJOR(i_rdev)((i_rdev) >> 8); | |||
1890 | unsigned int h; | |||
1891 | ||||
1892 | for (h = 0; h < MAX_HWIFS4; ++h) { | |||
1893 | ide_hwif_t *hwif = &ide_hwifs[h]; | |||
1894 | if (hwif->present && major == hwif->major) { | |||
1895 | unsigned unit = DEVICE_NR(i_rdev)(((i_rdev) & ((1<<8) - 1)) >> 6); | |||
1896 | if (unit < MAX_DRIVES2) { | |||
1897 | ide_drive_t *drive = &hwif->drives[unit]; | |||
1898 | if (drive->present) | |||
1899 | return drive; | |||
1900 | } else if (major == IDE0_MAJOR3 && unit < 4) { | |||
1901 | printk("ide: probable bad entry for /dev/hd%c\n", 'a'+unit); | |||
1902 | printk("ide: to fix it, run: /usr/src/linux/scripts/MAKEDEV.ide\n"); | |||
1903 | } | |||
1904 | break; | |||
1905 | } | |||
1906 | } | |||
1907 | return NULL((void *) 0); | |||
1908 | } | |||
1909 | ||||
1910 | /* | |||
1911 | * This function is intended to be used prior to invoking ide_do_drive_cmd(). | |||
1912 | */ | |||
1913 | void ide_init_drive_cmd (struct request *rq) | |||
1914 | { | |||
1915 | rq->buffer = NULL((void *) 0); | |||
1916 | rq->cmd = IDE_DRIVE_CMD99; | |||
1917 | rq->sector = 0; | |||
1918 | rq->nr_sectors = 0; | |||
1919 | rq->current_nr_sectors = 0; | |||
1920 | rq->sem = NULL((void *) 0); | |||
1921 | rq->bh = NULL((void *) 0); | |||
1922 | rq->bhtail = NULL((void *) 0); | |||
1923 | rq->next = NULL((void *) 0); | |||
1924 | ||||
1925 | #if 0 /* these are done each time through ide_do_drive_cmd() */ | |||
1926 | rq->errors = 0; | |||
1927 | rq->rq_status = RQ_ACTIVE1; | |||
1928 | rq->rq_dev = ????; | |||
1929 | #endif | |||
1930 | rq->quiet = 0; | |||
1931 | } | |||
1932 | ||||
1933 | /* | |||
1934 | * This function issues a special IDE device request | |||
1935 | * onto the request queue. | |||
1936 | * | |||
1937 | * If action is ide_wait, then the rq is queued at the end of the | |||
1938 | * request queue, and the function sleeps until it has been processed. | |||
1939 | * This is for use when invoked from an ioctl handler. | |||
1940 | * | |||
1941 | * If action is ide_preempt, then the rq is queued at the head of | |||
1942 | * the request queue, displacing the currently-being-processed | |||
1943 | * request and this function returns immediately without waiting | |||
1944 | * for the new rq to be completed. This is VERY DANGEROUS, and is | |||
1945 | * intended for careful use by the ATAPI tape/cdrom driver code. | |||
1946 | * | |||
1947 | * If action is ide_next, then the rq is queued immediately after | |||
1948 | * the currently-being-processed-request (if any), and the function | |||
1949 | * returns without waiting for the new rq to be completed. As above, | |||
1950 | * This is VERY DANGEROUS, and is intended for careful use by the | |||
1951 | * ATAPI tape/cdrom driver code. | |||
1952 | * | |||
1953 | * If action is ide_end, then the rq is queued at the end of the | |||
1954 | * request queue, and the function returns immediately without waiting | |||
1955 | * for the new rq to be completed. This is again intended for careful | |||
1956 | * use by the ATAPI tape/cdrom driver code. (Currently used by ide-tape.c, | |||
1957 | * when operating in the pipelined operation mode). | |||
1958 | */ | |||
1959 | int ide_do_drive_cmd (ide_drive_t *drive, struct request *rq, ide_action_t action) | |||
1960 | { | |||
1961 | unsigned long flags; | |||
1962 | unsigned int major = HWIF(drive)((ide_hwif_t *)((drive)->hwif))->major; | |||
1963 | struct request *cur_rq; | |||
1964 | struct blk_dev_struct *bdev = &blk_dev[major]; | |||
1965 | struct semaphore sem = MUTEX_LOCKED((struct semaphore) { 0, 0, 0, ((void *) 0) }); | |||
1966 | ||||
1967 | if (IS_PROMISE_DRIVE(0) && rq->buffer != NULL((void *) 0)) | |||
1968 | return -ENOSYS38; /* special drive cmds not supported */ | |||
1969 | rq->errors = 0; | |||
1970 | rq->rq_status = RQ_ACTIVE1; | |||
1971 | rq->rq_dev = MKDEV(major,(drive->select.b.unit)<<PARTN_BITS)(((major) << 8) | ((drive->select.b.unit)<<6)); | |||
1972 | if (action == ide_wait) | |||
1973 | rq->sem = &sem; | |||
1974 | unplug_device(bdev); | |||
1975 | ||||
1976 | save_flags(flags)__asm__ __volatile__("pushf ; pop %0" : "=r" (flags): :"memory" ); | |||
1977 | cli()__asm__ __volatile__ ("cli": : :"memory"); | |||
1978 | if (action == ide_next) | |||
1979 | HWGROUP(drive)((ide_hwgroup_t *)(((ide_hwif_t *)((drive)->hwif))->hwgroup ))->next_hwif = HWIF(drive)((ide_hwif_t *)((drive)->hwif)); | |||
1980 | cur_rq = bdev->current_request; | |||
1981 | ||||
1982 | if (cur_rq == NULL((void *) 0) || action == ide_preempt) { | |||
1983 | rq->next = cur_rq; | |||
1984 | bdev->current_request = rq; | |||
1985 | if (action == ide_preempt) | |||
1986 | HWGROUP(drive)((ide_hwgroup_t *)(((ide_hwif_t *)((drive)->hwif))->hwgroup ))->rq = NULL((void *) 0); | |||
1987 | } else { | |||
1988 | if (action == ide_wait || action == ide_end) { | |||
1989 | while (cur_rq->next != NULL((void *) 0)) /* find end of list */ | |||
1990 | cur_rq = cur_rq->next; | |||
1991 | } | |||
1992 | rq->next = cur_rq->next; | |||
1993 | cur_rq->next = rq; | |||
1994 | } | |||
1995 | if (!HWGROUP(drive)((ide_hwgroup_t *)(((ide_hwif_t *)((drive)->hwif))->hwgroup ))->active) { | |||
1996 | do_hwgroup_request(HWGROUP(drive)((ide_hwgroup_t *)(((ide_hwif_t *)((drive)->hwif))->hwgroup ))); | |||
1997 | cli()__asm__ __volatile__ ("cli": : :"memory"); | |||
1998 | } | |||
1999 | if (action == ide_wait && rq->rq_status != RQ_INACTIVE(-1)) | |||
2000 | down(&sem); /* wait for it to be serviced */ | |||
2001 | restore_flags(flags)__asm__ __volatile__("push %0 ; popf": :"g" (flags):"memory"); | |||
2002 | return rq->errors ? -EIO5 : 0; /* return -EIO if errors */ | |||
2003 | } | |||
2004 | ||||
2005 | static int ide_open(struct inode * inode, struct file * filp) | |||
2006 | { | |||
2007 | ide_drive_t *drive; | |||
2008 | unsigned long flags; | |||
2009 | ||||
2010 | if ((drive = get_info_ptr(inode->i_rdev)) == NULL((void *) 0)) | |||
2011 | return -ENXIO6; | |||
2012 | save_flags(flags)__asm__ __volatile__("pushf ; pop %0" : "=r" (flags): :"memory" ); | |||
2013 | cli()__asm__ __volatile__ ("cli": : :"memory"); | |||
2014 | while (drive->busy) | |||
2015 | sleep_on(&drive->wqueue); | |||
2016 | drive->usage++; | |||
2017 | restore_flags(flags)__asm__ __volatile__("push %0 ; popf": :"g" (flags):"memory"); | |||
2018 | #ifdef CONFIG_BLK_DEV_IDECD1 | |||
2019 | if (drive->media == ide_cdrom) | |||
2020 | return ide_cdrom_open (inode, filp, drive); | |||
2021 | #endif /* CONFIG_BLK_DEV_IDECD */ | |||
2022 | #ifdef CONFIG_BLK_DEV_IDETAPE | |||
2023 | if (drive->media == ide_tape) | |||
2024 | return idetape_blkdev_open (inode, filp, drive); | |||
2025 | #endif /* CONFIG_BLK_DEV_IDETAPE */ | |||
2026 | #ifdef CONFIG_BLK_DEV_IDEFLOPPY | |||
2027 | if (drive->media == ide_floppy) | |||
2028 | return idefloppy_open (inode, filp, drive); | |||
2029 | #endif /* CONFIG_BLK_DEV_IDEFLOPPY */ | |||
2030 | #ifdef CONFIG_BLK_DEV_IDESCSI | |||
2031 | if (drive->media == ide_scsi) | |||
2032 | return idescsi_open (inode, filp, drive); | |||
2033 | #endif /* CONFIG_BLK_DEV_IDESCSI */ | |||
2034 | if (drive->removable && drive->usage == 1) { | |||
2035 | byte door_lock[] = {WIN_DOORLOCK0xde,0,0,0}; | |||
2036 | struct request rq; | |||
2037 | check_disk_change(inode->i_rdev); | |||
2038 | ide_init_drive_cmd (&rq); | |||
2039 | rq.buffer = (char *)door_lock; | |||
2040 | /* | |||
2041 | * Ignore the return code from door_lock, | |||
2042 | * since the open() has already succeeded, | |||
2043 | * and the door_lock is irrelevant at this point. | |||
2044 | */ | |||
2045 | (void) ide_do_drive_cmd(drive, &rq, ide_wait); | |||
2046 | } | |||
2047 | return 0; | |||
2048 | } | |||
2049 | ||||
2050 | /* | |||
2051 | * Releasing a block device means we sync() it, so that it can safely | |||
2052 | * be forgotten about... | |||
2053 | */ | |||
2054 | static void ide_release(struct inode * inode, struct file * file) | |||
2055 | { | |||
2056 | ide_drive_t *drive; | |||
2057 | ||||
2058 | if ((drive = get_info_ptr(inode->i_rdev)) != NULL((void *) 0)) { | |||
2059 | fsync_dev(inode->i_rdev); | |||
2060 | drive->usage--; | |||
2061 | #ifdef CONFIG_BLK_DEV_IDECD1 | |||
2062 | if (drive->media == ide_cdrom) { | |||
2063 | ide_cdrom_release (inode, file, drive); | |||
2064 | return; | |||
2065 | } | |||
2066 | #endif /* CONFIG_BLK_DEV_IDECD */ | |||
2067 | #ifdef CONFIG_BLK_DEV_IDETAPE | |||
2068 | if (drive->media == ide_tape) { | |||
2069 | idetape_blkdev_release (inode, file, drive); | |||
2070 | return; | |||
2071 | } | |||
2072 | #endif /* CONFIG_BLK_DEV_IDETAPE */ | |||
2073 | #ifdef CONFIG_BLK_DEV_IDEFLOPPY | |||
2074 | if (drive->media == ide_floppy) { | |||
2075 | idefloppy_release (inode, file, drive); | |||
2076 | return; | |||
2077 | } | |||
2078 | #endif /* CONFIG_BLK_DEV_IDEFLOPPY */ | |||
2079 | #ifdef CONFIG_BLK_DEV_IDESCSI | |||
2080 | if (drive->media == ide_scsi) { | |||
2081 | idescsi_ide_release (inode, file, drive); | |||
2082 | return; | |||
2083 | } | |||
2084 | #endif /* CONFIG_BLK_DEV_IDESCSI */ | |||
2085 | if (drive->removable && !drive->usage) { | |||
2086 | byte door_unlock[] = {WIN_DOORUNLOCK0xdf,0,0,0}; | |||
2087 | struct request rq; | |||
2088 | invalidate_buffers(inode->i_rdev); | |||
2089 | ide_init_drive_cmd (&rq); | |||
2090 | rq.buffer = (char *)door_unlock; | |||
2091 | (void) ide_do_drive_cmd(drive, &rq, ide_wait); | |||
2092 | } | |||
2093 | } | |||
2094 | } | |||
2095 | ||||
2096 | /* | |||
2097 | * This routine is called to flush all partitions and partition tables | |||
2098 | * for a changed disk, and then re-read the new partition table. | |||
2099 | * If we are revalidating a disk because of a media change, then we | |||
2100 | * enter with usage == 0. If we are using an ioctl, we automatically have | |||
2101 | * usage == 1 (we need an open channel to use an ioctl :-), so this | |||
2102 | * is our limit. | |||
2103 | */ | |||
2104 | static int revalidate_disk(kdev_t i_rdev) | |||
2105 | { | |||
2106 | ide_drive_t *drive; | |||
2107 | unsigned int p, major, minor; | |||
2108 | long flags; | |||
2109 | ||||
2110 | if ((drive = get_info_ptr(i_rdev)) == NULL((void *) 0)) | |||
2111 | return -ENODEV19; | |||
2112 | ||||
2113 | major = MAJOR(i_rdev)((i_rdev) >> 8); | |||
2114 | minor = drive->select.b.unit << PARTN_BITS6; | |||
2115 | save_flags(flags)__asm__ __volatile__("pushf ; pop %0" : "=r" (flags): :"memory" ); | |||
2116 | cli()__asm__ __volatile__ ("cli": : :"memory"); | |||
2117 | if (drive->busy || (drive->usage > 1)) { | |||
2118 | restore_flags(flags)__asm__ __volatile__("push %0 ; popf": :"g" (flags):"memory"); | |||
2119 | return -EBUSY16; | |||
2120 | }; | |||
2121 | drive->busy = 1; | |||
2122 | restore_flags(flags)__asm__ __volatile__("push %0 ; popf": :"g" (flags):"memory"); | |||
2123 | ||||
2124 | for (p = 0; p < (1<<PARTN_BITS6); ++p) { | |||
2125 | if (drive->part[p].nr_sects > 0) { | |||
2126 | kdev_t devp = MKDEV(major, minor+p)(((major) << 8) | (minor+p)); | |||
2127 | fsync_dev (devp); | |||
2128 | invalidate_inodes (devp); | |||
2129 | invalidate_buffers (devp); | |||
2130 | set_blocksize(devp, 1024); | |||
2131 | } | |||
2132 | drive->part[p].start_sect = 0; | |||
2133 | drive->part[p].nr_sects = 0; | |||
2134 | }; | |||
2135 | ||||
2136 | drive->part[0].nr_sects = current_capacity(drive); | |||
2137 | if ((drive->media != ide_disk && drive->media != ide_floppy) || !drive->part[0].nr_sects) | |||
2138 | drive->part[0].start_sect = -1; | |||
2139 | resetup_one_dev(HWIF(drive)((ide_hwif_t *)((drive)->hwif))->gd, drive->select.b.unit); | |||
2140 | ||||
2141 | drive->busy = 0; | |||
2142 | wake_up(&drive->wqueue); | |||
2143 | return 0; | |||
2144 | } | |||
2145 | ||||
2146 | static int write_fs_long (unsigned long useraddr, long value) | |||
2147 | { | |||
2148 | int err; | |||
2149 | ||||
2150 | if (NULL((void *) 0) == (long *)useraddr) | |||
2151 | return -EINVAL22; | |||
2152 | if ((err = verify_area(VERIFY_WRITE1, (long *)useraddr, sizeof(long)))) | |||
2153 | return err; | |||
2154 | put_user((unsigned)value, (long *) useraddr)__put_user((unsigned long)((unsigned)value),((long *) useraddr ),sizeof(*((long *) useraddr))); | |||
2155 | return 0; | |||
2156 | } | |||
2157 | ||||
2158 | static int ide_ioctl (struct inode *inode, struct file *file, | |||
2159 | unsigned int cmd, unsigned long arg) | |||
2160 | { | |||
2161 | int err; | |||
2162 | ide_drive_t *drive; | |||
2163 | unsigned long flags; | |||
2164 | struct request rq; | |||
2165 | ||||
2166 | if (!inode || !(inode->i_rdev)) | |||
| ||||
2167 | return -EINVAL22; | |||
2168 | if ((drive = get_info_ptr(inode->i_rdev)) == NULL((void *) 0)) | |||
2169 | return -ENODEV19; | |||
2170 | ide_init_drive_cmd (&rq); | |||
2171 | switch (cmd) { | |||
2172 | case HDIO_GETGEO0x0301: | |||
2173 | { | |||
2174 | struct hd_geometry *loc = (struct hd_geometry *) arg; | |||
2175 | if (!loc || (drive->media != ide_disk && drive->media != ide_floppy)) return -EINVAL22; | |||
2176 | #ifdef MACH1 | |||
2177 | loc->heads = drive->bios_head; | |||
2178 | loc->sectors = drive->bios_sect; | |||
2179 | loc->cylinders = drive->bios_cyl; | |||
2180 | loc->start | |||
2181 | = (drive->part[MINOR(inode->i_rdev)((inode->i_rdev) & ((1<<8) - 1))&PARTN_MASK((1<<6)-1)] | |||
2182 | .start_sect); | |||
2183 | #else | |||
2184 | err = verify_area(VERIFY_WRITE1, loc, sizeof(*loc)); | |||
2185 | if (err) return err; | |||
2186 | put_user(drive->bios_head, (byte *) &loc->heads)__put_user((unsigned long)(drive->bios_head),((byte *) & loc->heads),sizeof(*((byte *) &loc->heads))); | |||
2187 | put_user(drive->bios_sect, (byte *) &loc->sectors)__put_user((unsigned long)(drive->bios_sect),((byte *) & loc->sectors),sizeof(*((byte *) &loc->sectors))); | |||
2188 | put_user(drive->bios_cyl, (unsigned short *) &loc->cylinders)__put_user((unsigned long)(drive->bios_cyl),((unsigned short *) &loc->cylinders),sizeof(*((unsigned short *) & loc->cylinders))); | |||
2189 | put_user((unsigned)drive->part[MINOR(inode->i_rdev)&PARTN_MASK].start_sect,__put_user((unsigned long)((unsigned)drive->part[((inode-> i_rdev) & ((1<<8) - 1))&((1<<6)-1)].start_sect ),((unsigned long *) &loc->start),sizeof(*((unsigned long *) &loc->start))) | |||
2190 | (unsigned long *) &loc->start)__put_user((unsigned long)((unsigned)drive->part[((inode-> i_rdev) & ((1<<8) - 1))&((1<<6)-1)].start_sect ),((unsigned long *) &loc->start),sizeof(*((unsigned long *) &loc->start))); | |||
2191 | #endif | |||
2192 | return 0; | |||
2193 | } | |||
2194 | case BLKFLSBUF(((0U) << (((0 +8)+8)+14)) | (((0x12)) << (0 +8)) | (((97)) << 0) | ((0) << ((0 +8)+8))): | |||
2195 | if (!suser()) return -EACCES13; | |||
2196 | fsync_dev(inode->i_rdev); | |||
2197 | invalidate_buffers(inode->i_rdev); | |||
2198 | return 0; | |||
2199 | ||||
2200 | case BLKRASET(((0U) << (((0 +8)+8)+14)) | (((0x12)) << (0 +8)) | (((98)) << 0) | ((0) << ((0 +8)+8))): | |||
2201 | if (!suser()) return -EACCES13; | |||
2202 | if(arg > 0xff) return -EINVAL22; | |||
2203 | read_ahead[MAJOR(inode->i_rdev)((inode->i_rdev) >> 8)] = arg; | |||
2204 | return 0; | |||
2205 | ||||
2206 | case BLKRAGET(((0U) << (((0 +8)+8)+14)) | (((0x12)) << (0 +8)) | (((99)) << 0) | ((0) << ((0 +8)+8))): | |||
2207 | return write_fs_long(arg, read_ahead[MAJOR(inode->i_rdev)((inode->i_rdev) >> 8)]); | |||
2208 | ||||
2209 | case BLKGETSIZE(((0U) << (((0 +8)+8)+14)) | (((0x12)) << (0 +8)) | (((96)) << 0) | ((0) << ((0 +8)+8))): /* Return device size */ | |||
2210 | return write_fs_long(arg, drive->part[MINOR(inode->i_rdev)((inode->i_rdev) & ((1<<8) - 1))&PARTN_MASK((1<<6)-1)].nr_sects); | |||
2211 | case BLKRRPART(((0U) << (((0 +8)+8)+14)) | (((0x12)) << (0 +8)) | (((95)) << 0) | ((0) << ((0 +8)+8))): /* Re-read partition tables */ | |||
2212 | if (!suser()) return -EACCES13; | |||
2213 | return revalidate_disk(inode->i_rdev); | |||
2214 | ||||
2215 | case HDIO_GET_KEEPSETTINGS0x0308: | |||
2216 | return write_fs_long(arg, drive->keep_settings); | |||
2217 | ||||
2218 | case HDIO_GET_UNMASKINTR0x0302: | |||
2219 | return write_fs_long(arg, drive->unmask); | |||
2220 | ||||
2221 | case HDIO_GET_DMA0x030b: | |||
2222 | return write_fs_long(arg, drive->using_dma); | |||
2223 | ||||
2224 | case HDIO_GET_32BIT0x0309: | |||
2225 | return write_fs_long(arg, drive->io_32bit); | |||
2226 | ||||
2227 | case HDIO_GET_MULTCOUNT0x0304: | |||
2228 | return write_fs_long(arg, drive->mult_count); | |||
2229 | ||||
2230 | case HDIO_GET_IDENTITY0x030d: | |||
2231 | if (!arg || (MINOR(inode->i_rdev)((inode->i_rdev) & ((1<<8) - 1)) & PARTN_MASK((1<<6)-1))) | |||
2232 | return -EINVAL22; | |||
2233 | if (drive->id == NULL((void *) 0)) | |||
2234 | return -ENOMSG42; | |||
2235 | err = verify_area(VERIFY_WRITE1, (char *)arg, sizeof(*drive->id)); | |||
2236 | if (!err) | |||
2237 | memcpy_tofs((char *)arg, (char *)drive->id, sizeof(*drive->id)); | |||
2238 | return err; | |||
2239 | ||||
2240 | case HDIO_GET_NOWERR0x030a: | |||
2241 | return write_fs_long(arg, drive->bad_wstat == BAD_R_STAT(0x80 | 0x01)); | |||
2242 | ||||
2243 | case HDIO_SET_DMA0x0326: | |||
2244 | if (!suser()) return -EACCES13; | |||
2245 | #ifdef CONFIG_BLK_DEV_IDECD1 | |||
2246 | if (drive->media == ide_cdrom) | |||
2247 | return -EPERM1; | |||
2248 | #endif /* CONFIG_BLK_DEV_IDECD */ | |||
2249 | if (!drive->id || !(drive->id->capability & 1) || !HWIF(drive)((ide_hwif_t *)((drive)->hwif))->dmaproc) | |||
2250 | return -EPERM1; | |||
2251 | case HDIO_SET_KEEPSETTINGS0x0323: | |||
2252 | case HDIO_SET_UNMASKINTR0x0322: | |||
2253 | case HDIO_SET_NOWERR0x0325: | |||
2254 | if (arg > 1) | |||
2255 | return -EINVAL22; | |||
2256 | case HDIO_SET_32BIT0x0324: | |||
2257 | if (!suser()) return -EACCES13; | |||
2258 | if ((MINOR(inode->i_rdev)((inode->i_rdev) & ((1<<8) - 1)) & PARTN_MASK((1<<6)-1))) | |||
2259 | return -EINVAL22; | |||
2260 | save_flags(flags)__asm__ __volatile__("pushf ; pop %0" : "=r" (flags): :"memory" ); | |||
2261 | cli()__asm__ __volatile__ ("cli": : :"memory"); | |||
2262 | switch (cmd) { | |||
2263 | case HDIO_SET_DMA0x0326: | |||
2264 | if (!(HWIF(drive)((ide_hwif_t *)((drive)->hwif))->dmaproc)) { | |||
2265 | restore_flags(flags)__asm__ __volatile__("push %0 ; popf": :"g" (flags):"memory"); | |||
2266 | return -EPERM1; | |||
2267 | } | |||
2268 | drive->using_dma = arg; | |||
2269 | break; | |||
2270 | case HDIO_SET_KEEPSETTINGS0x0323: | |||
2271 | drive->keep_settings = arg; | |||
2272 | break; | |||
2273 | case HDIO_SET_UNMASKINTR0x0322: | |||
2274 | if (arg && drive->no_unmask) { | |||
2275 | restore_flags(flags)__asm__ __volatile__("push %0 ; popf": :"g" (flags):"memory"); | |||
2276 | return -EPERM1; | |||
2277 | } | |||
2278 | drive->unmask = arg; | |||
2279 | break; | |||
2280 | case HDIO_SET_NOWERR0x0325: | |||
2281 | drive->bad_wstat = arg ? BAD_R_STAT(0x80 | 0x01) : BAD_W_STAT((0x80 | 0x01) | 0x20); | |||
2282 | break; | |||
2283 | case HDIO_SET_32BIT0x0324: | |||
2284 | if (arg > (1 + (SUPPORT_VLB_SYNC1<<1))) { | |||
2285 | restore_flags(flags)__asm__ __volatile__("push %0 ; popf": :"g" (flags):"memory"); | |||
2286 | return -EINVAL22; | |||
2287 | } | |||
2288 | if (arg && drive->no_io_32bit) { | |||
2289 | restore_flags(flags)__asm__ __volatile__("push %0 ; popf": :"g" (flags):"memory"); | |||
2290 | return -EPERM1; | |||
2291 | } | |||
2292 | drive->io_32bit = arg; | |||
2293 | #ifdef CONFIG_BLK_DEV_DTC2278 | |||
2294 | if (HWIF(drive)((ide_hwif_t *)((drive)->hwif))->chipset == ide_dtc2278) | |||
2295 | HWIF(drive)((ide_hwif_t *)((drive)->hwif))->drives[!drive->select.b.unit].io_32bit = arg; | |||
2296 | #endif /* CONFIG_BLK_DEV_DTC2278 */ | |||
2297 | break; | |||
2298 | } | |||
2299 | restore_flags(flags)__asm__ __volatile__("push %0 ; popf": :"g" (flags):"memory"); | |||
2300 | return 0; | |||
2301 | ||||
2302 | case HDIO_SET_MULTCOUNT0x0321: | |||
2303 | if (!suser()) return -EACCES13; | |||
2304 | if (MINOR(inode->i_rdev)((inode->i_rdev) & ((1<<8) - 1)) & PARTN_MASK((1<<6)-1)) | |||
2305 | return -EINVAL22; | |||
2306 | if (drive->id && arg > drive->id->max_multsect) | |||
2307 | return -EINVAL22; | |||
2308 | save_flags(flags)__asm__ __volatile__("pushf ; pop %0" : "=r" (flags): :"memory" ); | |||
2309 | cli()__asm__ __volatile__ ("cli": : :"memory"); | |||
2310 | if (drive->special.b.set_multmode) { | |||
2311 | restore_flags(flags)__asm__ __volatile__("push %0 ; popf": :"g" (flags):"memory"); | |||
2312 | return -EBUSY16; | |||
2313 | } | |||
2314 | drive->mult_req = arg; | |||
2315 | drive->special.b.set_multmode = 1; | |||
2316 | restore_flags(flags)__asm__ __volatile__("push %0 ; popf": :"g" (flags):"memory"); | |||
2317 | (void) ide_do_drive_cmd (drive, &rq, ide_wait); | |||
2318 | return (drive->mult_count == arg) ? 0 : -EIO5; | |||
2319 | ||||
2320 | case HDIO_DRIVE_CMD0x031f: | |||
2321 | { | |||
2322 | byte args[4], *argbuf = args; | |||
2323 | int argsize = 4; | |||
2324 | if (!suser() || securelevel > 0) return -EACCES13; | |||
2325 | if (NULL((void *) 0) == (void *) arg) { | |||
2326 | err = ide_do_drive_cmd(drive, &rq, ide_wait); | |||
2327 | } else if (!(err = verify_area(VERIFY_READ0,(void *)arg, 4))) { | |||
2328 | memcpy_fromfs(args, (void *)arg, 4); | |||
2329 | if (args[3]) { | |||
2330 | argsize = 4 + (SECTOR_WORDS(512 / 4) * 4 * args[3]); | |||
2331 | argbuf = kmalloclinux_kmalloc(argsize, GFP_KERNEL0x03); | |||
2332 | if (argbuf == NULL((void *) 0)) | |||
2333 | return -ENOMEM12; | |||
2334 | argbuf[0] = args[0]; | |||
2335 | argbuf[1] = args[1]; | |||
2336 | argbuf[2] = args[2]; | |||
2337 | argbuf[3] = args[3]; | |||
2338 | } | |||
2339 | if (!(err = verify_area(VERIFY_WRITE1,(void *)arg, argsize))) { | |||
2340 | rq.buffer = (char *)argbuf; | |||
2341 | err = ide_do_drive_cmd(drive, &rq, ide_wait); | |||
2342 | memcpy_tofs((void *)arg, argbuf, argsize); | |||
2343 | } | |||
2344 | if (argsize > 4) | |||
2345 | kfreelinux_kfree(argbuf); | |||
2346 | } | |||
2347 | return err; | |||
2348 | } | |||
2349 | case HDIO_SET_PIO_MODE0x0327: | |||
2350 | if (!suser()) return -EACCES13; | |||
2351 | if (MINOR(inode->i_rdev)((inode->i_rdev) & ((1<<8) - 1)) & PARTN_MASK((1<<6)-1)) | |||
2352 | return -EINVAL22; | |||
2353 | if (!HWIF(drive)((ide_hwif_t *)((drive)->hwif))->tuneproc) | |||
2354 | return -ENOSYS38; | |||
2355 | save_flags(flags)__asm__ __volatile__("pushf ; pop %0" : "=r" (flags): :"memory" ); | |||
2356 | cli()__asm__ __volatile__ ("cli": : :"memory"); | |||
2357 | if (drive->special.b.set_tune) { | |||
2358 | restore_flags(flags)__asm__ __volatile__("push %0 ; popf": :"g" (flags):"memory"); | |||
2359 | return -EBUSY16; | |||
2360 | } | |||
2361 | drive->tune_req = (byte) arg; | |||
2362 | drive->special.b.set_tune = 1; | |||
2363 | restore_flags(flags)__asm__ __volatile__("push %0 ; popf": :"g" (flags):"memory"); | |||
2364 | (void) ide_do_drive_cmd (drive, &rq, ide_wait); | |||
2365 | return 0; | |||
2366 | ||||
2367 | RO_IOCTLS(inode->i_rdev, arg)case (((0U) << (((0 +8)+8)+14)) | (((0x12)) << (0 +8)) | (((93)) << 0) | ((0) << ((0 +8)+8))): { int __err; if (!suser()) return -13; __err = verify_area(0, (void *) (arg), sizeof(long)); if (!__err) set_device_ro((inode-> i_rdev),__get_user((const unsigned int *)((long *) (arg)),4)) ; return __err; } case (((0U) << (((0 +8)+8)+14)) | ((( 0x12)) << (0 +8)) | (((94)) << 0) | ((0) << ((0 +8)+8))): { int __err = verify_area(1, (void *) (arg), sizeof (long)); if (!__err) __put_user((0!=is_read_only(inode->i_rdev )),(unsigned int *)((long *) (arg)),4); return __err; }; | |||
2368 | ||||
2369 | default: | |||
2370 | #ifdef CONFIG_BLK_DEV_IDECD1 | |||
2371 | if (drive->media == ide_cdrom) | |||
2372 | return ide_cdrom_ioctl(drive, inode, file, cmd, arg); | |||
2373 | #endif /* CONFIG_BLK_DEV_IDECD */ | |||
2374 | #ifdef CONFIG_BLK_DEV_IDETAPE | |||
2375 | if (drive->media == ide_tape) | |||
2376 | return idetape_blkdev_ioctl(drive, inode, file, cmd, arg); | |||
2377 | #endif /* CONFIG_BLK_DEV_IDETAPE */ | |||
2378 | #ifdef CONFIG_BLK_DEV_IDEFLOPPY | |||
2379 | if (drive->media == ide_floppy) | |||
2380 | return idefloppy_ioctl(drive, inode, file, cmd, arg); | |||
2381 | #endif /* CONFIG_BLK_DEV_IDEFLOPPY */ | |||
2382 | #ifdef CONFIG_BLK_DEV_IDESCSI | |||
2383 | if (drive->media == ide_scsi) | |||
2384 | return idescsi_ioctl(drive, inode, file, cmd, arg); | |||
2385 | #endif /* CONFIG_BLK_DEV_IDESCSI */ | |||
2386 | return -EPERM1; | |||
2387 | } | |||
2388 | } | |||
| ||||
2389 | ||||
2390 | static int ide_check_media_change (kdev_t i_rdev) | |||
2391 | { | |||
2392 | ide_drive_t *drive; | |||
2393 | ||||
2394 | if ((drive = get_info_ptr(i_rdev)) == NULL((void *) 0)) | |||
2395 | return -ENODEV19; | |||
2396 | #ifdef CONFIG_BLK_DEV_IDECD1 | |||
2397 | if (drive->media == ide_cdrom) | |||
2398 | return ide_cdrom_check_media_change (drive); | |||
2399 | #endif /* CONFIG_BLK_DEV_IDECD */ | |||
2400 | #ifdef CONFIG_BLK_DEV_IDEFLOPPY | |||
2401 | if (drive->media == ide_floppy) | |||
2402 | return idefloppy_media_change (drive); | |||
2403 | #endif /* CONFIG_BLK_DEV_IDEFLOPPY */ | |||
2404 | if (drive->removable) /* for disks */ | |||
2405 | return 1; /* always assume it was changed */ | |||
2406 | return 0; | |||
2407 | } | |||
2408 | ||||
2409 | void ide_fixstring (byte *s, const int bytecount, const int byteswap) | |||
2410 | { | |||
2411 | byte *p = s, *end = &s[bytecount & ~1]; /* bytecount must be even */ | |||
2412 | ||||
2413 | if (byteswap) { | |||
2414 | /* convert from big-endian to host byte order */ | |||
2415 | for (p = end ; p != s;) { | |||
2416 | unsigned short *pp = (unsigned short *) (p -= 2); | |||
2417 | *pp = ntohs(*pp); | |||
2418 | } | |||
2419 | } | |||
2420 | ||||
2421 | /* strip leading blanks */ | |||
2422 | while (s != end && *s == ' ') | |||
2423 | ++s; | |||
2424 | ||||
2425 | /* compress internal blanks and strip trailing blanks */ | |||
2426 | while (s != end && *s) { | |||
2427 | if (*s++ != ' ' || (s != end && *s && *s != ' ')) | |||
2428 | *p++ = *(s-1); | |||
2429 | } | |||
2430 | ||||
2431 | /* wipe out trailing garbage */ | |||
2432 | while (p != end) | |||
2433 | *p++ = '\0'; | |||
2434 | } | |||
2435 | ||||
2436 | static inlineinline __attribute__((always_inline)) void do_identify (ide_drive_t *drive, byte cmd) | |||
2437 | { | |||
2438 | int bswap; | |||
2439 | struct hd_driveid *id; | |||
2440 | unsigned long capacity, check; | |||
2441 | ||||
2442 | id = drive->id = kmalloclinux_kmalloc (SECTOR_WORDS(512 / 4)*4, GFP_KERNEL0x03); | |||
2443 | ide_input_data(drive, id, SECTOR_WORDS(512 / 4));/* read 512 bytes of id info */ | |||
2444 | sti()__asm__ __volatile__ ("sti": : :"memory"); | |||
2445 | ||||
2446 | #if defined (CONFIG_SCSI_EATA_DMA) || defined (CONFIG_SCSI_EATA_PIO1) || defined (CONFIG_SCSI_EATA1) | |||
2447 | /* | |||
2448 | * EATA SCSI controllers do a hardware ATA emulation: | |||
2449 | * Ignore them if there is a driver for them available. | |||
2450 | */ | |||
2451 | if ((id->model[0] == 'P' && id->model[1] == 'M') | |||
2452 | || (id->model[0] == 'S' && id->model[1] == 'K')) { | |||
2453 | printk("%s: EATA SCSI HBA %.10s\n", drive->name, id->model); | |||
2454 | drive->present = 0; | |||
2455 | return; | |||
2456 | } | |||
2457 | #endif | |||
2458 | ||||
2459 | /* | |||
2460 | * WIN_IDENTIFY returns little-endian info, | |||
2461 | * WIN_PIDENTIFY *usually* returns little-endian info. | |||
2462 | */ | |||
2463 | bswap = 1; | |||
2464 | if (cmd == WIN_PIDENTIFY0xA1) { | |||
2465 | if ((id->model[0] == 'N' && id->model[1] == 'E') /* NEC */ | |||
2466 | || (id->model[0] == 'F' && id->model[1] == 'X') /* Mitsumi */ | |||
2467 | || (id->model[0] == 'P' && id->model[1] == 'i'))/* Pioneer */ | |||
2468 | bswap = 0; /* Vertos drives may still be weird */ | |||
2469 | } | |||
2470 | ide_fixstring (id->model, sizeof(id->model), bswap); | |||
2471 | ide_fixstring (id->fw_rev, sizeof(id->fw_rev), bswap); | |||
2472 | ide_fixstring (id->serial_no, sizeof(id->serial_no), bswap); | |||
2473 | ||||
2474 | if (strstr((char *)id->model, "E X A B Y T E N E S T")) | |||
2475 | return; | |||
2476 | ||||
2477 | #ifdef CONFIG_BLK_DEV_IDEATAPI1 | |||
2478 | /* | |||
2479 | * Check for an ATAPI device | |||
2480 | */ | |||
2481 | if (cmd == WIN_PIDENTIFY0xA1) { | |||
2482 | byte type = (id->config >> 8) & 0x1f; | |||
2483 | printk("%s: %s, ATAPI ", drive->name, id->model); | |||
2484 | #ifdef CONFIG_BLK_DEV_PROMISE | |||
2485 | if (HWIF(drive)((ide_hwif_t *)((drive)->hwif))->is_promise2) { | |||
2486 | printk(" -- not supported on 2nd Promise port\n"); | |||
2487 | drive->present = 0; | |||
2488 | return; | |||
2489 | } | |||
2490 | #endif /* CONFIG_BLK_DEV_PROMISE */ | |||
2491 | if (!drive->ide_scsi) switch (type) { | |||
2492 | case 0: | |||
2493 | if (!strstr((char *)id->model, "oppy") && | |||
2494 | !strstr((char *)id->model, "poyp") && | |||
2495 | !strstr((char *)id->model, "ZIP")) | |||
2496 | printk("cdrom or floppy?, assuming "); | |||
2497 | if (drive->media != ide_cdrom && | |||
2498 | !strstr((char *)id->model, "CD-ROM")) { | |||
2499 | #ifdef CONFIG_BLK_DEV_IDEFLOPPY | |||
2500 | printk("FLOPPY drive\n"); | |||
2501 | drive->media = ide_floppy; | |||
2502 | if (idefloppy_identify_device(drive, id)) | |||
2503 | drive->present = 1; | |||
2504 | return; | |||
2505 | #else | |||
2506 | printk("FLOPPY "); | |||
2507 | break; | |||
2508 | #endif /* CONFIG_BLK_DEV_IDEFLOPPY */ | |||
2509 | } | |||
2510 | /* Early cdrom models used zero */ | |||
2511 | case 5: | |||
2512 | #ifdef CONFIG_BLK_DEV_IDECD1 | |||
2513 | printk ("CDROM drive\n"); | |||
2514 | drive->media = ide_cdrom; | |||
2515 | drive->present = 1; | |||
2516 | drive->removable = 1; | |||
2517 | return; | |||
2518 | #else | |||
2519 | printk ("CDROM "); | |||
2520 | break; | |||
2521 | #endif /* CONFIG_BLK_DEV_IDECD */ | |||
2522 | case 1: | |||
2523 | #ifdef CONFIG_BLK_DEV_IDETAPE | |||
2524 | printk ("TAPE drive"); | |||
2525 | if (idetape_identify_device (drive,id)) { | |||
2526 | drive->media = ide_tape; | |||
2527 | drive->present = 1; | |||
2528 | drive->removable = 1; | |||
2529 | if (drive->autotune != 2 && HWIF(drive)((ide_hwif_t *)((drive)->hwif))->dmaproc != NULL((void *) 0)) { | |||
2530 | if (!HWIF(drive)((ide_hwif_t *)((drive)->hwif))->dmaproc(ide_dma_check, drive)) | |||
2531 | printk(", DMA"); | |||
2532 | } | |||
2533 | printk("\n"); | |||
2534 | } | |||
2535 | else { | |||
2536 | drive->present = 0; | |||
2537 | printk ("\nide-tape: the tape is not supported by this version of the driver\n"); | |||
2538 | } | |||
2539 | return; | |||
2540 | #else | |||
2541 | printk ("TAPE "); | |||
2542 | break; | |||
2543 | #endif /* CONFIG_BLK_DEV_IDETAPE */ | |||
2544 | default: | |||
2545 | drive->present = 0; | |||
2546 | printk("Type %d - Unknown device\n", type); | |||
2547 | return; | |||
2548 | } | |||
2549 | #ifdef CONFIG_BLK_DEV_IDESCSI | |||
2550 | printk("drive - enabling SCSI emulation\n"); | |||
2551 | drive->media = ide_scsi; | |||
2552 | drive->present = 1; | |||
2553 | idescsi_setup(drive); | |||
2554 | #else | |||
2555 | drive->present = 0; | |||
2556 | printk("- not supported by this kernel\n"); | |||
2557 | #endif /* CONFIG_BLK_DEV_IDESCSI */ | |||
2558 | return; | |||
2559 | } | |||
2560 | #endif /* CONFIG_BLK_DEV_IDEATAPI */ | |||
2561 | ||||
2562 | /* check for removable disks (eg. SYQUEST), ignore 'WD' drives */ | |||
2563 | if (id->config & (1<<7)) { /* removable disk ? */ | |||
2564 | if (id->model[0] != 'W' || id->model[1] != 'D') | |||
2565 | drive->removable = 1; | |||
2566 | } | |||
2567 | ||||
2568 | /* SunDisk drives: treat as non-removable, force one unit */ | |||
2569 | if (id->model[0] == 'S' && id->model[1] == 'u') { | |||
2570 | drive->removable = 0; | |||
2571 | if (drive->select.all & (1<<4)) { | |||
2572 | drive->present = 0; | |||
2573 | return; | |||
2574 | } | |||
2575 | } | |||
2576 | ||||
2577 | drive->media = ide_disk; | |||
2578 | /* Extract geometry if we did not already have one for the drive */ | |||
2579 | if (!drive->present) { | |||
2580 | drive->present = 1; | |||
2581 | drive->cyl = drive->bios_cyl = id->cyls; | |||
2582 | drive->head = drive->bios_head = id->heads; | |||
2583 | drive->sect = drive->bios_sect = id->sectors; | |||
2584 | } | |||
2585 | /* Handle logical geometry translation by the drive */ | |||
2586 | if ((id->field_valid & 1) && id->cur_cyls && id->cur_heads | |||
2587 | && (id->cur_heads <= 16) && id->cur_sectors) { | |||
2588 | /* | |||
2589 | * Extract the physical drive geometry for our use. | |||
2590 | * Note that we purposely do *not* update the bios info. | |||
2591 | * This way, programs that use it (like fdisk) will | |||
2592 | * still have the same logical view as the BIOS does, | |||
2593 | * which keeps the partition table from being screwed. | |||
2594 | * | |||
2595 | * An exception to this is the cylinder count, | |||
2596 | * which we reexamine later on to correct for 1024 limitations. | |||
2597 | */ | |||
2598 | drive->cyl = id->cur_cyls; | |||
2599 | drive->head = id->cur_heads; | |||
2600 | drive->sect = id->cur_sectors; | |||
2601 | ||||
2602 | /* check for word-swapped "capacity" field in id information */ | |||
2603 | capacity = drive->cyl * drive->head * drive->sect; | |||
2604 | check = (id->cur_capacity0 << 16) | id->cur_capacity1; | |||
2605 | if (check == capacity) { /* was it swapped? */ | |||
2606 | /* yes, bring it into little-endian order: */ | |||
2607 | id->cur_capacity0 = (capacity >> 0) & 0xffff; | |||
2608 | id->cur_capacity1 = (capacity >> 16) & 0xffff; | |||
2609 | } | |||
2610 | } | |||
2611 | /* Use physical geometry if what we have still makes no sense */ | |||
2612 | if ((!drive->head || drive->head > 16) && | |||
2613 | id->heads && id->heads <= 16) { | |||
2614 | drive->cyl = id->cyls; | |||
2615 | drive->head = id->heads; | |||
2616 | drive->sect = id->sectors; | |||
2617 | } | |||
2618 | ||||
2619 | /* calculate drive capacity, and select LBA if possible */ | |||
2620 | capacity = current_capacity (drive); | |||
2621 | ||||
2622 | /* | |||
2623 | * if possible, give fdisk access to more of the drive, | |||
2624 | * by correcting bios_cyls: | |||
2625 | */ | |||
2626 | if (capacity > drive->bios_cyl * drive->bios_head * drive->bios_sect | |||
2627 | && !drive->forced_geom && drive->bios_sect && drive->bios_head) { | |||
2628 | int cyl = (capacity / drive->bios_sect) / drive->bios_head; | |||
2629 | if (cyl <= 65535) | |||
2630 | drive->bios_cyl = cyl; | |||
2631 | else { | |||
2632 | /* OK until 539 GB */ | |||
2633 | drive->bios_sect = 63; | |||
2634 | drive->bios_head = 255; | |||
2635 | drive->bios_cyl = capacity / (63*255); | |||
2636 | } | |||
2637 | } | |||
2638 | ||||
2639 | if (!strncmp((char *)id->model, "BMI ", 4) && | |||
2640 | strstr((char *)id->model, " ENHANCED IDE ") && | |||
2641 | drive->select.b.lba) | |||
2642 | drive->no_geom = 1; | |||
2643 | ||||
2644 | printk ("%s: %.40s, %ldMB w/%dkB Cache, CHS=%d/%d/%d", | |||
2645 | drive->name, id->model, current_capacity(drive)/2048L, id->buf_size/2, | |||
2646 | drive->bios_cyl, drive->bios_head, drive->bios_sect); | |||
2647 | ||||
2648 | drive->mult_count = 0; | |||
2649 | if (id->max_multsect) { | |||
2650 | drive->mult_req = INITIAL_MULT_COUNT16; | |||
2651 | if (drive->mult_req > id->max_multsect) | |||
2652 | drive->mult_req = id->max_multsect; | |||
2653 | if (drive->mult_req || ((id->multsect_valid & 1) && id->multsect)) | |||
2654 | drive->special.b.set_multmode = 1; | |||
2655 | } | |||
2656 | if (drive->autotune != 2 && HWIF(drive)((ide_hwif_t *)((drive)->hwif))->dmaproc != NULL((void *) 0)) { | |||
2657 | if (!(HWIF(drive)((ide_hwif_t *)((drive)->hwif))->dmaproc(ide_dma_check, drive))) { | |||
2658 | if ((id->field_valid & 4) && (id->dma_ultra & (id->dma_ultra >> 8) & 7)) | |||
2659 | printk(", UDMA"); | |||
2660 | else | |||
2661 | printk(", DMA"); | |||
2662 | } | |||
2663 | } | |||
2664 | printk("\n"); | |||
2665 | } | |||
2666 | ||||
2667 | /* | |||
2668 | * Delay for *at least* 50ms. As we don't know how much time is left | |||
2669 | * until the next tick occurs, we wait an extra tick to be safe. | |||
2670 | * This is used only during the probing/polling for drives at boot time. | |||
2671 | */ | |||
2672 | static void delay_50ms (void) | |||
2673 | { | |||
2674 | unsigned long timer = jiffies + ((HZ100 + 19)/20) + 1; | |||
2675 | while (timer > jiffies); | |||
2676 | } | |||
2677 | ||||
2678 | /* | |||
2679 | * try_to_identify() sends an ATA(PI) IDENTIFY request to a drive | |||
2680 | * and waits for a response. It also monitors irqs while this is | |||
2681 | * happening, in hope of automatically determining which one is | |||
2682 | * being used by the interface. | |||
2683 | * | |||
2684 | * Returns: 0 device was identified | |||
2685 | * 1 device timed-out (no response to identify request) | |||
2686 | * 2 device aborted the command (refused to identify itself) | |||
2687 | */ | |||
2688 | static int try_to_identify (ide_drive_t *drive, byte cmd) | |||
2689 | { | |||
2690 | int hd_status, rc; | |||
2691 | unsigned long timeout; | |||
2692 | unsigned long irqs_on = 0; | |||
2693 | int irq_off; | |||
2694 | ||||
2695 | if (!HWIF(drive)((ide_hwif_t *)((drive)->hwif))->irq) { /* already got an IRQ? */ | |||
2696 | probe_irq_off(probe_irq_on()); /* clear dangling irqs */ | |||
2697 | irqs_on = probe_irq_on(); /* start monitoring irqs */ | |||
2698 | OUT_BYTE(drive->ctl,IDE_CONTROL_REG)((__builtin_constant_p((((((ide_hwif_t *)((drive)->hwif))-> ctl_port)))) && (((((ide_hwif_t *)((drive)->hwif)) ->ctl_port))) < 256) ? __outbc_p(((drive->ctl)),(((( (ide_hwif_t *)((drive)->hwif))->ctl_port)))) : __outb_p (((drive->ctl)),(((((ide_hwif_t *)((drive)->hwif))-> ctl_port))))); /* enable device irq */ | |||
2699 | } | |||
2700 | ||||
2701 | delay_50ms(); /* take a deep breath */ | |||
2702 | if ((IN_BYTE(IDE_ALTSTATUS_REG)(byte)((__builtin_constant_p(((((ide_hwif_t *)((drive)->hwif ))->ctl_port))) && ((((ide_hwif_t *)((drive)->hwif ))->ctl_port)) < 256) ? __inbc_p((((ide_hwif_t *)((drive )->hwif))->ctl_port)) : __inb_p((((ide_hwif_t *)((drive )->hwif))->ctl_port))) ^ IN_BYTE(IDE_STATUS_REG)(byte)((__builtin_constant_p(((((ide_hwif_t *)((drive)->hwif ))->io_base+(7)))) && ((((ide_hwif_t *)((drive)-> hwif))->io_base+(7))) < 256) ? __inbc_p((((ide_hwif_t * )((drive)->hwif))->io_base+(7))) : __inb_p((((ide_hwif_t *)((drive)->hwif))->io_base+(7))))) & ~INDEX_STAT0x02) { | |||
2703 | printk("%s: probing with STATUS instead of ALTSTATUS\n", drive->name); | |||
2704 | hd_status = IDE_STATUS_REG(((ide_hwif_t *)((drive)->hwif))->io_base+(7)); /* ancient Seagate drives */ | |||
2705 | } else | |||
2706 | hd_status = IDE_ALTSTATUS_REG(((ide_hwif_t *)((drive)->hwif))->ctl_port); /* use non-intrusive polling */ | |||
2707 | ||||
2708 | #if CONFIG_BLK_DEV_PROMISE | |||
2709 | if (IS_PROMISE_DRIVE(0)) { | |||
2710 | if (promise_cmd(drive,PROMISE_IDENTIFY)) { | |||
2711 | if (irqs_on) | |||
2712 | (void) probe_irq_off(irqs_on); | |||
2713 | return 1; | |||
2714 | } | |||
2715 | } else | |||
2716 | #endif /* CONFIG_BLK_DEV_PROMISE */ | |||
2717 | OUT_BYTE(cmd,IDE_COMMAND_REG)((__builtin_constant_p((((((ide_hwif_t *)((drive)->hwif))-> io_base+(7))))) && (((((ide_hwif_t *)((drive)->hwif ))->io_base+(7)))) < 256) ? __outbc_p(((cmd)),(((((ide_hwif_t *)((drive)->hwif))->io_base+(7))))) : __outb_p(((cmd)) ,(((((ide_hwif_t *)((drive)->hwif))->io_base+(7)))))); /* ask drive for ID */ | |||
2718 | timeout = ((cmd == WIN_IDENTIFY0xEC) ? WAIT_WORSTCASE(30*100) : WAIT_PIDENTIFY(1*100)) / 2; | |||
2719 | timeout += jiffies; | |||
2720 | do { | |||
2721 | if (jiffies > timeout) { | |||
2722 | if (irqs_on) | |||
2723 | (void) probe_irq_off(irqs_on); | |||
2724 | return 1; /* drive timed-out */ | |||
2725 | } | |||
2726 | delay_50ms(); /* give drive a breather */ | |||
2727 | } while (IN_BYTE(hd_status)(byte)((__builtin_constant_p((hd_status)) && (hd_status ) < 256) ? __inbc_p(hd_status) : __inb_p(hd_status)) & BUSY_STAT0x80); | |||
2728 | ||||
2729 | delay_50ms(); /* wait for IRQ and DRQ_STAT */ | |||
2730 | if (OK_STAT(GET_STAT(),DRQ_STAT,BAD_R_STAT)((((byte)((__builtin_constant_p(((((ide_hwif_t *)((drive)-> hwif))->io_base+(7)))) && ((((ide_hwif_t *)((drive )->hwif))->io_base+(7))) < 256) ? __inbc_p((((ide_hwif_t *)((drive)->hwif))->io_base+(7))) : __inb_p((((ide_hwif_t *)((drive)->hwif))->io_base+(7)))))&((0x08)|((0x80 | 0x01))))==(0x08))) { | |||
2731 | unsigned long flags; | |||
2732 | save_flags(flags)__asm__ __volatile__("pushf ; pop %0" : "=r" (flags): :"memory" ); | |||
2733 | cli()__asm__ __volatile__ ("cli": : :"memory"); /* some systems need this */ | |||
2734 | do_identify(drive, cmd); /* drive returned ID */ | |||
2735 | rc = 0; /* drive responded with ID */ | |||
2736 | (void) GET_STAT()(byte)((__builtin_constant_p(((((ide_hwif_t *)((drive)->hwif ))->io_base+(7)))) && ((((ide_hwif_t *)((drive)-> hwif))->io_base+(7))) < 256) ? __inbc_p((((ide_hwif_t * )((drive)->hwif))->io_base+(7))) : __inb_p((((ide_hwif_t *)((drive)->hwif))->io_base+(7)))); /* clear drive IRQ */ | |||
2737 | restore_flags(flags)__asm__ __volatile__("push %0 ; popf": :"g" (flags):"memory"); | |||
2738 | } else | |||
2739 | rc = 2; /* drive refused ID */ | |||
2740 | if (!HWIF(drive)((ide_hwif_t *)((drive)->hwif))->irq) { | |||
2741 | irq_off = probe_irq_off(irqs_on); /* get our irq number */ | |||
2742 | if (irq_off > 0) { | |||
2743 | HWIF(drive)((ide_hwif_t *)((drive)->hwif))->irq = irq_off; /* save it for later */ | |||
2744 | irqs_on = probe_irq_on(); | |||
2745 | OUT_BYTE(drive->ctl|2,IDE_CONTROL_REG)((__builtin_constant_p((((((ide_hwif_t *)((drive)->hwif))-> ctl_port)))) && (((((ide_hwif_t *)((drive)->hwif)) ->ctl_port))) < 256) ? __outbc_p(((drive->ctl|2)),(( (((ide_hwif_t *)((drive)->hwif))->ctl_port)))) : __outb_p (((drive->ctl|2)),(((((ide_hwif_t *)((drive)->hwif))-> ctl_port))))); /* mask device irq */ | |||
2746 | udelay(5)(__builtin_constant_p(5) ? __const_udelay((5) * 0x10c6ul) : __udelay (5)); | |||
2747 | (void) probe_irq_off(irqs_on); | |||
2748 | (void) probe_irq_off(probe_irq_on()); /* clear self-inflicted irq */ | |||
2749 | (void) GET_STAT()(byte)((__builtin_constant_p(((((ide_hwif_t *)((drive)->hwif ))->io_base+(7)))) && ((((ide_hwif_t *)((drive)-> hwif))->io_base+(7))) < 256) ? __inbc_p((((ide_hwif_t * )((drive)->hwif))->io_base+(7))) : __inb_p((((ide_hwif_t *)((drive)->hwif))->io_base+(7)))); /* clear drive IRQ */ | |||
2750 | ||||
2751 | } else { /* Mmmm.. multiple IRQs.. don't know which was ours */ | |||
2752 | printk("%s: IRQ probe failed (%d)\n", drive->name, irq_off); | |||
2753 | #ifdef CONFIG_BLK_DEV_CMD640 | |||
2754 | #ifdef CMD640_DUMP_REGS | |||
2755 | if (HWIF(drive)((ide_hwif_t *)((drive)->hwif))->chipset == ide_cmd640) { | |||
2756 | printk("%s: Hmmm.. probably a driver problem.\n", drive->name); | |||
2757 | CMD640_DUMP_REGS; | |||
2758 | } | |||
2759 | #endif /* CMD640_DUMP_REGS */ | |||
2760 | #endif /* CONFIG_BLK_DEV_CMD640 */ | |||
2761 | } | |||
2762 | } | |||
2763 | return rc; | |||
2764 | } | |||
2765 | ||||
2766 | /* | |||
2767 | * do_probe() has the difficult job of finding a drive if it exists, | |||
2768 | * without getting hung up if it doesn't exist, without trampling on | |||
2769 | * ethernet cards, and without leaving any IRQs dangling to haunt us later. | |||
2770 | * | |||
2771 | * If a drive is "known" to exist (from CMOS or kernel parameters), | |||
2772 | * but does not respond right away, the probe will "hang in there" | |||
2773 | * for the maximum wait time (about 30 seconds), otherwise it will | |||
2774 | * exit much more quickly. | |||
2775 | * | |||
2776 | * Returns: 0 device was identified | |||
2777 | * 1 device timed-out (no response to identify request) | |||
2778 | * 2 device aborted the command (refused to identify itself) | |||
2779 | * 3 bad status from device (possible for ATAPI drives) | |||
2780 | * 4 probe was not attempted because failure was obvious | |||
2781 | */ | |||
2782 | static int do_probe (ide_drive_t *drive, byte cmd) | |||
2783 | { | |||
2784 | int rc; | |||
2785 | ide_hwif_t *hwif = HWIF(drive)((ide_hwif_t *)((drive)->hwif)); | |||
2786 | unsigned long timeout; | |||
2787 | #ifdef CONFIG_BLK_DEV_IDEATAPI1 | |||
2788 | if (drive->present) { /* avoid waiting for inappropriate probes */ | |||
2789 | if ((drive->media != ide_disk) && (cmd == WIN_IDENTIFY0xEC)) | |||
2790 | return 4; | |||
2791 | } | |||
2792 | #endif /* CONFIG_BLK_DEV_IDEATAPI */ | |||
2793 | #ifdef DEBUG | |||
2794 | printk("probing for %s: present=%d, media=%d, probetype=%s\n", | |||
2795 | drive->name, drive->present, drive->media, | |||
2796 | (cmd == WIN_IDENTIFY0xEC) ? "ATA" : "ATAPI"); | |||
2797 | #endif | |||
2798 | SELECT_DRIVE(hwif,drive)((__builtin_constant_p(((hwif->io_base+(6)))) && ( (hwif->io_base+(6))) < 256) ? __outbc_p((((drive)->select .all)),((hwif->io_base+(6)))) : __outb_p((((drive)->select .all)),((hwif->io_base+(6)))));; | |||
2799 | delay_50ms(); | |||
2800 | if (IN_BYTE(IDE_SELECT_REG)(byte)((__builtin_constant_p(((((ide_hwif_t *)((drive)->hwif ))->io_base+(6)))) && ((((ide_hwif_t *)((drive)-> hwif))->io_base+(6))) < 256) ? __inbc_p((((ide_hwif_t * )((drive)->hwif))->io_base+(6))) : __inb_p((((ide_hwif_t *)((drive)->hwif))->io_base+(6)))) != drive->select.all && !drive->present) { | |||
2801 | OUT_BYTE(0xa0,IDE_SELECT_REG)((__builtin_constant_p((((((ide_hwif_t *)((drive)->hwif))-> io_base+(6))))) && (((((ide_hwif_t *)((drive)->hwif ))->io_base+(6)))) < 256) ? __outbc_p(((0xa0)),(((((ide_hwif_t *)((drive)->hwif))->io_base+(6))))) : __outb_p(((0xa0) ),(((((ide_hwif_t *)((drive)->hwif))->io_base+(6)))))); /* exit with drive0 selected */ | |||
2802 | delay_50ms(); /* allow BUSY_STAT to assert & clear */ | |||
2803 | return 3; /* no i/f present: avoid killing ethernet cards */ | |||
2804 | } | |||
2805 | ||||
2806 | if (OK_STAT(GET_STAT(),READY_STAT,BUSY_STAT)((((byte)((__builtin_constant_p(((((ide_hwif_t *)((drive)-> hwif))->io_base+(7)))) && ((((ide_hwif_t *)((drive )->hwif))->io_base+(7))) < 256) ? __inbc_p((((ide_hwif_t *)((drive)->hwif))->io_base+(7))) : __inb_p((((ide_hwif_t *)((drive)->hwif))->io_base+(7)))))&((0x40)|(0x80) ))==(0x40)) | |||
2807 | || drive->present || cmd == WIN_PIDENTIFY0xA1) | |||
2808 | { | |||
2809 | if ((rc = try_to_identify(drive,cmd))) /* send cmd and wait */ | |||
2810 | rc = try_to_identify(drive,cmd); /* failed: try again */ | |||
2811 | if (rc == 1 && cmd == WIN_PIDENTIFY0xA1 && drive->autotune != 2) { | |||
2812 | printk("%s: no response (status = 0x%02x), resetting drive\n", drive->name, GET_STAT()(byte)((__builtin_constant_p(((((ide_hwif_t *)((drive)->hwif ))->io_base+(7)))) && ((((ide_hwif_t *)((drive)-> hwif))->io_base+(7))) < 256) ? __inbc_p((((ide_hwif_t * )((drive)->hwif))->io_base+(7))) : __inb_p((((ide_hwif_t *)((drive)->hwif))->io_base+(7))))); | |||
2813 | delay_50ms(); | |||
2814 | OUT_BYTE (drive->select.all, IDE_SELECT_REG)((__builtin_constant_p((((((ide_hwif_t *)((drive)->hwif))-> io_base+(6))))) && (((((ide_hwif_t *)((drive)->hwif ))->io_base+(6)))) < 256) ? __outbc_p(((drive->select .all)),(((((ide_hwif_t *)((drive)->hwif))->io_base+(6)) ))) : __outb_p(((drive->select.all)),(((((ide_hwif_t *)((drive )->hwif))->io_base+(6)))))); | |||
2815 | delay_50ms(); | |||
2816 | OUT_BYTE(WIN_SRST, IDE_COMMAND_REG)((__builtin_constant_p((((((ide_hwif_t *)((drive)->hwif))-> io_base+(7))))) && (((((ide_hwif_t *)((drive)->hwif ))->io_base+(7)))) < 256) ? __outbc_p(((0x08)),(((((ide_hwif_t *)((drive)->hwif))->io_base+(7))))) : __outb_p(((0x08) ),(((((ide_hwif_t *)((drive)->hwif))->io_base+(7)))))); | |||
2817 | timeout = jiffies; | |||
2818 | while ((GET_STAT()(byte)((__builtin_constant_p(((((ide_hwif_t *)((drive)->hwif ))->io_base+(7)))) && ((((ide_hwif_t *)((drive)-> hwif))->io_base+(7))) < 256) ? __inbc_p((((ide_hwif_t * )((drive)->hwif))->io_base+(7))) : __inb_p((((ide_hwif_t *)((drive)->hwif))->io_base+(7)))) & BUSY_STAT0x80) && jiffies < timeout + WAIT_WORSTCASE(30*100)) | |||
2819 | delay_50ms(); | |||
2820 | rc = try_to_identify(drive, cmd); | |||
2821 | } | |||
2822 | if (rc == 1) | |||
2823 | printk("%s: no response (status = 0x%02x)\n", drive->name, GET_STAT()(byte)((__builtin_constant_p(((((ide_hwif_t *)((drive)->hwif ))->io_base+(7)))) && ((((ide_hwif_t *)((drive)-> hwif))->io_base+(7))) < 256) ? __inbc_p((((ide_hwif_t * )((drive)->hwif))->io_base+(7))) : __inb_p((((ide_hwif_t *)((drive)->hwif))->io_base+(7))))); | |||
2824 | (void) GET_STAT()(byte)((__builtin_constant_p(((((ide_hwif_t *)((drive)->hwif ))->io_base+(7)))) && ((((ide_hwif_t *)((drive)-> hwif))->io_base+(7))) < 256) ? __inbc_p((((ide_hwif_t * )((drive)->hwif))->io_base+(7))) : __inb_p((((ide_hwif_t *)((drive)->hwif))->io_base+(7)))); /* ensure drive irq is clear */ | |||
2825 | } else { | |||
2826 | rc = 3; /* not present or maybe ATAPI */ | |||
2827 | } | |||
2828 | if (drive->select.b.unit != 0) { | |||
2829 | OUT_BYTE(0xa0,IDE_SELECT_REG)((__builtin_constant_p((((((ide_hwif_t *)((drive)->hwif))-> io_base+(6))))) && (((((ide_hwif_t *)((drive)->hwif ))->io_base+(6)))) < 256) ? __outbc_p(((0xa0)),(((((ide_hwif_t *)((drive)->hwif))->io_base+(6))))) : __outb_p(((0xa0) ),(((((ide_hwif_t *)((drive)->hwif))->io_base+(6)))))); /* exit with drive0 selected */ | |||
2830 | delay_50ms(); | |||
2831 | (void) GET_STAT()(byte)((__builtin_constant_p(((((ide_hwif_t *)((drive)->hwif ))->io_base+(7)))) && ((((ide_hwif_t *)((drive)-> hwif))->io_base+(7))) < 256) ? __inbc_p((((ide_hwif_t * )((drive)->hwif))->io_base+(7))) : __inb_p((((ide_hwif_t *)((drive)->hwif))->io_base+(7)))); /* ensure drive irq is clear */ | |||
2832 | } | |||
2833 | return rc; | |||
2834 | } | |||
2835 | ||||
2836 | static void enable_nest (ide_drive_t *drive) | |||
2837 | { | |||
2838 | unsigned long timeout; | |||
2839 | ||||
2840 | printk("%s: enabling %s -- ", HWIF(drive)((ide_hwif_t *)((drive)->hwif))->name, drive->id->model); | |||
2841 | SELECT_DRIVE(HWIF(drive), drive)((__builtin_constant_p(((((ide_hwif_t *)((drive)->hwif))-> io_base+(6)))) && ((((ide_hwif_t *)((drive)->hwif) )->io_base+(6))) < 256) ? __outbc_p((((drive)->select .all)),((((ide_hwif_t *)((drive)->hwif))->io_base+(6))) ) : __outb_p((((drive)->select.all)),((((ide_hwif_t *)((drive )->hwif))->io_base+(6)))));; | |||
2842 | delay_50ms(); | |||
2843 | OUT_BYTE(EXABYTE_ENABLE_NEST, IDE_COMMAND_REG)((__builtin_constant_p((((((ide_hwif_t *)((drive)->hwif))-> io_base+(7))))) && (((((ide_hwif_t *)((drive)->hwif ))->io_base+(7)))) < 256) ? __outbc_p(((0xf0)),(((((ide_hwif_t *)((drive)->hwif))->io_base+(7))))) : __outb_p(((0xf0) ),(((((ide_hwif_t *)((drive)->hwif))->io_base+(7)))))); | |||
2844 | timeout = jiffies + WAIT_WORSTCASE(30*100); | |||
2845 | do { | |||
2846 | if (jiffies > timeout) { | |||
2847 | printk("failed (timeout)\n"); | |||
2848 | return; | |||
2849 | } | |||
2850 | delay_50ms(); | |||
2851 | } while (GET_STAT()(byte)((__builtin_constant_p(((((ide_hwif_t *)((drive)->hwif ))->io_base+(7)))) && ((((ide_hwif_t *)((drive)-> hwif))->io_base+(7))) < 256) ? __inbc_p((((ide_hwif_t * )((drive)->hwif))->io_base+(7))) : __inb_p((((ide_hwif_t *)((drive)->hwif))->io_base+(7)))) & BUSY_STAT0x80); | |||
2852 | delay_50ms(); | |||
2853 | if (!OK_STAT(GET_STAT(), 0, BAD_STAT)((((byte)((__builtin_constant_p(((((ide_hwif_t *)((drive)-> hwif))->io_base+(7)))) && ((((ide_hwif_t *)((drive )->hwif))->io_base+(7))) < 256) ? __inbc_p((((ide_hwif_t *)((drive)->hwif))->io_base+(7))) : __inb_p((((ide_hwif_t *)((drive)->hwif))->io_base+(7)))))&((0)|(((0x80 | 0x01) | 0x08))))==(0))) | |||
2854 | printk("failed (status = 0x%02x)\n", GET_STAT()(byte)((__builtin_constant_p(((((ide_hwif_t *)((drive)->hwif ))->io_base+(7)))) && ((((ide_hwif_t *)((drive)-> hwif))->io_base+(7))) < 256) ? __inbc_p((((ide_hwif_t * )((drive)->hwif))->io_base+(7))) : __inb_p((((ide_hwif_t *)((drive)->hwif))->io_base+(7))))); | |||
2855 | else | |||
2856 | printk("success\n"); | |||
2857 | if (do_probe(drive, WIN_IDENTIFY0xEC) >= 2) { /* if !(success||timed-out) */ | |||
2858 | #ifdef CONFIG_BLK_DEV_IDEATAPI1 | |||
2859 | (void) do_probe(drive, WIN_PIDENTIFY0xA1); /* look for ATAPI device */ | |||
2860 | #endif /* CONFIG_BLK_DEV_IDEATAPI */ | |||
2861 | } | |||
2862 | } | |||
2863 | ||||
2864 | /* | |||
2865 | * probe_for_drive() tests for existence of a given drive using do_probe(). | |||
2866 | * | |||
2867 | * Returns: 0 no device was found | |||
2868 | * 1 device was found (note: drive->present might still be 0) | |||
2869 | */ | |||
2870 | static inlineinline __attribute__((always_inline)) byte probe_for_drive (ide_drive_t *drive) | |||
2871 | { | |||
2872 | if (drive->noprobe) /* skip probing? */ | |||
2873 | return drive->present; | |||
2874 | if (do_probe(drive, WIN_IDENTIFY0xEC) >= 2) { /* if !(success||timed-out) */ | |||
2875 | #ifdef CONFIG_BLK_DEV_IDEATAPI1 | |||
2876 | (void) do_probe(drive, WIN_PIDENTIFY0xA1); /* look for ATAPI device */ | |||
2877 | #endif /* CONFIG_BLK_DEV_IDEATAPI */ | |||
2878 | } | |||
2879 | if (drive->id && strstr((char *)drive->id->model, "E X A B Y T E N E S T")) | |||
2880 | enable_nest(drive); | |||
2881 | if (!drive->present) | |||
2882 | return 0; /* drive not found */ | |||
2883 | if (drive->id == NULL((void *) 0)) { /* identification failed? */ | |||
2884 | if (drive->media == ide_disk) { | |||
2885 | printk ("%s: non-IDE drive, CHS=%d/%d/%d\n", | |||
2886 | drive->name, drive->cyl, drive->head, drive->sect); | |||
2887 | } | |||
2888 | #ifdef CONFIG_BLK_DEV_IDECD1 | |||
2889 | else if (drive->media == ide_cdrom) { | |||
2890 | printk("%s: ATAPI cdrom (?)\n", drive->name); | |||
2891 | } | |||
2892 | #endif /* CONFIG_BLK_DEV_IDECD */ | |||
2893 | else { | |||
2894 | drive->present = 0; /* nuke it */ | |||
2895 | } | |||
2896 | } | |||
2897 | return 1; /* drive was found */ | |||
2898 | } | |||
2899 | ||||
2900 | /* | |||
2901 | * We query CMOS about hard disks : it could be that we have a SCSI/ESDI/etc | |||
2902 | * controller that is BIOS compatible with ST-506, and thus showing up in our | |||
2903 | * BIOS table, but not register compatible, and therefore not present in CMOS. | |||
2904 | * | |||
2905 | * Furthermore, we will assume that our ST-506 drives <if any> are the primary | |||
2906 | * drives in the system -- the ones reflected as drive 1 or 2. The first | |||
2907 | * drive is stored in the high nibble of CMOS byte 0x12, the second in the low | |||
2908 | * nibble. This will be either a 4 bit drive type or 0xf indicating use byte | |||
2909 | * 0x19 for an 8 bit type, drive 1, 0x1a for drive 2 in CMOS. A non-zero value | |||
2910 | * means we have an AT controller hard disk for that drive. | |||
2911 | * | |||
2912 | * Of course, there is no guarantee that either drive is actually on the | |||
2913 | * "primary" IDE interface, but we don't bother trying to sort that out here. | |||
2914 | * If a drive is not actually on the primary interface, then these parameters | |||
2915 | * will be ignored. This results in the user having to supply the logical | |||
2916 | * drive geometry as a boot parameter for each drive not on the primary i/f. | |||
2917 | * | |||
2918 | * The only "perfect" way to handle this would be to modify the setup.[cS] code | |||
2919 | * to do BIOS calls Int13h/Fn08h and Int13h/Fn48h to get all of the drive info | |||
2920 | * for us during initialization. I have the necessary docs -- any takers? -ml | |||
2921 | */ | |||
2922 | static void probe_cmos_for_drives (ide_hwif_t *hwif) | |||
2923 | { | |||
2924 | #ifdef __i386__1 | |||
2925 | extern struct drive_info_struct drive_info; | |||
2926 | byte cmos_disks, *BIOS = (byte *) &drive_info; | |||
2927 | int unit; | |||
2928 | ||||
2929 | #ifdef CONFIG_BLK_DEV_PROMISE | |||
2930 | if (hwif->is_promise2) | |||
2931 | return; | |||
2932 | #endif /* CONFIG_BLK_DEV_PROMISE */ | |||
2933 | outb_p(0x12,0x70)((__builtin_constant_p((0x70)) && (0x70) < 256) ? __outbc_p ((0x12),(0x70)) : __outb_p((0x12),(0x70))); /* specify CMOS address 0x12 */ | |||
2934 | cmos_disks = inb_p(0x71)((__builtin_constant_p((0x71)) && (0x71) < 256) ? __inbc_p (0x71) : __inb_p(0x71)); /* read the data from 0x12 */ | |||
2935 | /* Extract drive geometry from CMOS+BIOS if not already setup */ | |||
2936 | for (unit = 0; unit < MAX_DRIVES2; ++unit) { | |||
2937 | ide_drive_t *drive = &hwif->drives[unit]; | |||
2938 | if ((cmos_disks & (0xf0 >> (unit*4))) && !drive->present && !drive->nobios) { | |||
2939 | unsigned short cyl = *(unsigned short *)BIOS; | |||
2940 | unsigned char head = *(BIOS+2); | |||
2941 | unsigned char sect = *(BIOS+14); | |||
2942 | unsigned char ctl = *(BIOS+8); | |||
2943 | if (cyl > 0 && head > 0 && sect > 0 && sect < 64) { | |||
2944 | drive->cyl = drive->bios_cyl = cyl; | |||
2945 | drive->head = drive->bios_head = head; | |||
2946 | drive->sect = drive->bios_sect = sect; | |||
2947 | drive->ctl = ctl; | |||
2948 | drive->present = 1; | |||
2949 | printk("hd%d: got CHS=%d/%d/%d CTL=%x from BIOS\n", | |||
2950 | unit, cyl, head, sect, ctl); | |||
2951 | ||||
2952 | } else { | |||
2953 | printk("hd%d: CHS=%d/%d/%d CTL=%x from BIOS ignored\n", | |||
2954 | unit, cyl, head, sect, ctl); | |||
2955 | } | |||
2956 | } | |||
2957 | BIOS += 16; | |||
2958 | } | |||
2959 | #endif | |||
2960 | } | |||
2961 | ||||
2962 | /* | |||
2963 | * This routine only knows how to look for drive units 0 and 1 | |||
2964 | * on an interface, so any setting of MAX_DRIVES > 2 won't work here. | |||
2965 | */ | |||
2966 | static void probe_hwif (ide_hwif_t *hwif) | |||
2967 | { | |||
2968 | unsigned int unit; | |||
2969 | ||||
2970 | if (hwif->noprobe) | |||
2971 | return; | |||
2972 | if (hwif->io_base == HD_DATA0x1f0) | |||
2973 | probe_cmos_for_drives (hwif); | |||
2974 | #if CONFIG_BLK_DEV_PROMISE | |||
2975 | if (!hwif->is_promise2 && | |||
2976 | (check_region(hwif->io_base,8) || check_region(hwif->ctl_port,1))) { | |||
2977 | #else | |||
2978 | if (check_region(hwif->io_base,8) || check_region(hwif->ctl_port,1)) { | |||
2979 | #endif /* CONFIG_BLK_DEV_PROMISE */ | |||
2980 | int msgout = 0; | |||
2981 | for (unit = 0; unit < MAX_DRIVES2; ++unit) { | |||
2982 | ide_drive_t *drive = &hwif->drives[unit]; | |||
2983 | if (drive->present) { | |||
2984 | drive->present = 0; | |||
2985 | printk("%s: ERROR, PORTS ALREADY IN USE\n", drive->name); | |||
2986 | msgout = 1; | |||
2987 | } | |||
2988 | } | |||
2989 | if (!msgout) | |||
2990 | printk("%s: ports already in use, skipping probe\n", hwif->name); | |||
2991 | } else { | |||
2992 | unsigned long flags; | |||
2993 | save_flags(flags)__asm__ __volatile__("pushf ; pop %0" : "=r" (flags): :"memory" ); | |||
2994 | ||||
2995 | sti()__asm__ __volatile__ ("sti": : :"memory"); /* needed for jiffies and irq probing */ | |||
2996 | /* | |||
2997 | * Second drive should only exist if first drive was found, | |||
2998 | * but a lot of cdrom drives are configured as single slaves. | |||
2999 | */ | |||
3000 | for (unit = 0; unit < MAX_DRIVES2; ++unit) { | |||
3001 | ide_drive_t *drive = &hwif->drives[unit]; | |||
3002 | (void) probe_for_drive (drive); | |||
3003 | if (drive->present && drive->media == ide_disk) { | |||
3004 | if ((!drive->head || drive->head > 16) && !drive->select.b.lba) { | |||
3005 | printk("%s: INVALID GEOMETRY: %d PHYSICAL HEADS?\n", | |||
3006 | drive->name, drive->head); | |||
3007 | drive->present = 0; | |||
3008 | } | |||
3009 | } | |||
3010 | if (drive->present && !hwif->present) { | |||
3011 | hwif->present = 1; | |||
3012 | request_region(hwif->io_base, 8, hwif->name); | |||
3013 | request_region(hwif->ctl_port, 1, hwif->name); | |||
3014 | } | |||
3015 | } | |||
3016 | restore_flags(flags)__asm__ __volatile__("push %0 ; popf": :"g" (flags):"memory"); | |||
3017 | for (unit = 0; unit < MAX_DRIVES2; ++unit) { | |||
3018 | ide_drive_t *drive = &hwif->drives[unit]; | |||
3019 | if (drive->present && drive->media != ide_tape) { | |||
3020 | ide_tuneproc_t *tuneproc = HWIF(drive)((ide_hwif_t *)((drive)->hwif))->tuneproc; | |||
3021 | if (tuneproc != NULL((void *) 0) && drive->autotune == 1) | |||
3022 | tuneproc(drive, 255); /* auto-tune PIO mode */ | |||
3023 | } | |||
3024 | } | |||
3025 | } | |||
3026 | } | |||
3027 | ||||
3028 | /* | |||
3029 | * stridx() returns the offset of c within s, | |||
3030 | * or -1 if c is '\0' or not found within s. | |||
3031 | */ | |||
3032 | static int stridx (const char *s, char c) | |||
3033 | { | |||
3034 | char *i = strchr(s, c); | |||
3035 | return (i && c) ? i - s : -1; | |||
3036 | } | |||
3037 | ||||
3038 | /* | |||
3039 | * match_parm() does parsing for ide_setup(): | |||
3040 | * | |||
3041 | * 1. the first char of s must be '='. | |||
3042 | * 2. if the remainder matches one of the supplied keywords, | |||
3043 | * the index (1 based) of the keyword is negated and returned. | |||
3044 | * 3. if the remainder is a series of no more than max_vals numbers | |||
3045 | * separated by commas, the numbers are saved in vals[] and a | |||
3046 | * count of how many were saved is returned. Base10 is assumed, | |||
3047 | * and base16 is allowed when prefixed with "0x". | |||
3048 | * 4. otherwise, zero is returned. | |||
3049 | */ | |||
3050 | static int match_parm (char *s, const char *keywords[], int vals[], int max_vals) | |||
3051 | { | |||
3052 | static const char *decimal = "0123456789"; | |||
3053 | static const char *hex = "0123456789abcdef"; | |||
3054 | int i, n; | |||
3055 | ||||
3056 | if (*s++ == '=') { | |||
3057 | /* | |||
3058 | * Try matching against the supplied keywords, | |||
3059 | * and return -(index+1) if we match one | |||
3060 | */ | |||
3061 | if (keywords != NULL((void *) 0)) { | |||
3062 | for (i = 0; *keywords != NULL((void *) 0); ++i) { | |||
3063 | if (!strcmp(s, *keywords++)) | |||
3064 | return -(i+1); | |||
3065 | } | |||
3066 | } | |||
3067 | /* | |||
3068 | * Look for a series of no more than "max_vals" | |||
3069 | * numeric values separated by commas, in base10, | |||
3070 | * or base16 when prefixed with "0x". | |||
3071 | * Return a count of how many were found. | |||
3072 | */ | |||
3073 | for (n = 0; (i = stridx(decimal, *s)) >= 0;) { | |||
3074 | vals[n] = i; | |||
3075 | while ((i = stridx(decimal, *++s)) >= 0) | |||
3076 | vals[n] = (vals[n] * 10) + i; | |||
3077 | if (*s == 'x' && !vals[n]) { | |||
3078 | while ((i = stridx(hex, *++s)) >= 0) | |||
3079 | vals[n] = (vals[n] * 0x10) + i; | |||
3080 | } | |||
3081 | if (++n == max_vals) | |||
3082 | break; | |||
3083 | if (*s == ',') | |||
3084 | ++s; | |||
3085 | } | |||
3086 | if (!*s) | |||
3087 | return n; | |||
3088 | } | |||
3089 | return 0; /* zero = nothing matched */ | |||
3090 | } | |||
3091 | ||||
3092 | /* | |||
3093 | * ide_setup() gets called VERY EARLY during initialization, | |||
3094 | * to handle kernel "command line" strings beginning with "hdx=" | |||
3095 | * or "ide". Here is the complete set currently supported: | |||
3096 | * | |||
3097 | * "hdx=" is recognized for all "x" from "a" to "h", such as "hdc". | |||
3098 | * "idex=" is recognized for all "x" from "0" to "3", such as "ide1". | |||
3099 | * | |||
3100 | * "hdx=noprobe" : drive may be present, but do not probe for it | |||
3101 | * "hdx=none" : drive is NOT present, ignore cmos and do not probe | |||
3102 | * "hdx=nowerr" : ignore the WRERR_STAT bit on this drive | |||
3103 | * "hdx=cdrom" : drive is present, and is a cdrom drive | |||
3104 | * "hdx=cyl,head,sect" : disk drive is present, with specified geometry | |||
3105 | * "hdx=autotune" : driver will attempt to tune interface speed | |||
3106 | * to the fastest PIO mode supported, | |||
3107 | * if possible for this drive only. | |||
3108 | * Not fully supported by all chipset types, | |||
3109 | * and quite likely to cause trouble with | |||
3110 | * older/odd IDE drives. | |||
3111 | * | |||
3112 | * "idebus=xx" : inform IDE driver of VESA/PCI bus speed in Mhz, | |||
3113 | * where "xx" is between 20 and 66 inclusive, | |||
3114 | * used when tuning chipset PIO modes. | |||
3115 | * For PCI bus, 25 is correct for a P75 system, | |||
3116 | * 30 is correct for P90,P120,P180 systems, | |||
3117 | * and 33 is used for P100,P133,P166 systems. | |||
3118 | * If in doubt, use idebus=33 for PCI. | |||
3119 | * As for VLB, it is safest to not specify it. | |||
3120 | * | |||
3121 | * "idex=noprobe" : do not attempt to access/use this interface | |||
3122 | * "idex=base" : probe for an interface at the addr specified, | |||
3123 | * where "base" is usually 0x1f0 or 0x170 | |||
3124 | * and "ctl" is assumed to be "base"+0x206 | |||
3125 | * "idex=base,ctl" : specify both base and ctl | |||
3126 | * "idex=base,ctl,irq" : specify base, ctl, and irq number | |||
3127 | * "idex=autotune" : driver will attempt to tune interface speed | |||
3128 | * to the fastest PIO mode supported, | |||
3129 | * for all drives on this interface. | |||
3130 | * Not fully supported by all chipset types, | |||
3131 | * and quite likely to cause trouble with | |||
3132 | * older/odd IDE drives. | |||
3133 | * "idex=noautotune" : driver will NOT attempt to tune interface speed | |||
3134 | * This is the default for most chipsets, | |||
3135 | * except the cmd640. | |||
3136 | * "idex=serialize" : do not overlap operations on idex and ide(x^1) | |||
3137 | * | |||
3138 | * The following are valid ONLY on ide0, | |||
3139 | * and the defaults for the base,ctl ports must not be altered. | |||
3140 | * | |||
3141 | * "ide0=dtc2278" : probe/support DTC2278 interface | |||
3142 | * "ide0=ht6560b" : probe/support HT6560B interface | |||
3143 | * "ide0=cmd640_vlb" : *REQUIRED* for VLB cards with the CMD640 chip | |||
3144 | * (not for PCI -- automatically detected) | |||
3145 | * "ide0=qd6580" : probe/support qd6580 interface | |||
3146 | * "ide0=ali14xx" : probe/support ali14xx chipsets (ALI M1439, M1443, M1445) | |||
3147 | * "ide0=umc8672" : probe/support umc8672 chipsets | |||
3148 | */ | |||
3149 | void ide_setup (char *s) | |||
3150 | { | |||
3151 | int i, vals[3]; | |||
3152 | ide_hwif_t *hwif; | |||
3153 | ide_drive_t *drive; | |||
3154 | unsigned int hw, unit; | |||
3155 | const char max_drive = 'a' + ((MAX_HWIFS4 * MAX_DRIVES2) - 1); | |||
3156 | const char max_hwif = '0' + (MAX_HWIFS4 - 1); | |||
3157 | ||||
3158 | printk("ide_setup: %s", s); | |||
3159 | init_ide_data (); | |||
3160 | ||||
3161 | /* | |||
3162 | * Look for drive options: "hdx=" | |||
3163 | */ | |||
3164 | if (s[0] == 'h' && s[1] == 'd' && s[2] >= 'a' && s[2] <= max_drive) { | |||
3165 | const char *hd_words[] = {"none", "noprobe", "nowerr", "cdrom", | |||
3166 | "serialize", "autotune", "noautotune", | |||
3167 | "slow", "ide-scsi", NULL((void *) 0)}; | |||
3168 | unit = s[2] - 'a'; | |||
3169 | hw = unit / MAX_DRIVES2; | |||
3170 | unit = unit % MAX_DRIVES2; | |||
3171 | hwif = &ide_hwifs[hw]; | |||
3172 | drive = &hwif->drives[unit]; | |||
3173 | switch (match_parm(&s[3], hd_words, vals, 3)) { | |||
3174 | case -1: /* "none" */ | |||
3175 | drive->nobios = 1; /* drop into "noprobe" */ | |||
3176 | case -2: /* "noprobe" */ | |||
3177 | drive->noprobe = 1; | |||
3178 | goto done; | |||
3179 | case -3: /* "nowerr" */ | |||
3180 | drive->bad_wstat = BAD_R_STAT(0x80 | 0x01); | |||
3181 | hwif->noprobe = 0; | |||
3182 | goto done; | |||
3183 | case -4: /* "cdrom" */ | |||
3184 | drive->present = 1; | |||
3185 | drive->media = ide_cdrom; | |||
3186 | hwif->noprobe = 0; | |||
3187 | goto done; | |||
3188 | case -5: /* "serialize" */ | |||
3189 | printk(" -- USE \"ide%d=serialize\" INSTEAD", hw); | |||
3190 | goto do_serialize; | |||
3191 | case -6: /* "autotune" */ | |||
3192 | drive->autotune = 1; | |||
3193 | goto done; | |||
3194 | case -7: /* "noautotune" */ | |||
3195 | drive->autotune = 2; | |||
3196 | goto done; | |||
3197 | case -8: /* "slow" */ | |||
3198 | drive->slow = 1; | |||
3199 | goto done; | |||
3200 | case -9: /* "ide-scsi" */ | |||
3201 | drive->ide_scsi = 1; | |||
3202 | goto done; | |||
3203 | case 3: /* cyl,head,sect */ | |||
3204 | drive->media = ide_disk; | |||
3205 | drive->cyl = drive->bios_cyl = vals[0]; | |||
3206 | drive->head = drive->bios_head = vals[1]; | |||
3207 | drive->sect = drive->bios_sect = vals[2]; | |||
3208 | drive->present = 1; | |||
3209 | drive->forced_geom = 1; | |||
3210 | hwif->noprobe = 0; | |||
3211 | goto done; | |||
3212 | default: | |||
3213 | goto bad_option; | |||
3214 | } | |||
3215 | } | |||
3216 | ||||
3217 | if (s[0] != 'i' || s[1] != 'd' || s[2] != 'e') | |||
3218 | goto bad_option; | |||
3219 | /* | |||
3220 | * Look for bus speed option: "idebus=" | |||
3221 | */ | |||
3222 | if (s[3] == 'b' && s[4] == 'u' && s[5] == 's') { | |||
3223 | if (match_parm(&s[6], NULL((void *) 0), vals, 1) != 1) | |||
3224 | goto bad_option; | |||
3225 | if (vals[0] >= 20 && vals[0] <= 66) | |||
3226 | idebus_parameter = vals[0]; | |||
3227 | else | |||
3228 | printk(" -- BAD BUS SPEED! Expected value from 20 to 66"); | |||
3229 | goto done; | |||
3230 | } | |||
3231 | /* | |||
3232 | * Look for interface options: "idex=" | |||
3233 | */ | |||
3234 | if (s[3] >= '0' && s[3] <= max_hwif) { | |||
3235 | /* | |||
3236 | * Be VERY CAREFUL changing this: note hardcoded indexes below | |||
3237 | */ | |||
3238 | const char *ide_words[] = {"noprobe", "serialize", "autotune", "noautotune", | |||
3239 | "qd6580", "ht6560b", "cmd640_vlb", "dtc2278", "umc8672", "ali14xx", "dc4030", NULL((void *) 0)}; | |||
3240 | hw = s[3] - '0'; | |||
3241 | hwif = &ide_hwifs[hw]; | |||
3242 | i = match_parm(&s[4], ide_words, vals, 3); | |||
3243 | ||||
3244 | /* | |||
3245 | * Cryptic check to ensure chipset not already set for hwif: | |||
3246 | */ | |||
3247 | if (i > 0 || i <= -5) { | |||
3248 | if (hwif->chipset != ide_unknown) | |||
3249 | goto bad_option; | |||
3250 | if (i <= -5) { | |||
3251 | if (ide_hwifs[1].chipset != ide_unknown) | |||
3252 | goto bad_option; | |||
3253 | /* | |||
3254 | * Interface keywords work only for ide0: | |||
3255 | */ | |||
3256 | if (hw != 0) | |||
3257 | goto bad_hwif; | |||
3258 | } | |||
3259 | } | |||
3260 | ||||
3261 | switch (i) { | |||
3262 | #ifdef CONFIG_BLK_DEV_PROMISE | |||
3263 | case -11: /* "dc4030" */ | |||
3264 | { | |||
3265 | setup_dc4030(hwif); | |||
3266 | goto done; | |||
3267 | } | |||
3268 | #endif /* CONFIG_BLK_DEV_PROMISE */ | |||
3269 | #ifdef CONFIG_BLK_DEV_ALI14XX | |||
3270 | case -10: /* "ali14xx" */ | |||
3271 | { | |||
3272 | extern void init_ali14xx (void); | |||
3273 | init_ali14xx(); | |||
3274 | goto done; | |||
3275 | } | |||
3276 | #endif /* CONFIG_BLK_DEV_ALI14XX */ | |||
3277 | #ifdef CONFIG_BLK_DEV_UMC8672 | |||
3278 | case -9: /* "umc8672" */ | |||
3279 | { | |||
3280 | extern void init_umc8672 (void); | |||
3281 | init_umc8672(); | |||
3282 | goto done; | |||
3283 | } | |||
3284 | #endif /* CONFIG_BLK_DEV_UMC8672 */ | |||
3285 | #ifdef CONFIG_BLK_DEV_DTC2278 | |||
3286 | case -8: /* "dtc2278" */ | |||
3287 | { | |||
3288 | extern void init_dtc2278 (void); | |||
3289 | init_dtc2278(); | |||
3290 | goto done; | |||
3291 | } | |||
3292 | #endif /* CONFIG_BLK_DEV_DTC2278 */ | |||
3293 | #ifdef CONFIG_BLK_DEV_CMD640 | |||
3294 | case -7: /* "cmd640_vlb" */ | |||
3295 | { | |||
3296 | extern int cmd640_vlb; /* flag for cmd640.c */ | |||
3297 | cmd640_vlb = 1; | |||
3298 | goto done; | |||
3299 | } | |||
3300 | #endif /* CONFIG_BLK_DEV_CMD640 */ | |||
3301 | #ifdef CONFIG_BLK_DEV_HT6560B | |||
3302 | case -6: /* "ht6560b" */ | |||
3303 | { | |||
3304 | extern void init_ht6560b (void); | |||
3305 | init_ht6560b(); | |||
3306 | goto done; | |||
3307 | } | |||
3308 | #endif /* CONFIG_BLK_DEV_HT6560B */ | |||
3309 | #if CONFIG_BLK_DEV_QD6580 | |||
3310 | case -5: /* "qd6580" (has secondary i/f) */ | |||
3311 | { | |||
3312 | extern void init_qd6580 (void); | |||
3313 | init_qd6580(); | |||
3314 | goto done; | |||
3315 | } | |||
3316 | #endif /* CONFIG_BLK_DEV_QD6580 */ | |||
3317 | case -4: /* "noautotune" */ | |||
3318 | hwif->drives[0].autotune = 2; | |||
3319 | hwif->drives[1].autotune = 2; | |||
3320 | goto done; | |||
3321 | case -3: /* "autotune" */ | |||
3322 | hwif->drives[0].autotune = 1; | |||
3323 | hwif->drives[1].autotune = 1; | |||
3324 | goto done; | |||
3325 | case -2: /* "serialize" */ | |||
3326 | do_serialize: | |||
3327 | ide_hwifs[hw].serialized = 1; /* serialize */ | |||
3328 | ide_hwifs[hw^1].serialized = 1; /* with mate */ | |||
3329 | goto done; | |||
3330 | ||||
3331 | case -1: /* "noprobe" */ | |||
3332 | hwif->noprobe = 1; | |||
3333 | goto done; | |||
3334 | ||||
3335 | case 1: /* base */ | |||
3336 | vals[1] = vals[0] + 0x206; /* default ctl */ | |||
3337 | case 2: /* base,ctl */ | |||
3338 | vals[2] = 0; /* default irq = probe for it */ | |||
3339 | case 3: /* base,ctl,irq */ | |||
3340 | hwif->io_base = vals[0]; | |||
3341 | hwif->ctl_port = vals[1]; | |||
3342 | hwif->irq = vals[2]; | |||
3343 | hwif->noprobe = 0; | |||
3344 | hwif->chipset = ide_generic; | |||
3345 | goto done; | |||
3346 | ||||
3347 | case 0: goto bad_option; | |||
3348 | default: | |||
3349 | printk(" -- SUPPORT NOT CONFIGURED IN THIS KERNEL\n"); | |||
3350 | return; | |||
3351 | } | |||
3352 | } | |||
3353 | bad_option: | |||
3354 | printk(" -- BAD OPTION\n"); | |||
3355 | return; | |||
3356 | bad_hwif: | |||
3357 | printk("-- NOT SUPPORTED ON ide%d", hw); | |||
3358 | done: | |||
3359 | printk("\n"); | |||
3360 | } | |||
3361 | ||||
3362 | /* | |||
3363 | * This routine is called from the partition-table code in genhd.c | |||
3364 | * to "convert" a drive to a logical geometry with fewer than 1024 cyls. | |||
3365 | * | |||
3366 | * The second parameter, "xparm", determines exactly how the translation | |||
3367 | * will be handled: | |||
3368 | * 0 = convert to CHS with fewer than 1024 cyls | |||
3369 | * using the same method as Ontrack DiskManager. | |||
3370 | * 1 = same as "0", plus offset everything by 63 sectors. | |||
3371 | * -1 = similar to "0", plus redirect sector 0 to sector 1. | |||
3372 | * >1 = convert to a CHS geometry with "xparm" heads. | |||
3373 | * | |||
3374 | * Returns 0 if the translation was not possible, if the device was not | |||
3375 | * an IDE disk drive, or if a geometry was "forced" on the commandline. | |||
3376 | * Returns 1 if the geometry translation was successful. | |||
3377 | */ | |||
3378 | ||||
3379 | int ide_xlate_1024 (kdev_t i_rdev, int xparm, const char *msg) | |||
3380 | { | |||
3381 | ide_drive_t *drive; | |||
3382 | static const byte head_vals[] = {4, 8, 16, 32, 64, 128, 255, 0}; | |||
3383 | const byte *heads = head_vals; | |||
3384 | unsigned long tracks; | |||
3385 | ||||
3386 | drive = get_info_ptr(i_rdev); | |||
3387 | if (!drive) | |||
3388 | return 0; | |||
3389 | ||||
3390 | if (drive->forced_geom) | |||
3391 | return 0; | |||
3392 | ||||
3393 | if (xparm > 1 && xparm <= drive->bios_head && drive->bios_sect == 63) | |||
3394 | return 0; /* we already have a translation */ | |||
3395 | ||||
3396 | printk("%s ", msg); | |||
3397 | ||||
3398 | if (xparm < 0 && (drive->bios_cyl * drive->bios_head * drive->bios_sect) < (1024 * 16 * 63)) { | |||
3399 | return 0; /* small disk: no translation needed */ | |||
3400 | } | |||
3401 | ||||
3402 | if (drive->id) { | |||
3403 | drive->cyl = drive->id->cyls; | |||
3404 | drive->head = drive->id->heads; | |||
3405 | drive->sect = drive->id->sectors; | |||
3406 | } | |||
3407 | drive->bios_cyl = drive->cyl; | |||
3408 | drive->bios_head = drive->head; | |||
3409 | drive->bios_sect = drive->sect; | |||
3410 | drive->special.b.set_geometry = 1; | |||
3411 | ||||
3412 | tracks = drive->bios_cyl * drive->bios_head * drive->bios_sect / 63; | |||
3413 | drive->bios_sect = 63; | |||
3414 | if (xparm > 1) { | |||
3415 | drive->bios_head = xparm; | |||
3416 | drive->bios_cyl = tracks / drive->bios_head; | |||
3417 | } else { | |||
3418 | while (drive->bios_cyl >= 1024) { | |||
3419 | drive->bios_head = *heads; | |||
3420 | drive->bios_cyl = tracks / drive->bios_head; | |||
3421 | if (0 == *++heads) | |||
3422 | break; | |||
3423 | } | |||
3424 | #if FAKE_FDISK_FOR_EZDRIVE1 | |||
3425 | if (xparm == -1) { | |||
3426 | drive->remap_0_to_1 = 1; | |||
3427 | msg = "0->1"; | |||
3428 | } else | |||
3429 | #endif /* FAKE_FDISK_FOR_EZDRIVE */ | |||
3430 | if (xparm == 1) { | |||
3431 | drive->sect0 = 63; | |||
3432 | drive->bios_cyl = (tracks - 1) / drive->bios_head; | |||
3433 | msg = "+63"; | |||
3434 | } | |||
3435 | printk("[remap %s] ", msg); | |||
3436 | } | |||
3437 | drive->part[0].nr_sects = current_capacity(drive); | |||
3438 | printk("[%d/%d/%d]", drive->bios_cyl, drive->bios_head, drive->bios_sect); | |||
3439 | return 1; | |||
3440 | } | |||
3441 | ||||
3442 | #if MAX_HWIFS4 > 1 | |||
3443 | /* | |||
3444 | * save_match() is used to simplify logic in init_irq() below. | |||
3445 | * | |||
3446 | * A loophole here is that we may not know about a particular | |||
3447 | * hwif's irq until after that hwif is actually probed/initialized.. | |||
3448 | * This could be a problem for the case where an hwif is on a | |||
3449 | * dual interface that requires serialization (eg. cmd640) and another | |||
3450 | * hwif using one of the same irqs is initialized beforehand. | |||
3451 | * | |||
3452 | * This routine detects and reports such situations, but does not fix them. | |||
3453 | */ | |||
3454 | static void save_match (ide_hwif_t *hwif, ide_hwif_t *new, ide_hwif_t **match) | |||
3455 | { | |||
3456 | ide_hwif_t *m = *match; | |||
3457 | ||||
3458 | if (m && m->hwgroup && m->hwgroup != new->hwgroup) { | |||
3459 | if (!new->hwgroup) | |||
3460 | return; | |||
3461 | printk("%s: potential irq problem with %s and %s\n", hwif->name, new->name, m->name); | |||
3462 | } | |||
3463 | if (!m || m->irq != hwif->irq) /* don't undo a prior perfect match */ | |||
3464 | *match = new; | |||
3465 | } | |||
3466 | #endif /* MAX_HWIFS > 1 */ | |||
3467 | ||||
3468 | /* | |||
3469 | * This routine sets up the irq for an ide interface, and creates a new | |||
3470 | * hwgroup for the irq/hwif if none was previously assigned. | |||
3471 | * | |||
3472 | * Much of the code is for correctly detecting/handling irq sharing | |||
3473 | * and irq serialization situations. This is somewhat complex because | |||
3474 | * it handles static as well as dynamic (PCMCIA) IDE interfaces. | |||
3475 | * | |||
3476 | * The SA_INTERRUPT in sa_flags means ide_intr() is always entered with | |||
3477 | * interrupts completely disabled. This can be bad for interrupt latency, | |||
3478 | * but anything else has led to problems on some machines. We re-enable | |||
3479 | * interrupts as much as we can safely do in most places. | |||
3480 | */ | |||
3481 | static int init_irq (ide_hwif_t *hwif) | |||
3482 | { | |||
3483 | unsigned long flags; | |||
3484 | #if MAX_HWIFS4 > 1 | |||
3485 | unsigned int index; | |||
3486 | #endif /* MAX_HWIFS > 1 */ | |||
3487 | ide_hwgroup_t *hwgroup; | |||
3488 | ide_hwif_t *match = NULL((void *) 0); | |||
3489 | ||||
3490 | save_flags(flags)__asm__ __volatile__("pushf ; pop %0" : "=r" (flags): :"memory" ); | |||
3491 | cli()__asm__ __volatile__ ("cli": : :"memory"); | |||
3492 | ||||
3493 | hwif->hwgroup = NULL((void *) 0); | |||
3494 | #if MAX_HWIFS4 > 1 | |||
3495 | /* | |||
3496 | * Group up with any other hwifs that share our irq(s). | |||
3497 | */ | |||
3498 | for (index = 0; index < MAX_HWIFS4; index++) { | |||
3499 | ide_hwif_t *h = &ide_hwifs[index]; | |||
3500 | if (h->hwgroup) { /* scan only initialized hwif's */ | |||
3501 | if (hwif->irq == h->irq) { | |||
3502 | hwif->sharing_irq = h->sharing_irq = 1; | |||
3503 | save_match(hwif, h, &match); | |||
3504 | } | |||
3505 | if (hwif->serialized) { | |||
3506 | ide_hwif_t *mate = &ide_hwifs[hwif->index^1]; | |||
3507 | if (index == mate->index || h->irq == mate->irq) | |||
3508 | save_match(hwif, h, &match); | |||
3509 | } | |||
3510 | if (h->serialized) { | |||
3511 | ide_hwif_t *mate = &ide_hwifs[h->index^1]; | |||
3512 | if (hwif->irq == mate->irq) | |||
3513 | save_match(hwif, h, &match); | |||
3514 | } | |||
3515 | } | |||
3516 | } | |||
3517 | #endif /* MAX_HWIFS > 1 */ | |||
3518 | /* | |||
3519 | * If we are still without a hwgroup, then form a new one | |||
3520 | */ | |||
3521 | if (match) { | |||
3522 | hwgroup = match->hwgroup; | |||
3523 | } else { | |||
3524 | hwgroup = kmalloclinux_kmalloc(sizeof(ide_hwgroup_t), GFP_KERNEL0x03); | |||
3525 | hwgroup->hwif = hwgroup->next_hwif = hwif->next = hwif; | |||
3526 | hwgroup->rq = NULL((void *) 0); | |||
3527 | hwgroup->handler = NULL((void *) 0); | |||
3528 | if (hwif->drives[0].present) | |||
3529 | hwgroup->drive = &hwif->drives[0]; | |||
3530 | else | |||
3531 | hwgroup->drive = &hwif->drives[1]; | |||
3532 | hwgroup->poll_timeout = 0; | |||
3533 | hwgroup->active = 0; | |||
3534 | init_timer(&hwgroup->timer); | |||
3535 | hwgroup->timer.function = &timer_expiry; | |||
3536 | hwgroup->timer.data = (unsigned long) hwgroup; | |||
3537 | } | |||
3538 | ||||
3539 | /* | |||
3540 | * Allocate the irq, if not already obtained for another hwif | |||
3541 | */ | |||
3542 | if (!match || match->irq != hwif->irq) { | |||
3543 | if (request_irq(hwif->irq, ide_intr, SA_INTERRUPT0x20000000, hwif->name, hwgroup)) { | |||
3544 | if (!match) | |||
3545 | kfreelinux_kfree(hwgroup); | |||
3546 | restore_flags(flags)__asm__ __volatile__("push %0 ; popf": :"g" (flags):"memory"); | |||
3547 | return 1; | |||
3548 | } | |||
3549 | } | |||
3550 | ||||
3551 | /* | |||
3552 | * Everything is okay, so link us into the hwgroup | |||
3553 | */ | |||
3554 | hwif->hwgroup = hwgroup; | |||
3555 | hwif->next = hwgroup->hwif->next; | |||
3556 | hwgroup->hwif->next = hwif; | |||
3557 | ||||
3558 | restore_flags(flags)__asm__ __volatile__("push %0 ; popf": :"g" (flags):"memory"); /* safe now that hwif->hwgroup is set up */ | |||
3559 | ||||
3560 | printk("%s at 0x%03x-0x%03x,0x%03x on irq %d", hwif->name, | |||
3561 | hwif->io_base, hwif->io_base+7, hwif->ctl_port, hwif->irq); | |||
3562 | if (match) | |||
3563 | printk(" (%sed with %s)", hwif->sharing_irq ? "shar" : "serializ", match->name); | |||
3564 | printk("\n"); | |||
3565 | return 0; | |||
3566 | } | |||
3567 | ||||
3568 | static struct file_operations ide_fops = { | |||
3569 | NULL((void *) 0), /* lseek - default */ | |||
3570 | block_read, /* read - general block-dev read */ | |||
3571 | block_write, /* write - general block-dev write */ | |||
3572 | NULL((void *) 0), /* readdir - bad */ | |||
3573 | NULL((void *) 0), /* select */ | |||
3574 | ide_ioctl, /* ioctl */ | |||
3575 | NULL((void *) 0), /* mmap */ | |||
3576 | ide_open, /* open */ | |||
3577 | ide_release, /* release */ | |||
3578 | block_fsync /* fsync */ | |||
3579 | ,NULL((void *) 0), /* fasync */ | |||
3580 | ide_check_media_change, /* check_media_change */ | |||
3581 | revalidate_disk /* revalidate */ | |||
3582 | }; | |||
3583 | ||||
3584 | #ifdef CONFIG_PCI1 | |||
3585 | #if defined(CONFIG_BLK_DEV_RZ10001) || defined(CONFIG_BLK_DEV_TRITON1) | |||
3586 | ||||
3587 | typedef void (ide_pci_init_proc_t)(byte, byte); | |||
3588 | ||||
3589 | /* | |||
3590 | * ide_probe_pci() scans PCI for a specific vendor/device function, | |||
3591 | * and invokes the supplied init routine for each instance detected. | |||
3592 | */ | |||
3593 | static void ide_probe_pci (unsigned short vendor, unsigned short device, ide_pci_init_proc_t *init, int func_adj) | |||
3594 | { | |||
3595 | unsigned long flags; | |||
3596 | unsigned index; | |||
3597 | byte fn, bus; | |||
3598 | ||||
3599 | save_flags(flags)__asm__ __volatile__("pushf ; pop %0" : "=r" (flags): :"memory" ); | |||
3600 | cli()__asm__ __volatile__ ("cli": : :"memory"); | |||
3601 | for (index = 0; !pcibios_find_device (vendor, device, index, &bus, &fn); ++index) { | |||
3602 | init (bus, fn + func_adj); | |||
3603 | } | |||
3604 | restore_flags(flags)__asm__ __volatile__("push %0 ; popf": :"g" (flags):"memory"); | |||
3605 | } | |||
3606 | ||||
3607 | #endif /* defined(CONFIG_BLK_DEV_RZ1000) || defined(CONFIG_BLK_DEV_TRITON) */ | |||
3608 | ||||
3609 | static void ide_probe_promise_20246(void) | |||
3610 | { | |||
3611 | byte fn, bus; | |||
3612 | unsigned short io[6], count = 0; | |||
3613 | unsigned int reg, tmp, i; | |||
3614 | ide_hwif_t *hwif; | |||
3615 | ||||
3616 | memset(io, 0, 6 * sizeof(unsigned short))(__builtin_constant_p(0) ? (__builtin_constant_p((6 * sizeof( unsigned short))) ? __constant_c_and_count_memset(((io)),((0x01010101UL *(unsigned char)(0))),((6 * sizeof(unsigned short)))) : __constant_c_memset (((io)),((0x01010101UL*(unsigned char)(0))),((6 * sizeof(unsigned short))))) : (__builtin_constant_p((6 * sizeof(unsigned short ))) ? __memset_generic((((io))),(((0))),(((6 * sizeof(unsigned short))))) : __memset_generic(((io)),((0)),((6 * sizeof(unsigned short)))))); | |||
3617 | if (pcibios_find_device(PCI_VENDOR_ID_PROMISE0x105a, PCI_DEVICE_ID_PROMISE_202460x4d33, 0, &bus, &fn)) | |||
3618 | return; | |||
3619 | printk("ide: Promise Technology IDE Ultra-DMA 33 on PCI bus %d function %d\n", bus, fn); | |||
3620 | for (reg = PCI_BASE_ADDRESS_00x10; reg <= PCI_BASE_ADDRESS_50x24; reg += 4) { | |||
3621 | pcibios_read_config_dword(bus, fn, reg, &tmp); | |||
3622 | if (tmp & PCI_BASE_ADDRESS_SPACE_IO0x01) | |||
3623 | io[count++] = tmp & PCI_BASE_ADDRESS_IO_MASK(~0x03); | |||
3624 | } | |||
3625 | for (i = 2; i < 4; i++) { | |||
3626 | hwif = ide_hwifs + i; | |||
3627 | if (hwif->chipset == ide_generic) { | |||
3628 | printk("ide%d: overridden with command line parameter\n", i); | |||
3629 | return; | |||
3630 | } | |||
3631 | tmp = (i - 2) * 2; | |||
3632 | if (!io[tmp] || !io[tmp + 1]) { | |||
3633 | printk("ide%d: invalid port address %x, %x -- aborting\n", i, io[tmp], io[tmp + 1]); | |||
3634 | return; | |||
3635 | } | |||
3636 | hwif->io_base = io[tmp]; | |||
3637 | hwif->ctl_port = io[tmp + 1] + 2; | |||
3638 | hwif->noprobe = 0; | |||
3639 | } | |||
3640 | } | |||
3641 | ||||
3642 | #endif /* CONFIG_PCI */ | |||
3643 | ||||
3644 | /* | |||
3645 | * ide_init_pci() finds/initializes "known" PCI IDE interfaces | |||
3646 | * | |||
3647 | * This routine should ideally be using pcibios_find_class() to find | |||
3648 | * all IDE interfaces, but that function causes some systems to "go weird". | |||
3649 | */ | |||
3650 | static void probe_for_hwifs (void) | |||
3651 | { | |||
3652 | #ifdef CONFIG_PCI1 | |||
3653 | /* | |||
3654 | * Find/initialize PCI IDE interfaces | |||
3655 | */ | |||
3656 | if (pcibios_present()) { | |||
3657 | #ifdef CONFIG_BLK_DEV_RZ10001 | |||
3658 | ide_pci_init_proc_t init_rz1000; | |||
3659 | ide_probe_pci (PCI_VENDOR_ID_PCTECH0x1042, PCI_DEVICE_ID_PCTECH_RZ10000x1000, &init_rz1000, 0); | |||
3660 | ide_probe_pci (PCI_VENDOR_ID_PCTECH0x1042, PCI_DEVICE_ID_PCTECH_RZ10010x1001, &init_rz1000, 0); | |||
3661 | #endif /* CONFIG_BLK_DEV_RZ1000 */ | |||
3662 | #ifdef CONFIG_BLK_DEV_TRITON1 | |||
3663 | /* | |||
3664 | * Apparently the BIOS32 services on Intel motherboards are | |||
3665 | * buggy and won't find the PCI_DEVICE_ID_INTEL_82371_1 for us. | |||
3666 | * So instead, we search for PCI_DEVICE_ID_INTEL_82371_0, | |||
3667 | * and then add 1. | |||
3668 | */ | |||
3669 | ide_probe_pci (PCI_VENDOR_ID_INTEL0x8086, PCI_DEVICE_ID_INTEL_82371_00x122e, &ide_init_triton, 1); | |||
3670 | ide_probe_pci (PCI_VENDOR_ID_INTEL0x8086, PCI_DEVICE_ID_INTEL_82371SB_10x7010, &ide_init_triton, 0); | |||
3671 | ide_probe_pci (PCI_VENDOR_ID_INTEL0x8086, PCI_DEVICE_ID_INTEL_82371AB0x7111, &ide_init_triton, 0); | |||
3672 | ide_probe_pci (PCI_VENDOR_ID_SI0x1039, PCI_DEVICE_ID_SI_55130x5513, &ide_init_triton, 0); | |||
3673 | ide_probe_pci (PCI_VENDOR_ID_VIA0x1106, PCI_DEVICE_ID_VIA_82C586_10x0571, &ide_init_triton, 0); | |||
3674 | ide_probe_pci (PCI_VENDOR_ID_AL0x10b9, PCI_DEVICE_ID_AL_M52290x5229, &ide_init_triton, 0); | |||
3675 | #endif /* CONFIG_BLK_DEV_TRITON */ | |||
3676 | ide_probe_promise_20246(); | |||
3677 | } | |||
3678 | #endif /* CONFIG_PCI */ | |||
3679 | #ifdef CONFIG_BLK_DEV_CMD640 | |||
3680 | { | |||
3681 | extern void ide_probe_for_cmd640x (void); | |||
3682 | ide_probe_for_cmd640x(); | |||
3683 | } | |||
3684 | #endif | |||
3685 | #ifdef CONFIG_BLK_DEV_PROMISE | |||
3686 | init_dc4030(); | |||
3687 | #endif | |||
3688 | ahci_probe_pci(); | |||
3689 | } | |||
3690 | ||||
3691 | static int hwif_init (int h) | |||
3692 | { | |||
3693 | ide_hwif_t *hwif = &ide_hwifs[h]; | |||
3694 | void (*rfn)(void); | |||
3695 | ||||
3696 | if (!hwif->present) | |||
3697 | return 0; | |||
3698 | if (!hwif->irq) { | |||
3699 | if (!(hwif->irq = default_irqs[h])) { | |||
3700 | printk("%s: DISABLED, NO IRQ\n", hwif->name); | |||
3701 | return (hwif->present = 0); | |||
3702 | } | |||
3703 | } | |||
3704 | #ifdef CONFIG_BLK_DEV_HD | |||
3705 | if (hwif->irq == HD_IRQ14 && hwif->io_base != HD_DATA0x1f0) { | |||
3706 | printk("%s: CANNOT SHARE IRQ WITH OLD HARDDISK DRIVER (hd.c)\n", hwif->name); | |||
3707 | return (hwif->present = 0); | |||
3708 | } | |||
3709 | #endif /* CONFIG_BLK_DEV_HD */ | |||
3710 | ||||
3711 | hwif->present = 0; /* we set it back to 1 if all is ok below */ | |||
3712 | switch (hwif->major) { | |||
3713 | case IDE0_MAJOR3: rfn = &do_ide0_request; break; | |||
3714 | #if MAX_HWIFS4 > 1 | |||
3715 | case IDE1_MAJOR22: rfn = &do_ide1_request; break; | |||
3716 | #endif | |||
3717 | #if MAX_HWIFS4 > 2 | |||
3718 | case IDE2_MAJOR33: rfn = &do_ide2_request; break; | |||
3719 | #endif | |||
3720 | #if MAX_HWIFS4 > 3 | |||
3721 | case IDE3_MAJOR34: rfn = &do_ide3_request; break; | |||
3722 | #endif | |||
3723 | default: | |||
3724 | printk("%s: request_fn NOT DEFINED\n", hwif->name); | |||
3725 | return (hwif->present = 0); | |||
3726 | } | |||
3727 | if (register_blkdev (hwif->major, hwif->name, &ide_fops)) { | |||
3728 | printk("%s: UNABLE TO GET MAJOR NUMBER %d\n", hwif->name, hwif->major); | |||
3729 | } else if (init_irq (hwif)) { | |||
3730 | printk("%s: UNABLE TO GET IRQ %d\n", hwif->name, hwif->irq); | |||
3731 | (void) unregister_blkdev (hwif->major, hwif->name); | |||
3732 | } else { | |||
3733 | init_gendisk(hwif); | |||
3734 | blk_dev[hwif->major].request_fn = rfn; | |||
3735 | read_ahead[hwif->major] = 8; /* (4kB) */ | |||
3736 | hwif->present = 1; /* success */ | |||
3737 | } | |||
3738 | return hwif->present; | |||
3739 | } | |||
3740 | ||||
3741 | /* | |||
3742 | * This is gets invoked once during initialization, to set *everything* up | |||
3743 | */ | |||
3744 | int ide_init (void) | |||
3745 | { | |||
3746 | int index; | |||
3747 | ||||
3748 | init_ide_data (); | |||
3749 | /* | |||
3750 | * Probe for special "known" interface chipsets | |||
3751 | */ | |||
3752 | probe_for_hwifs (); | |||
3753 | ||||
3754 | /* | |||
3755 | * Probe for drives in the usual way.. CMOS/BIOS, then poke at ports | |||
3756 | */ | |||
3757 | for (index = 0; index < MAX_HWIFS4; ++index) | |||
3758 | probe_hwif (&ide_hwifs[index]); | |||
3759 | for (index = 0; index < MAX_HWIFS4; ++index) | |||
3760 | hwif_init (index); | |||
3761 | ||||
3762 | #ifdef CONFIG_BLK_DEV_IDETAPE | |||
3763 | idetape_register_chrdev(); /* Register character device interface to the ide tape */ | |||
3764 | #endif /* CONFIG_BLK_DEV_IDETAPE */ | |||
3765 | ||||
3766 | return 0; | |||
3767 | } | |||
3768 | ||||
3769 | #ifdef CONFIG_BLK_DEV_IDE_PCMCIA | |||
3770 | int ide_register(int io_base, int ctl_port, int irq) | |||
3771 | { | |||
3772 | int index, i, rc = -1; | |||
3773 | ide_hwif_t *hwif; | |||
3774 | ide_drive_t *drive; | |||
3775 | unsigned long flags; | |||
3776 | ||||
3777 | save_flags(flags)__asm__ __volatile__("pushf ; pop %0" : "=r" (flags): :"memory" ); | |||
3778 | cli()__asm__ __volatile__ ("cli": : :"memory"); | |||
3779 | for (index = 0; index < MAX_HWIFS4; ++index) { | |||
3780 | hwif = &ide_hwifs[index]; | |||
3781 | if (hwif->present) { | |||
3782 | if (hwif->io_base == io_base || hwif->ctl_port == ctl_port) | |||
3783 | break; /* this ide port already exists */ | |||
3784 | } else { | |||
3785 | hwif->io_base = io_base; | |||
3786 | hwif->ctl_port = ctl_port; | |||
3787 | hwif->irq = irq; | |||
3788 | hwif->noprobe = 0; | |||
3789 | probe_hwif(hwif); | |||
3790 | if (!hwif_init(index)) | |||
3791 | break; | |||
3792 | for (i = 0; i < hwif->gd->nr_real; i++) { | |||
3793 | drive = &hwif->drives[i]; | |||
3794 | revalidate_disk(MKDEV(hwif->major, i<<PARTN_BITS)(((hwif->major) << 8) | (i<<6))); | |||
3795 | #ifdef CONFIG_BLK_DEV_IDECD1 | |||
3796 | if (drive->present && drive->media == ide_cdrom) | |||
3797 | ide_cdrom_setup(drive); | |||
3798 | #endif /* CONFIG_BLK_DEV_IDECD */ | |||
3799 | } | |||
3800 | rc = index; | |||
3801 | break; | |||
3802 | } | |||
3803 | } | |||
3804 | restore_flags(flags)__asm__ __volatile__("push %0 ; popf": :"g" (flags):"memory"); | |||
3805 | return rc; | |||
3806 | } | |||
3807 | ||||
3808 | void ide_unregister (unsigned int index) | |||
3809 | { | |||
3810 | struct gendisk *gd, **gdp; | |||
3811 | ide_hwif_t *hwif, *g; | |||
3812 | ide_hwgroup_t *hwgroup; | |||
3813 | int irq_count = 0; | |||
3814 | unsigned long flags; | |||
3815 | ||||
3816 | if (index >= MAX_HWIFS4) | |||
3817 | return; | |||
3818 | save_flags(flags)__asm__ __volatile__("pushf ; pop %0" : "=r" (flags): :"memory" ); | |||
3819 | cli()__asm__ __volatile__ ("cli": : :"memory"); | |||
3820 | hwif = &ide_hwifs[index]; | |||
3821 | if (!hwif->present || hwif->drives[0].busy || hwif->drives[1].busy) { | |||
3822 | restore_flags(flags)__asm__ __volatile__("push %0 ; popf": :"g" (flags):"memory"); | |||
3823 | return; | |||
3824 | } | |||
3825 | hwif->present = 0; | |||
3826 | hwgroup = hwif->hwgroup; | |||
3827 | ||||
3828 | /* | |||
3829 | * free the irq if we were the only hwif using it | |||
3830 | */ | |||
3831 | g = hwgroup->hwif; | |||
3832 | do { | |||
3833 | if (g->irq == hwif->irq) | |||
3834 | ++irq_count; | |||
3835 | g = g->next; | |||
3836 | } while (g != hwgroup->hwif); | |||
3837 | if (irq_count == 1) | |||
3838 | free_irq(hwif->irq, hwgroup); | |||
3839 | ||||
3840 | /* | |||
3841 | * Note that we only release the standard ports, | |||
3842 | * and do not even try to handle any extra ports | |||
3843 | * allocated for weird IDE interface chipsets. | |||
3844 | */ | |||
3845 | release_region(hwif->io_base, 8); | |||
3846 | release_region(hwif->ctl_port, 1); | |||
3847 | ||||
3848 | /* | |||
3849 | * Remove us from the hwgroup, and free | |||
3850 | * the hwgroup if we were the only member | |||
3851 | */ | |||
3852 | while (hwgroup->hwif->next != hwif) | |||
3853 | hwgroup->hwif = hwgroup->hwif->next; | |||
3854 | hwgroup->hwif->next = hwif->next; | |||
3855 | if (hwgroup->hwif == hwif) | |||
3856 | hwgroup->hwif = hwif->next; | |||
3857 | if (hwgroup->next_hwif == hwif) | |||
3858 | hwgroup->next_hwif = hwif->next; | |||
3859 | if (hwgroup->hwif == hwif) | |||
3860 | kfreelinux_kfree(hwgroup); | |||
3861 | ||||
3862 | /* | |||
3863 | * Remove us from the kernel's knowledge | |||
3864 | */ | |||
3865 | unregister_blkdev(hwif->major, hwif->name); | |||
3866 | kfreelinux_kfree(blksize_size[hwif->major]); | |||
3867 | blk_dev[hwif->major].request_fn = NULL((void *) 0); | |||
3868 | blksize_size[hwif->major] = NULL((void *) 0); | |||
3869 | for (gdp = &gendisk_head; *gdp; gdp = &((*gdp)->next)) | |||
3870 | if (*gdp == hwif->gd) | |||
3871 | break; | |||
3872 | if (*gdp == NULL((void *) 0)) | |||
3873 | printk("gd not in disk chain!\n"); | |||
3874 | else { | |||
3875 | gd = *gdp; *gdp = gd->next; | |||
3876 | kfreelinux_kfree(gd->sizes); | |||
3877 | kfreelinux_kfree(gd->part); | |||
3878 | kfreelinux_kfree(gd); | |||
3879 | } | |||
3880 | init_hwif_data (index); /* restore hwif data to pristine status */ | |||
3881 | restore_flags(flags)__asm__ __volatile__("push %0 ; popf": :"g" (flags):"memory"); | |||
3882 | } | |||
3883 | #endif /* CONFIG_BLK_DEV_IDE_PCMCIA */ |