📄 ide.c
字号:
#endif /* CONFIG_BLK_DEV_IDETAPE */ for (unit = 0; unit < MAX_DRIVES; ++unit) { ide_drive_t *drive = &hwif->drives[unit]; 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';#ifdef MACH drive->name[2] = '0' + (index * MAX_DRIVES) + unit;#else drive->name[2] = 'a' + (index * MAX_DRIVES) + unit;#endif }}/* * 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;}/* * 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 (pcibios_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; override with idebus=xx\n", system_bus_speed); } 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 (unsigned short 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){ unsigned short io_base = HWIF(drive)->io_base; unsigned short data_reg = io_base+IDE_DATA_OFFSET; byte io_32bit = drive->io_32bit; if (io_32bit) {#if SUPPORT_VLB_SYNC if (io_32bit & 2) { cli(); do_vlb_sync(io_base+IDE_NSECTOR_OFFSET); insl(data_reg, buffer, wcount); if (drive->unmask) sti(); } else#endif /* SUPPORT_VLB_SYNC */ insl(data_reg, buffer, wcount); } else {#if SUPPORT_SLOW_DATA_PORTS if (drive->slow) { unsigned short *ptr = (unsigned short *) buffer; while (wcount--) { *ptr++ = inw_p(data_reg); *ptr++ = inw_p(data_reg); } } else#endif /* SUPPORT_SLOW_DATA_PORTS */ insw(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){ unsigned short io_base = HWIF(drive)->io_base; unsigned short data_reg = io_base+IDE_DATA_OFFSET; byte io_32bit = drive->io_32bit; if (io_32bit) {#if SUPPORT_VLB_SYNC if (io_32bit & 2) { cli(); do_vlb_sync(io_base+IDE_NSECTOR_OFFSET); outsl(data_reg, buffer, wcount); if (drive->unmask) sti(); } else#endif /* SUPPORT_VLB_SYNC */ outsl(data_reg, buffer, wcount); } else {#if SUPPORT_SLOW_DATA_PORTS if (drive->slow) { unsigned short *ptr = (unsigned short *) buffer; while (wcount--) { outw_p(*ptr++, data_reg); outw_p(*ptr++, data_reg); } } else#endif /* SUPPORT_SLOW_DATA_PORTS */ outsw(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; 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; ide_output_data (drive, buffer, bytecount / 4); if ((bytecount & 0x03) >= 2) outsw (IDE_DATA_REG, ((byte *)buffer) + (bytecount & ~0x03), 1);}/* * This should get invoked any time we exit the driver to * wait for an interrupt response from a drive. handler() points * at the appropriate code to handle the next interrupt, and a * timer is started to prevent us from waiting forever in case * something goes wrong (see the timer_expiry() handler later on). */void ide_set_handler (ide_drive_t *drive, ide_handler_t *handler, unsigned int timeout){ ide_hwgroup_t *hwgroup = HWGROUP(drive);#ifdef DEBUG if (hwgroup->handler != NULL) { printk("%s: ide_set_handler: handler not null; old=%p, new=%p\n", drive->name, hwgroup->handler, handler); }#endif hwgroup->handler = handler; hwgroup->timer.expires = jiffies + timeout; add_timer(&(hwgroup->timer));}/* * lba_capacity_is_ok() performs a sanity check on the claimed "lba_capacity" * value for this drive (from its reported identification information). * * Returns: 1 if lba_capacity looks sensible * 0 otherwise */static int lba_capacity_is_ok (struct hd_driveid *id){ unsigned long lba_sects = id->lba_capacity; unsigned long chs_sects = id->cyls * id->heads * id->sectors; unsigned long _10_percent = chs_sects / 10; /* very large drives (8GB+) may lie about the number of cylinders */ if (id->cyls == 16383 && id->heads == 16 && id->sectors == 63 && lba_sects > chs_sects) { return 1; /* lba_capacity is our only option */ } /* perform a rough sanity check on lba_sects: within 10% is "okay" */ if ((lba_sects - chs_sects) < _10_percent) return 1; /* lba_capacity is good */ /* some drives have the word order reversed */ lba_sects = (lba_sects << 16) | (lba_sects >> 16); if ((lba_sects - chs_sects) < _10_percent) { id->lba_capacity = lba_sects; /* fix it */ return 1; /* lba_capacity is (now) good */ } return 0; /* lba_capacity value is bad */}/* * current_capacity() returns the capacity (in sectors) of a drive * according to its current geometry/LBA settings. */static unsigned long current_capacity (ide_drive_t *drive){ struct hd_driveid *id = drive->id; unsigned long capacity = drive->cyl * drive->head * drive->sect; if (!drive->present) return 0;#ifdef CONFIG_BLK_DEV_IDEFLOPPY if (drive->media == ide_floppy) return idefloppy_capacity(drive);#endif /* CONFIG_BLK_DEV_IDEFLOPPY */ if (drive->media != ide_disk) return 0x7fffffff; /* cdrom or tape */ drive->select.b.lba = 0; /* Determine capacity, and use LBA if the drive properly supports it */ if (id != NULL && (id->capability & 2) && lba_capacity_is_ok(id)) { if (id->lba_capacity >= capacity) { capacity = id->lba_capacity; drive->select.b.lba = 1; } } return (capacity - drive->sect0);}/* * ide_geninit() is called exactly *once* for each major, from genhd.c, * at the beginning of the initial partition check for the drives. */static void ide_geninit (struct gendisk *gd){ unsigned int unit; ide_hwif_t *hwif = gd->real_devices; for (unit = 0; unit < gd->nr_real; ++unit) { ide_drive_t *drive = &hwif->drives[unit];#ifdef CONFIG_BLK_DEV_IDECD if (drive->present && drive->media == ide_cdrom) ide_cdrom_setup(drive);#endif /* CONFIG_BLK_DEV_IDECD */#ifdef CONFIG_BLK_DEV_IDETAPE if (drive->present && drive->media == ide_tape) idetape_setup(drive);#endif /* CONFIG_BLK_DEV_IDETAPE */#ifdef CONFIG_BLK_DEV_IDEFLOPPY if (drive->present && drive->media == ide_floppy) idefloppy_setup(drive);#endif /* CONFIG_BLK_DEV_IDEFLOPPY */ drive->part[0].nr_sects = current_capacity(drive); if (!drive->present || (drive->media != ide_disk && drive->media != ide_floppy) || !drive->part[0].nr_sects) { drive->part[0].start_sect = -1; /* skip partition check */ } }}/* * init_gendisk() (as opposed to ide_geninit) is called for each major device, * after probing for drives, to allocate partition tables and other data * structures needed for the routines in genhd.c. ide_geninit() gets called * somewhat later, during the partition check. */static void init_gendisk (ide_hwif_t *hwif){ struct gendisk *gd, **gdp; unsigned int unit, units, minors; int *bs; /* figure out maximum drive number on the interface */ for (units = MAX_DRIVES; units > 0; --units) { if (hwif->drives[units-1].present) break; } minors = units * (1<<PARTN_BITS); gd = kmalloc (sizeof(struct gendisk), GFP_KERNEL); gd->sizes = kmalloc (minors * sizeof(int), GFP_KERNEL); gd->part = kmalloc (minors * sizeof(struct hd_struct), GFP_KERNEL); bs = kmalloc (minors*sizeof(int), GFP_KERNEL); memset(gd->part, 0, minors * sizeof(struct hd_struct)); /* cdroms and msdos f/s are examples of non-1024 blocksizes */ blksize_size[hwif->major] = bs; for (unit = 0; unit < minors; ++unit) *bs++ = BLOCK_SIZE; for (unit = 0; unit < units; ++unit) hwif->drives[unit].part = &gd->part[unit << PARTN_BITS]; gd->major = hwif->major; /* our major device number */ gd->major_name = IDE_MAJOR_NAME; /* treated special in genhd.c */ gd->minor_shift = PARTN_BITS; /* num bits for partitions */ gd->max_p = 1<<PARTN_BITS; /* 1 + max partitions / drive */ gd->max_nr = units; /* max num real drives */ gd->nr_real = units; /* current num real drives */ gd->init = ide_geninit; /* initialization function */ gd->real_devices= hwif; /* ptr to internal data */ gd->next = NULL; /* linked list of major devs */ for (gdp = &gendisk_head; *gdp; gdp = &((*gdp)->next)) ; hwif->gd = *gdp = gd; /* link onto tail of list */}static void do_reset1 (ide_drive_t *, int); /* needed below */#ifdef CONFIG_BLK_DEV_IDEATAPI/* * atapi_reset_pollfunc() gets invoked to poll the interface for completion every 50ms * during an atapi drive reset operation. If the drive has not yet responded, * and we have not yet hit our maximum waiting time, then the timer is restarted * for another 50ms. */static void atapi_reset_pollfunc (ide_drive_t *drive){ ide_hwgroup_t *hwgroup = HWGROUP(drive); byte stat; OUT_BYTE (drive->select.all, IDE_SELECT_REG); udelay (10); if (OK_STAT(stat=GET_STAT(), 0, BUSY_STAT)) { printk("%s: ATAPI reset complete\n", drive->name); } else { if (jiffies < hwgroup->poll_timeout) { ide_set_handler (drive, &atapi_reset_pollfunc, HZ/20); return; /* continue polling */ } hwgroup->poll_timeout = 0; /* end of polling */ printk("%s: ATAPI reset timed-out, status=0x%02x\n", drive->name, stat); do_reset1 (drive, 1); /* do it the old fashioned way */ return; } hwgroup->poll_timeout = 0; /* done polling */}#endif /* CONFIG_BLK_DEV_IDEATAPI *//* * reset_pollfunc() gets invoked to poll the interface for completion every 50ms * during an ide reset operation. If the drives have not yet responded, * and we have not yet hit our maximum waiting time, then the timer is restarted * for another 50ms. */static void reset_pollfunc (ide_drive_t *drive){ ide_hwgroup_t *hwgroup = HWGROUP(drive); ide_hwif_t *hwif = HWIF(drive); byte tmp; if (!OK_STAT(tmp=GET_STAT(), 0, BUSY_STAT)) { if (jiffies < hwgroup->poll_timeout) { ide_set_handler (drive, &reset_pollfunc, HZ/20); return; /* continue polling */ } printk("%s: reset timed-out, status=0x%02x\n", hwif->name, tmp); } else { printk("%s: reset: ", hwif->name); if ((tmp = GET_ERR()) == 1) printk("success\n"); else {#if FANCY_STATUS_DUMPS printk("master: "); switch (tmp & 0x7f) { case 1: printk("passed");
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -