📄 ide.c
字号:
/* * linux/drivers/block/ide.c Version 6.18 August 16, 1998 * * Copyright (C) 1994-1998 Linus Torvalds & authors (see below) *//* * Mostly written by Mark Lord <mlord@pobox.com> * and Gadi Oxman <gadio@netvision.net.il> * * See linux/MAINTAINERS for address of current maintainer. * * This is the multiple IDE interface driver, as evolved from hd.c. * It supports up to MAX_HWIFS 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 * ... * * 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 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.60 start to modularize the driver; the disk and ATAPI * drivers can be compiled as loadable modules. * move IDE probe code to ide-probe.c * move IDE disk code to ide-disk.c * add support for generic IDE device subdrivers * add m68k code from Geert Uytterhoeven * probe all interfaces by default * add ioctl to (re)probe an interface * Version 6.00 use per device request queues * attempt to optimize shared hwgroup performance * add ioctl to manually adjust bandwidth algorithms * add kerneld support for the probe module * fix bug in ide_error() * fix bug in the first ide_get_lock() call for Atari * don't flush leftover data for ATAPI devices * Version 6.01 clear hwgroup->active while the hwgroup sleeps * support HDIO_GETGEO for floppies * Version 6.02 fix ide_ack_intr() call * check partition table on floppies * Version 6.03 handle bad status bit sequencing in ide_wait_stat() * Version 6.10 deleted old entries from this list of updates * replaced triton.c with ide-dma.c generic PCI DMA * added support for BIOS-enabled UltraDMA * rename all "promise" things to "pdc4030" * fix EZ-DRIVE handling on small disks * Version 6.11 fix probe error in ide_scan_devices() * fix ancient "jiffies" polling bugs * mask all hwgroup interrupts on each irq entry * Version 6.12 integrate ioctl and proc interfaces * fix parsing of "idex=" command line parameter * Version 6.13 add support for ide4/ide5 courtesy rjones@orchestream.com * Version 6.14 fixed IRQ sharing among PCI devices * Version 6.15 added SMP awareness to IDE drivers * Version 6.16 fixed various bugs; even more SMP friendly * Version 6.17 fix for newest EZ-Drive problem * Version 6.18 default unpartitioned-disk translation now "BIOS LBA" * * 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 */#define _IDE_C /* Tell ide.h it's really us */#include <linux/config.h>#include <linux/module.h>#include <linux/types.h>#include <linux/string.h>#include <linux/kernel.h>#include <linux/timer.h>#include <linux/mm.h>#include <linux/interrupt.h>#include <linux/major.h>#include <linux/errno.h>#include <linux/genhd.h>#include <linux/malloc.h>#include <linux/pci.h>#include <linux/delay.h>#include <asm/byteorder.h>#include <asm/irq.h>#include <asm/uaccess.h>#include <asm/io.h>#include <asm/bitops.h>#include "ide.h"#include "ide_modes.h"#ifdef CONFIG_KMOD#include <linux/kmod.h>#endif /* CONFIG_KMOD */static const byte ide_hwif_to_major[] = {IDE0_MAJOR, IDE1_MAJOR, IDE2_MAJOR, IDE3_MAJOR, IDE4_MAJOR, IDE5_MAJOR };static int idebus_parameter; /* holds the "idebus=" parameter */static int system_bus_speed; /* holds what we think is VESA/PCI bus speed */static int initializing; /* set while initializing built-in drivers *//* * ide_lock is used by the Atari code to obtain access to the IDE interrupt, * which is shared between several drivers. */static int ide_lock = 0;/* * ide_modules keeps track of the available IDE chipset/probe/driver modules. */ide_module_t *ide_modules = NULL;/* * 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); /* local CPU only */ __cli(); /* local CPU only */ t = jiffies * 11932; outb_p(0, 0x43); i = inb_p(0x40); i |= inb(0x40) << 8; __restore_flags(flags); /* local CPU only */ return (t - i);}#endif /* DISK_RECOVERY_TIME */static inline void set_recovery_timer (ide_hwif_t *hwif){#if (DISK_RECOVERY_TIME > 0) hwif->last_time = read_timer();#endif /* DISK_RECOVERY_TIME */}/* * Do not even *think* about calling this! */static void init_hwif_data (unsigned int index){ unsigned int unit; ide_hwif_t *hwif = &ide_hwifs[index]; /* bulk initialize hwif & drive info with zeros */ memset(hwif, 0, sizeof(ide_hwif_t)); /* fill in any non-zero initial values */ hwif->index = index; ide_init_hwif_ports(hwif->io_ports, ide_default_io_base(index), &hwif->irq); hwif->noprobe = !hwif->io_ports[IDE_DATA_OFFSET];#ifdef CONFIG_BLK_DEV_HD if (hwif->io_ports[IDE_DATA_OFFSET] == 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; for (unit = 0; unit < MAX_DRIVES; ++unit) { ide_drive_t *drive = &hwif->drives[unit]; drive->media = ide_disk; drive->select.all = (unit<<4)|0xa0; drive->hwif = hwif; drive->ctl = 0x08; drive->ready_stat = READY_STAT; drive->bad_wstat = BAD_W_STAT; drive->special.b.recalibrate = 1; drive->special.b.set_geometry = 1; drive->name[0] = 'h'; drive->name[1] = 'd'; drive->name[2] = 'a' + (index * MAX_DRIVES) + unit; }}/* * init_ide_data() sets reasonable default values into all fields * of all instances of the hwifs and drives, but only on the first call. * Subsequent calls have no effect (they don't wipe out anything). * * This routine is normally called at driver initialization time, * but may also be called MUCH earlier during kernel "command-line" * parameter processing. As such, we cannot depend on any other parts * of the kernel (such as memory allocation) to be functioning yet. * * This is too bad, as otherwise we could dynamically allocate the * ide_drive_t structs as needed, rather than always consuming memory * for the max possible number (MAX_HWIFS * MAX_DRIVES) of them. */#define MAGIC_COOKIE 0x12345678static void init_ide_data (void){ unsigned int index; static unsigned long magic_cookie = MAGIC_COOKIE; if (magic_cookie != MAGIC_COOKIE) return; /* already initialized */ magic_cookie = 0; for (index = 0; index < MAX_HWIFS; ++index) init_hwif_data(index); idebus_parameter = 0; system_bus_speed = 0;}/* * CompactFlash cards and their brethern pretend to be removable hard disks, except: * (1) they never have a slave unit, and * (2) they don't have doorlock mechanisms. * This test catches them, and is invoked elsewhere when setting appropriate config bits. * * FIXME: This treatment is probably applicable for *all* PCMCIA (PC CARD) devices, * so in linux 2.3.x we should change this to just treat all PCMCIA drives this way, * and get rid of the model-name tests below (too big of an interface change for 2.2.x). * At that time, we might also consider parameterizing the timeouts and retries, * since these are MUCH faster than mechanical drives. -M.Lord */int drive_is_flashcard (ide_drive_t *drive){ struct hd_driveid *id = drive->id; if (drive->removable && id != NULL) { if (!strncmp(id->model, "KODAK ATA_FLASH", 15) /* Kodak */ || !strncmp(id->model, "Hitachi CV", 10) /* Hitachi */ || !strncmp(id->model, "SunDisk SDCFB", 13) /* SunDisk */ || !strncmp(id->model, "HAGIWARA HPC", 12)) /* Hagiwara */ { return 1; /* yes, it is a flash memory card */ } } return 0; /* no, it is not a flash memory card */}/* * ide_system_bus_speed() returns what we think is the system VESA/PCI * bus speed (in MHz). This is used for calculating interface PIO timings. * The default is 40 for known PCI systems, 50 otherwise. * The "idebus=xx" parameter can be used to override this value. * The actual value to be used is computed/displayed the first time through. */int ide_system_bus_speed (void){ if (!system_bus_speed) { if (idebus_parameter) system_bus_speed = idebus_parameter; /* user supplied value */#ifdef CONFIG_PCI else if (pci_present()) system_bus_speed = 40; /* safe default value for PCI */#endif /* CONFIG_PCI */ else system_bus_speed = 50; /* safe default value for VESA and PCI */ printk("ide: Assuming %dMHz system bus speed for PIO modes%s\n", system_bus_speed, idebus_parameter ? "" : "; override with idebus=xx"); } return system_bus_speed;}#if SUPPORT_VLB_SYNC/* * Some localbus EIDE interfaces require a special access sequence * when using 32-bit I/O instructions to transfer data. We call this * the "vlb_sync" sequence, which consists of three successive reads * of the sector count register location, with interrupts disabled * to ensure that the reads all happen together. */static inline void do_vlb_sync (ide_ioreg_t port) { (void) inb (port); (void) inb (port); (void) inb (port);}#endif /* SUPPORT_VLB_SYNC *//* * This is used for most PIO data transfers *from* the IDE interface */void ide_input_data (ide_drive_t *drive, void *buffer, unsigned int wcount){ byte io_32bit = drive->io_32bit; if (io_32bit) {#if SUPPORT_VLB_SYNC if (io_32bit & 2) { unsigned long flags; __save_flags(flags); /* local CPU only */ __cli(); /* local CPU only */ do_vlb_sync(IDE_NSECTOR_REG); insl(IDE_DATA_REG, buffer, wcount); __restore_flags(flags); /* local CPU only */ } else#endif /* SUPPORT_VLB_SYNC */ insl(IDE_DATA_REG, buffer, wcount); } else {#if SUPPORT_SLOW_DATA_PORTS if (drive->slow) { unsigned short *ptr = (unsigned short *) buffer; while (wcount--) { *ptr++ = inw_p(IDE_DATA_REG); *ptr++ = inw_p(IDE_DATA_REG); } } else#endif /* SUPPORT_SLOW_DATA_PORTS */ insw(IDE_DATA_REG, buffer, wcount<<1); }}/* * This is used for most PIO data transfers *to* the IDE interface */void ide_output_data (ide_drive_t *drive, void *buffer, unsigned int wcount){ byte io_32bit = drive->io_32bit; if (io_32bit) {#if SUPPORT_VLB_SYNC if (io_32bit & 2) { unsigned long flags; __save_flags(flags); /* local CPU only */ __cli(); /* local CPU only */ do_vlb_sync(IDE_NSECTOR_REG); outsl(IDE_DATA_REG, buffer, wcount); __restore_flags(flags); /* local CPU only */ } else#endif /* SUPPORT_VLB_SYNC */ outsl(IDE_DATA_REG, buffer, wcount); } else {#if SUPPORT_SLOW_DATA_PORTS if (drive->slow) { unsigned short *ptr = (unsigned short *) buffer; while (wcount--) { outw_p(*ptr++, IDE_DATA_REG); outw_p(*ptr++, IDE_DATA_REG); } } else#endif /* SUPPORT_SLOW_DATA_PORTS */ outsw(IDE_DATA_REG, buffer, wcount<<1); }}/* * The following routines are mainly used by the ATAPI drivers. * * These routines will round up any request for an odd number of bytes, * so if an odd bytecount is specified, be sure that there's at least one * extra byte allocated for the buffer. */void atapi_input_bytes (ide_drive_t *drive, void *buffer, unsigned int bytecount){ ++bytecount;#ifdef CONFIG_ATARI if (MACH_IS_ATARI) { /* Atari has a byte-swapped IDE interface */ insw_swapw(IDE_DATA_REG, buffer, bytecount / 2); return; }#endif /* CONFIG_ATARI */ ide_input_data (drive, buffer, bytecount / 4); if ((bytecount & 0x03) >= 2) insw (IDE_DATA_REG, ((byte *)buffer) + (bytecount & ~0x03), 1);}void atapi_output_bytes (ide_drive_t *drive, void *buffer, unsigned int bytecount){ ++bytecount;#ifdef CONFIG_ATARI if (MACH_IS_ATARI) { /* Atari has a byte-swapped IDE interface */ outsw_swapw(IDE_DATA_REG, buffer, bytecount / 2); return; }#endif /* CONFIG_ATARI */ ide_output_data (drive, buffer, bytecount / 4); if ((bytecount & 0x03) >= 2) outsw (IDE_DATA_REG, ((byte *)buffer) + (bytecount & ~0x03), 1);}/* * Needed for PCI irq sharing */static inline int drive_is_ready (ide_drive_t *drive){ if (drive->waiting_for_dma) return HWIF(drive)->dmaproc(ide_dma_test_irq, drive);#if 0
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -