⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ide.c

📁 GNU Mach 微内核源代码, 基于美国卡内基美隆大学的 Mach 研究项目
💻 C
📖 第 1 页 / 共 5 页
字号:
/* *  linux/drivers/block/ide.c	Version 5.53  Jun  24, 1997 * *  Copyright (C) 1994-1996  Linus Torvalds & authors (see below) */#define _IDE_C		/* needed by <linux/blk.h> *//* *  Maintained by Mark Lord  <mlord@pobox.com> *            and Gadi Oxman <gadio@netvision.net.il> * * This is the multiple IDE interface driver, as evolved from hd.c. * It supports up to four IDE interfaces, on one or more IRQs (usually 14 & 15). * There can be up to two drives per interface, as per the ATA-2 spec. * * Primary:    ide0, port 0x1f0; major=3;  hda is minor=0; hdb is minor=64 * Secondary:  ide1, port 0x170; major=22; hdc is minor=0; hdd is minor=64 * Tertiary:   ide2, port 0x???; major=33; hde is minor=0; hdf is minor=64 * Quaternary: ide3, port 0x???; major=34; hdg is minor=0; hdh is minor=64 * * It is easy to extend ide.c to handle more than four interfaces: * *	Change the MAX_HWIFS constant in ide.h. * *	Define some new major numbers (in major.h), and insert them into *	the ide_hwif_to_major table in ide.c. * *	Fill in the extra values for the new interfaces into the two tables *	inside ide.c:  default_io_base[]  and  default_irqs[]. * *	Create the new request handlers by cloning "do_ide3_request()" *	for each new interface, and add them to the switch statement *	in the ide_init() function in ide.c. * *	Recompile, create the new /dev/ entries, and it will probably work. * *  From hd.c: *  | *  | It traverses the request-list, using interrupts to jump between functions. *  | As nearly all functions can be called within interrupts, we may not sleep. *  | Special care is recommended.  Have Fun! *  | *  | modified by Drew Eckhardt to check nr of hd's from the CMOS. *  | *  | Thanks to Branko Lankester, lankeste@fwi.uva.nl, who found a bug *  | in the early extended-partition checks and added DM partitions. *  | *  | Early work on error handling by Mika Liljeberg (liljeber@cs.Helsinki.FI). *  | *  | IRQ-unmask, drive-id, multiple-mode, support for ">16 heads", *  | and general streamlining by Mark Lord (mlord@pobox.com). * *  October, 1994 -- Complete line-by-line overhaul for linux 1.1.x, by: * *	Mark Lord	(mlord@pobox.com)		(IDE Perf.Pkg) *	Delman Lee	(delman@mipg.upenn.edu)		("Mr. atdisk2") *	Scott Snyder	(snyder@fnald0.fnal.gov)	(ATAPI IDE cd-rom) * *  This was a rewrite of just about everything from hd.c, though some original *  code is still sprinkled about.  Think of it as a major evolution, with *  inspiration from lots of linux users, esp.  hamish@zot.apana.org.au * *  Version 1.0 ALPHA	initial code, primary i/f working okay *  Version 1.3 BETA	dual i/f on shared irq tested & working! *  Version 1.4 BETA	added auto probing for irq(s) *  Version 1.5 BETA	added ALPHA (untested) support for IDE cd-roms, *  ... *  Version 3.5		correct the bios_cyl field if it's too small *  (linux 1.1.76)	 (to help fdisk with brain-dead BIOSs) *  Version 3.6		cosmetic corrections to comments and stuff *  (linux 1.1.77)	reorganise probing code to make it understandable *			added halfway retry to probing for drive identification *			added "hdx=noprobe" command line option *			allow setting multmode even when identification fails *  Version 3.7		move set_geometry=1 from do_identify() to ide_init() *			increase DRQ_WAIT to eliminate nuisance messages *			wait for DRQ_STAT instead of DATA_READY during probing *			  (courtesy of Gary Thomas gary@efland.UU.NET) *  Version 3.8		fixed byte-swapping for confused Mitsumi cdrom drives *			update of ide-cd.c from Scott, allows blocksize=1024 *			cdrom probe fixes, inspired by jprang@uni-duisburg.de *  Version 3.9		don't use LBA if lba_capacity looks funny *			correct the drive capacity calculations *			fix probing for old Seagates without IDE_ALTSTATUS_REG *			fix byte-ordering for some NEC cdrom drives *  Version 3.10	disable multiple mode by default; was causing trouble *  Version 3.11	fix mis-identification of old WD disks as cdroms *  Version 3,12	simplify logic for selecting initial mult_count *			  (fixes problems with buggy WD drives) *  Version 3.13	remove excess "multiple mode disabled" messages *  Version 3.14	fix ide_error() handling of BUSY_STAT *			fix byte-swapped cdrom strings (again.. arghh!) *			ignore INDEX bit when checking the ALTSTATUS reg *  Version 3.15	add SINGLE_THREADED flag for use with dual-CMD i/f *			ignore WRERR_STAT for non-write operations *			added vlb_sync support for DC-2000A & others, *			 (incl. some Promise chips), courtesy of Frank Gockel *  Version 3.16	convert vlb_32bit and vlb_sync into runtime flags *			add ioctls to get/set VLB flags (HDIO_[SG]ET_CHIPSET) *			rename SINGLE_THREADED to SUPPORT_SERIALIZE, *			add boot flag to "serialize" operation for CMD i/f *			add optional support for DTC2278 interfaces, *			 courtesy of andy@cercle.cts.com (Dyan Wile). *			add boot flag to enable "dtc2278" probe *			add probe to avoid EATA (SCSI) interfaces, *			 courtesy of neuffer@goofy.zdv.uni-mainz.de. *  Version 4.00	tidy up verify_area() calls - heiko@colossus.escape.de *			add flag to ignore WRERR_STAT for some drives *			 courtesy of David.H.West@um.cc.umich.edu *			assembly syntax tweak to vlb_sync *			removable drive support from scuba@cs.tu-berlin.de *			add transparent support for DiskManager-6.0x "Dynamic *			 Disk Overlay" (DDO), most of this is in genhd.c *			eliminate "multiple mode turned off" message at boot *  Version 4.10	fix bug in ioctl for "hdparm -c3" *			fix DM6:DDO support -- now works with LILO, fdisk, ... *			don't treat some naughty WD drives as removable *  Version 4.11	updated DM6 support using info provided by OnTrack *  Version 5.00	major overhaul, multmode setting fixed, vlb_sync fixed *			added support for 3rd/4th/alternative IDE ports *			created ide.h; ide-cd.c now compiles separate from ide.c *			hopefully fixed infinite "unexpected_intr" from cdroms *			zillions of other changes and restructuring *			somehow reduced overall memory usage by several kB *			probably slowed things down slightly, but worth it *  Version 5.01	AT LAST!!  Finally understood why "unexpected_intr" *			 was happening at various times/places:  whenever the *			 ide-interface's ctl_port was used to "mask" the irq, *			 it also would trigger an edge in the process of masking *			 which would result in a self-inflicted interrupt!! *			 (such a stupid way to build a hardware interrupt mask). *			 This is now fixed (after a year of head-scratching). *  Version 5.02	got rid of need for {enable,disable}_irq_list() *  Version 5.03	tune-ups, comments, remove "busy wait" from drive resets *			removed PROBE_FOR_IRQS option -- no longer needed *			OOOPS!  fixed "bad access" bug for 2nd drive on an i/f *  Version 5.04	changed "ira %d" to "irq %d" in DEBUG message *			added more comments, cleaned up unexpected_intr() *			OOOPS!  fixed null pointer problem in ide reset code *			added autodetect for Triton chipset -- no effect yet *  Version 5.05	OOOPS!  fixed bug in revalidate_disk() *			OOOPS!  fixed bug in ide_do_request() *			added ATAPI reset sequence for cdroms *  Version 5.10	added Bus-Mastered DMA support for Triton Chipset *			some (mostly) cosmetic changes *  Version 5.11	added ht6560b support by malafoss@snakemail.hut.fi *			reworked PCI scanning code *			added automatic RZ1000 detection/support *			added automatic PCI CMD640 detection/support *			added option for VLB CMD640 support *			tweaked probe to find cdrom on hdb with disks on hda,hdc *  Version 5.12	some performance tuning *			added message to alert user to bad /dev/hd[cd] entries *			OOOPS!  fixed bug in atapi reset *			driver now forces "serialize" again for all cmd640 chips *			noticed REALLY_SLOW_IO had no effect, moved it to ide.c *			made do_drive_cmd() into public ide_do_drive_cmd() *  Version 5.13	fixed typo ('B'), thanks to houston@boyd.geog.mcgill.ca *			fixed ht6560b support *  Version 5.13b (sss)	fix problem in calling ide_cdrom_setup() *			don't bother invalidating nonexistent partitions *  Version 5.14	fixes to cmd640 support.. maybe it works now(?) *			added & tested full EZ-DRIVE support -- don't use LILO! *			don't enable 2nd CMD640 PCI port during init - conflict *  Version 5.15	bug fix in init_cmd640_vlb() *			bug fix in interrupt sharing code *  Version 5.16	ugh.. fix "serialize" support, broken in 5.15 *			remove "Huh?" from cmd640 code *			added qd6580 interface speed select from Colten Edwards *  Version 5.17	kludge around bug in BIOS32 on Intel triton motherboards *  Version 5.18	new CMD640 code, moved to cmd640.c, #include'd for now *			new UMC8672 code, moved to umc8672.c, #include'd for now *			disallow turning on DMA when h/w not capable of DMA *  Version 5.19	fix potential infinite timeout on resets *			extend reset poll into a general purpose polling scheme *			add atapi tape drive support from Gadi Oxman *			simplify exit from _intr routines -- no IDE_DO_REQUEST *  Version 5.20	leave current rq on blkdev request list during I/O *			generalized ide_do_drive_cmd() for tape/cdrom driver use *  Version 5.21	fix nasty cdrom/tape bug (ide_preempt was messed up) *  Version 5.22	fix ide_xlate_1024() to work with/without drive->id *  Version 5.23	miscellaneous touch-ups *  Version 5.24	fix #if's for SUPPORT_CMD640 *  Version 5.25	more touch-ups, fix cdrom resets, ... *			cmd640.c now configs/compiles separate from ide.c *  Version 5.26	keep_settings now maintains the using_dma flag *			fix [EZD] remap message to only output at boot time *			fix "bad /dev/ entry" message to say hdc, not hdc0 *			fix ide_xlate_1024() to respect user specified CHS *			use CHS from partn table if it looks translated *			re-merged flags chipset,vlb_32bit,vlb_sync into io_32bit *			keep track of interface chipset type, when known *			add generic PIO mode "tuneproc" mechanism *			fix cmd640_vlb option *			fix ht6560b support (was completely broken) *			umc8672.c now configures/compiles separate from ide.c *			move dtc2278 support to dtc2278.c *			move ht6560b support to ht6560b.c *			move qd6580  support to qd6580.c *			add  ali14xx support in ali14xx.c * Version 5.27		add [no]autotune parameters to help cmd640 *			move rz1000  support to rz1000.c * Version 5.28		#include "ide_modes.h" *			fix disallow_unmask: now per-interface "no_unmask" bit *			force io_32bit to be the same on drive pairs of dtc2278 *			improved IDE tape error handling, and tape DMA support *			bugfix in ide_do_drive_cmd() for cdroms + serialize * Version 5.29		fixed non-IDE check for too many physical heads *			don't use LBA if capacity is smaller than CHS * Version 5.30		remove real_devices kludge, formerly used by genhd.c * Version 5.32		change "KB" to "kB" *			fix serialize (was broken in kernel 1.3.72) *			add support for "hdparm -I" *			use common code for disk/tape/cdrom IDE_DRIVE_CMDs *			add support for Promise DC4030VL caching card *			improved serialize support *			put partition check back into alphabetical order *			add config option for PCMCIA baggage *			try to make PCMCIA support safer to use *			improve security on ioctls(): all are suser() only * Version 5.33		improve handling of HDIO_DRIVE_CMDs that read data * Version 5.34		fix irq-sharing problem from 5.33 *			fix cdrom ioctl problem from 5.33 * Version 5.35		cosmetic changes *			fix cli() problem in try_to_identify() * Version 5.36		fixes to optional PCMCIA support * Version 5.37		don't use DMA when "noautotune" is specified * Version 5.37a (go)	fix shared irq probing (was broken in kernel 1.3.72) *			call unplug_device() from ide_do_drive_cmd() * Version 5.38		add "hdx=none" option, courtesy of Joel Maslak *			mask drive irq after use, if sharing with another hwif *			add code to help debug weird cmd640 problems * Version 5.39		fix horrible error in earlier irq sharing "fix" * Version 5.40		fix serialization -- was broken in 5.39 *			help sharing by masking device irq after probing * Version 5.41		more fixes to irq sharing/serialize detection *			disable io_32bit by default on drive reset * Version 5.42		simplify irq-masking after probe *			fix NULL pointer deref in save_match() * Version 5.43		Ugh.. unexpected_intr is back: try to exterminate it * Version 5.44		Fix for "irq probe failed" on cmd640 *			change path on message regarding MAKEDEV.ide *			add a throttle to the unexpected_intr() messages * Version 5.45		fix ugly parameter parsing bugs (thanks Derek) *			include Gadi's magic fix for cmd640 unexpected_intr *			include mc68000 patches from Geert Uytterhoeven *			add Gadi's fix for PCMCIA cdroms * Version 5.46		remove the mc68000 #ifdefs for 2.0.x * Version 5.47		fix set_tune race condition *			fix bug in earlier PCMCIA cdrom update * Version 5.48		if def'd, invoke CMD640_DUMP_REGS when irq probe fails *			lengthen the do_reset1() pulse, for laptops *			add idebus=xx parameter for cmd640 and ali chipsets *			no_unmask flag now per-drive instead of per-hwif *			fix tune_req so that it gets done immediately *			fix missing restore_flags() in ide_ioctl *			prevent use of io_32bit on cmd640 with no prefetch * Version 5.49		fix minor quirks in probing routines * Version 5.50		allow values as small as 20 for idebus= * Version 5.51		force non io_32bit in drive_cmd_intr() *			change delay_10ms() to delay_50ms() to fix problems * Version 5.52		fix incorrect invalidation of removable devices *			add "hdx=slow" command line option * Version 5.53		add ATAPI floppy drive support *			change default media for type 0 to floppy *			add support for Exabyte Nest *			add missing set_blocksize() in revalidate_disk() *			handle bad status bit sequencing in ide_wait_stat() *			support partition table translations with 255 heads *			probe all interfaces by default *			add probe for the i82371AB chipset *			acknowledge media change on removable drives *			add work-around for BMI drives *			remove "LBA" from boot messages * Version 5.53.1	add UDMA "CRC retry" support * Version 5.53.2	add Promise/33 auto-detection and DMA support *			fix MC_ERR handling *			fix mis-detection of NEC cdrom as floppy *			issue ATAPI reset and re-probe after "no response" * *  Some additional driver compile-time options are in ide.h * *  To do, in likely order of completion: *	- modify kernel to obtain BIOS geometry for drives on 2nd/3rd/4th i/f*/#undef REALLY_SLOW_IO		/* most systems can safely undef this */#include <linux/config.h>#include <linux/types.h>#include <linux/string.h>#include <linux/kernel.h>#include <linux/delay.h>#include <linux/timer.h>#include <linux/mm.h>#include <linux/ioport.h>#include <linux/interrupt.h>#include <linux/major.h>#include <linux/blkdev.h>#include <linux/errno.h>#include <linux/hdreg.h>#include <linux/genhd.h>#include <linux/malloc.h>#include <asm/byteorder.h>#include <asm/irq.h>#include <asm/segment.h>#include <asm/io.h>#ifdef CONFIG_PCI#include <linux/bios32.h>#include <linux/pci.h>#endif /* CONFIG_PCI */#include "ide.h"#include "ide_modes.h"#ifdef CONFIG_BLK_DEV_PROMISE#include "promise.h"#define IS_PROMISE_DRIVE (HWIF(drive)->chipset == ide_promise)#else#define IS_PROMISE_DRIVE (0)	/* auto-NULLs out Promise code */#endif /* CONFIG_BLK_DEV_PROMISE */static const byte	ide_hwif_to_major[MAX_HWIFS] = {IDE0_MAJOR, IDE1_MAJOR, IDE2_MAJOR, IDE3_MAJOR};static const unsigned short default_io_base[MAX_HWIFS] = {0x1f0, 0x170, 0x1e8, 0x168};static const byte	default_irqs[MAX_HWIFS]     = {14, 15, 11, 10};static int	idebus_parameter; /* holds the "idebus=" parameter */static int	system_bus_speed; /* holds what we think is VESA/PCI bus speed *//* * This is declared extern in ide.h, for access by other IDE modules: */ide_hwif_t	ide_hwifs[MAX_HWIFS];	/* master data repository */#if (DISK_RECOVERY_TIME > 0)/* * For really screwy hardware (hey, at least it *can* be used with Linux) * we can enforce a minimum delay time between successive operations. */static unsigned long read_timer(void){	unsigned long t, flags;	int i;	save_flags(flags);	cli();	t = jiffies * 11932;    	outb_p(0, 0x43);	i = inb_p(0x40);	i |= inb(0x40) << 8;	restore_flags(flags);	return (t - i);}static void set_recovery_timer (ide_hwif_t *hwif){	hwif->last_time = read_timer();}#define SET_RECOVERY_TIMER(drive) set_recovery_timer (drive)#else#define SET_RECOVERY_TIMER(drive)#endif /* DISK_RECOVERY_TIME *//* * Do not even *think* about calling this! */static void init_hwif_data (unsigned int index){	byte *p;	unsigned int unit;	ide_hwif_t *hwif = &ide_hwifs[index];	/* bulk initialize hwif & drive info with zeros */	p = ((byte *) hwif) + sizeof(ide_hwif_t);	do {		*--p = 0;	} while (p > (byte *) hwif);	/* fill in any non-zero initial values */	hwif->index     = index;	hwif->io_base	= default_io_base[index];	hwif->ctl_port	= hwif->io_base ? hwif->io_base+0x206 : 0x000;#ifdef CONFIG_BLK_DEV_HD	if (hwif->io_base == HD_DATA)		hwif->noprobe = 1; /* may be overridden by ide_setup() */#endif /* CONFIG_BLK_DEV_HD */	hwif->major	= ide_hwif_to_major[index];	hwif->name[0]	= 'i';	hwif->name[1]	= 'd';	hwif->name[2]	= 'e';	hwif->name[3]	= '0' + index;#ifdef CONFIG_BLK_DEV_IDETAPE	hwif->tape_drive = NULL;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -