?? ide-disk.c
字號:
args.command_type = ide_cmd_type_parser(&args); (void) ide_raw_taskfile(drive, &args, NULL); drive->wcache = arg; return 0;}static int call_idedisk_standby (ide_drive_t *drive, int arg){ ide_task_t args; u8 standby = (arg) ? WIN_STANDBYNOW2 : WIN_STANDBYNOW1; memset(&args, 0, sizeof(ide_task_t)); args.tfRegister[IDE_COMMAND_OFFSET] = standby; args.command_type = ide_cmd_type_parser(&args); return ide_raw_taskfile(drive, &args, NULL);}static int do_idedisk_standby (ide_drive_t *drive){ return call_idedisk_standby(drive, 0);}static int call_idedisk_suspend (ide_drive_t *drive, int arg){ ide_task_t args; u8 suspend = (arg) ? WIN_SLEEPNOW2 : WIN_SLEEPNOW1; memset(&args, 0, sizeof(ide_task_t)); args.tfRegister[IDE_COMMAND_OFFSET] = suspend; args.command_type = ide_cmd_type_parser(&args); return ide_raw_taskfile(drive, &args, NULL);}static int do_idedisk_suspend (ide_drive_t *drive){ if (drive->suspend_reset) return 1; ide_cacheflush_p(drive); return call_idedisk_suspend(drive, 0);}#if 0static int call_idedisk_checkpower (ide_drive_t *drive, int arg){ ide_task_t args; u8 ckpw = (arg) ? WIN_CHECKPOWERMODE2 : WIN_CHECKPOWERMODE1; memset(&args, 0, sizeof(ide_task_t)); args.tfRegister[IDE_COMMAND_OFFSET] = ckpw; args.command_type = ide_cmd_type_parser(&args); ide_raw_taskfile(drive, &args, NULL);#if 0if (errno != EIO || args[0] != 0 || args[1] != 0) state = "unknown";else state = "sleeping";} else { state = (args[2] == 255) ? "active/idle" : "standby";#endif return 0;}static int do_idedisk_checkpower (ide_drive_t *drive){ return call_idedisk_checkpower(drive, 0);}#endifstatic int do_idedisk_resume (ide_drive_t *drive){ if (!drive->suspend_reset) return 1; return 0;}static int do_idedisk_flushcache (ide_drive_t *drive){ ide_task_t args; memset(&args, 0, sizeof(ide_task_t)); if (drive->id->cfs_enable_2 & 0x2400) args.tfRegister[IDE_COMMAND_OFFSET] = WIN_FLUSH_CACHE_EXT; else args.tfRegister[IDE_COMMAND_OFFSET] = WIN_FLUSH_CACHE; args.command_type = ide_cmd_type_parser(&args); return ide_raw_taskfile(drive, &args, NULL);}static int set_acoustic (ide_drive_t *drive, int arg){ ide_task_t args; memset(&args, 0, sizeof(ide_task_t)); args.tfRegister[IDE_FEATURE_OFFSET] = (arg) ? SETFEATURES_EN_AAM : SETFEATURES_DIS_AAM; args.tfRegister[IDE_NSECTOR_OFFSET] = arg; args.tfRegister[IDE_COMMAND_OFFSET] = WIN_SETFEATURES; args.command_type = ide_cmd_type_parser(&args); ide_raw_taskfile(drive, &args, NULL); drive->acoustic = arg; return 0;}static int probe_lba_addressing (ide_drive_t *drive, int arg){ drive->addressing = 0; if (HWIF(drive)->addressing) return 0; if (!(drive->id->cfs_enable_2 & 0x0400)) return -EIO; drive->addressing = arg; return 0;}static int set_lba_addressing (ide_drive_t *drive, int arg){ return (probe_lba_addressing(drive, arg));}static void idedisk_add_settings(ide_drive_t *drive){ struct hd_driveid *id = drive->id; int major = HWIF(drive)->major; int minor = drive->select.b.unit << PARTN_BITS; ide_add_setting(drive, "bios_cyl", SETTING_RW, -1, -1, TYPE_INT, 0, 65535, 1, 1, &drive->bios_cyl, NULL); ide_add_setting(drive, "bios_head", SETTING_RW, -1, -1, TYPE_BYTE, 0, 255, 1, 1, &drive->bios_head, NULL); ide_add_setting(drive, "bios_sect", SETTING_RW, -1, -1, TYPE_BYTE, 0, 63, 1, 1, &drive->bios_sect, NULL); ide_add_setting(drive, "address", SETTING_RW, HDIO_GET_ADDRESS, HDIO_SET_ADDRESS, TYPE_INTA, 0, 2, 1, 1, &drive->addressing, set_lba_addressing); ide_add_setting(drive, "bswap", SETTING_READ, -1, -1, TYPE_BYTE, 0, 1, 1, 1, &drive->bswap, NULL); ide_add_setting(drive, "multcount", id ? SETTING_RW : SETTING_READ, HDIO_GET_MULTCOUNT, HDIO_SET_MULTCOUNT, TYPE_BYTE, 0, id ? id->max_multsect : 0, 1, 1, &drive->mult_count, set_multcount); ide_add_setting(drive, "nowerr", SETTING_RW, HDIO_GET_NOWERR, HDIO_SET_NOWERR, TYPE_BYTE, 0, 1, 1, 1, &drive->nowerr, set_nowerr); ide_add_setting(drive, "breada_readahead", SETTING_RW, BLKRAGET, BLKRASET, TYPE_INT, 0, 255, 1, 1, &read_ahead[major], NULL); ide_add_setting(drive, "file_readahead", SETTING_RW, BLKFRAGET, BLKFRASET, TYPE_INTA, 0, 4096, PAGE_SIZE, 1024, &max_readahead[major][minor], NULL); ide_add_setting(drive, "max_kb_per_request", SETTING_RW, BLKSECTGET, BLKSECTSET, TYPE_INTA, 1, 255, 1, 2, &max_sectors[major][minor], NULL); ide_add_setting(drive, "lun", SETTING_RW, -1, -1, TYPE_INT, 0, 7, 1, 1, &drive->lun, NULL); ide_add_setting(drive, "wcache", SETTING_RW, HDIO_GET_WCACHE, HDIO_SET_WCACHE, TYPE_BYTE, 0, 1, 1, 1, &drive->wcache, write_cache); ide_add_setting(drive, "acoustic", SETTING_RW, HDIO_GET_ACOUSTIC, HDIO_SET_ACOUSTIC, TYPE_BYTE, 0, 254, 1, 1, &drive->acoustic, set_acoustic); ide_add_setting(drive, "failures", SETTING_RW, -1, -1, TYPE_INT, 0, 65535, 1, 1, &drive->failures, NULL); ide_add_setting(drive, "max_failures", SETTING_RW, -1, -1, TYPE_INT, 0, 65535, 1, 1, &drive->max_failures, NULL);}static int idedisk_ioctl (ide_drive_t *drive, struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg){#if 0HDIO_GET_ADDRESSHDIO_SET_ADDRESSHDIO_GET_WCACHEHDIO_SET_WCACHEHDIO_GET_ACOUSTICHDIO_SET_ACOUSTICHDIO_GET_MULTCOUNTHDIO_SET_MULTCOUNTHDIO_GET_NOWERRHDIO_SET_NOWERR#endif return -EINVAL;}static void idedisk_setup (ide_drive_t *drive){ int i; struct hd_driveid *id = drive->id; unsigned long capacity; idedisk_add_settings(drive); if (drive->id_read == 0) return; /* * CompactFlash cards and their brethern look just like hard drives * to us, but they are removable and don't have a doorlock mechanism. */ if (drive->removable && !(drive->is_flash)) { /* * Removable disks (eg. SYQUEST); ignore 'WD' drives */ if (id->model[0] != 'W' || id->model[1] != 'D') { drive->doorlocking = 1; } } for (i = 0; i < MAX_DRIVES; ++i) { ide_hwif_t *hwif = HWIF(drive); if (drive != &hwif->drives[i]) continue; hwif->gd->de_arr[i] = drive->de; if (drive->removable) hwif->gd->flags[i] |= GENHD_FL_REMOVABLE; break; }#if 1 (void) probe_lba_addressing(drive, 1);#else /* if using 48-bit addressing bump the request size up */ if (probe_lba_addressing(drive, 1)) blk_queue_max_sectors(&drive->queue, 2048);#endif /* Extract geometry if we did not already have one for the drive */ if (!drive->cyl || !drive->head || !drive->sect) { drive->cyl = drive->bios_cyl = id->cyls; drive->head = drive->bios_head = id->heads; drive->sect = drive->bios_sect = id->sectors; } /* Handle logical geometry translation by the drive */ if ((id->field_valid & 1) && id->cur_cyls && id->cur_heads && (id->cur_heads <= 16) && id->cur_sectors) { drive->cyl = id->cur_cyls; drive->head = id->cur_heads; drive->sect = id->cur_sectors; } /* Use physical geometry if what we have still makes no sense */ if (drive->head > 16 && id->heads && id->heads <= 16) { drive->cyl = id->cyls; drive->head = id->heads; drive->sect = id->sectors; } /* calculate drive capacity, and select LBA if possible */ init_idedisk_capacity (drive); /* * if possible, give fdisk access to more of the drive, * by correcting bios_cyls: */ capacity = idedisk_capacity (drive); if ((capacity >= (drive->bios_cyl * drive->bios_sect * drive->bios_head)) && (!drive->forced_geom) && drive->bios_sect && drive->bios_head) drive->bios_cyl = (capacity / drive->bios_sect) / drive->bios_head; printk (KERN_INFO "%s: %ld sectors", drive->name, capacity); /* Give size in megabytes (MB), not mebibytes (MiB). */ /* We compute the exact rounded value, avoiding overflow. */ printk (" (%ld MB)", (capacity - capacity/625 + 974)/1950); /* Only print cache size when it was specified */ if (id->buf_size) printk (" w/%dKiB Cache", id->buf_size/2); printk(", CHS=%d/%d/%d", drive->bios_cyl, drive->bios_head, drive->bios_sect);#ifdef CONFIG_BLK_DEV_IDEDMA if (drive->using_dma) (void) HWIF(drive)->ide_dma_verbose(drive);#endif /* CONFIG_BLK_DEV_IDEDMA */ printk("\n"); drive->mult_count = 0; if (id->max_multsect) { id->multsect = ((id->max_multsect/2) > 1) ? id->max_multsect : 0; id->multsect_valid = id->multsect ? 1 : 0; drive->mult_req = id->multsect_valid ? id->max_multsect : INITIAL_MULT_COUNT; drive->special.b.set_multmode = drive->mult_req ? 1 : 0; } drive->no_io_32bit = id->dword_io ? 1 : 0; if (drive->id->cfs_enable_2 & 0x3000) write_cache(drive, (id->cfs_enable_2 & 0x3000));}static int idedisk_cleanup(ide_drive_t *drive){ ide_cacheflush_p(drive); return ide_unregister_subdriver(drive);}int idedisk_init (void);int idedisk_attach(ide_drive_t *drive);/* * IDE subdriver functions, registered with ide.c */static ide_driver_t idedisk_driver = { name: "ide-disk", version: IDEDISK_VERSION, media: ide_disk, busy: 0, supports_dma: 1, supports_dsc_overlap: 0, cleanup: idedisk_cleanup, standby: do_idedisk_standby, suspend: do_idedisk_suspend, resume: do_idedisk_resume, flushcache: do_idedisk_flushcache, do_request: ide_do_rw_disk, end_request: idedisk_end_request, sense: idedisk_dump_status, error: idedisk_error, abort: idedisk_abort, ioctl: idedisk_ioctl, open: idedisk_open, release: idedisk_release, media_change: idedisk_media_change, revalidate: idedisk_revalidate, pre_reset: idedisk_pre_reset, capacity: idedisk_capacity, special: idedisk_special, proc: idedisk_proc, init: idedisk_init, attach: idedisk_attach, ata_prebuilder: NULL, atapi_prebuilder: NULL,};static ide_module_t idedisk_module = { IDE_DRIVER_MODULE, idedisk_init, &idedisk_driver, NULL};MODULE_DESCRIPTION("ATA DISK Driver");int idedisk_attach (ide_drive_t *drive){ int ret = 0; MOD_INC_USE_COUNT; if (ide_register_subdriver(drive, &idedisk_driver, IDE_SUBDRIVER_VERSION)) { printk(KERN_ERR "ide-disk: %s: Failed to register the " "driver with ide.c\n", drive->name); ret= 1; goto bye_game_over; } DRIVER(drive)->busy++; idedisk_setup(drive); if ((!drive->head || drive->head > 16) && !drive->select.b.lba) { printk(KERN_ERR "%s: INVALID GEOMETRY: %d PHYSICAL HEADS?\n", drive->name, drive->head); (void) idedisk_cleanup(drive); ret= 1; } DRIVER(drive)->busy--;bye_game_over: MOD_DEC_USE_COUNT; return ret;}static void __exit idedisk_exit (void){ ide_drive_t *drive; int failed = 0; while ((drive = ide_scan_devices(ide_disk, idedisk_driver.name, &idedisk_driver, failed)) != NULL) { if (idedisk_cleanup (drive)) { printk(KERN_ERR "%s: cleanup_module() called while " "still busy\n", drive->name); failed++; }#ifdef CONFIG_PROC_FS /* We must remove proc entries defined in this module. * Otherwise we oops while accessing these entries */ if (drive->proc) ide_remove_proc_entries(drive->proc, idedisk_proc);#endif } ide_unregister_module(&idedisk_module);}int idedisk_init (void){#ifdef CLASSIC_BUILTINS_METHOD ide_drive_t *drive; int failed = 0;#endif /* CLASSIC_BUILTINS_METHOD */ MOD_INC_USE_COUNT;#ifdef CLASSIC_BUILTINS_METHOD while ((drive = ide_scan_devices(ide_disk, idedisk_driver.name, NULL, failed++)) != NULL) { if (ide_register_subdriver(drive, &idedisk_driver, IDE_SUBDRIVER_VERSION)) { printk(KERN_ERR "ide-disk: %s: Failed to register " "the driver with ide.c\n", drive->name); continue; } DRIVER(drive)->busy++; idedisk_setup(drive); if ((!drive->head || drive->head > 16) && (!drive->select.b.lba)) { printk(KERN_ERR "%s: INVALID GEOMETRY: %d " "PHYSICAL HEADS?\n", drive->name, drive->head); (void) idedisk_cleanup(drive); DRIVER(drive)->busy--; continue; } DRIVER(drive)->busy--; failed--; }#endif /* CLASSIC_BUILTINS_METHOD */ ide_register_module(&idedisk_module); MOD_DEC_USE_COUNT; return 0;}ide_startstop_t panic_box(ide_drive_t *drive){#if 0 panic("%s: Attempted to corrupt something: ide operation "#else printk(KERN_ERR "%s: Attempted to corrupt something: ide operation "#endif "was pending accross suspend/resume.\n", drive->name); return ide_stopped;}int ide_disks_busy(void){ int i; for (i=0; i<MAX_HWIFS; i++) { struct hwgroup_s *hwgroup = ide_hwifs[i].hwgroup; if (!hwgroup) continue; if ((hwgroup->handler) && (hwgroup->handler != panic_box)) return 1; } return 0;}void ide_disk_suspend(void){ int i; while (ide_disks_busy()) { printk("*"); schedule(); } for (i=0; i<MAX_HWIFS; i++) { struct hwgroup_s *hwgroup = ide_hwifs[i].hwgroup; if (!hwgroup) continue; hwgroup->handler_save = hwgroup->handler; hwgroup->handler = panic_box; } driver_blocked = 1; if (ide_disks_busy()) panic("How did you get that request through?!");}/* unsuspend and resume should be equal in the ideal world */void ide_disk_unsuspend(void){ int i; for (i=0; i<MAX_HWIFS; i++) { struct hwgroup_s *hwgroup = ide_hwifs[i].hwgroup; if (!hwgroup) continue; hwgroup->handler = NULL; /* hwgroup->handler_save; */ hwgroup->handler_save = NULL; } driver_blocked = 0;}void ide_disk_resume(void){ int i; for (i=0; i<MAX_HWIFS; i++) { struct hwgroup_s *hwgroup = ide_hwifs[i].hwgroup; if (!hwgroup) continue; if (hwgroup->handler != panic_box) panic("Handler was not set to panic?"); hwgroup->handler_save = NULL; hwgroup->handler = NULL; } driver_blocked = 0;}module_init(idedisk_init);module_exit(idedisk_exit);MODULE_LICENSE("GPL");
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -