#define IDE_DISK_MINORS 0
#endif
-struct ide_disk_obj {
- ide_drive_t *drive;
- ide_driver_t *driver;
- struct gendisk *disk;
- struct kref kref;
- unsigned int openers; /* protected by BKL for now */
-};
+#include "ide-disk.h"
static DEFINE_MUTEX(idedisk_ref_mutex);
-#define to_ide_disk(obj) container_of(obj, struct ide_disk_obj, kref)
-
-#define ide_disk_g(disk) \
- container_of((disk)->private_data, struct ide_disk_obj, driver)
-
static void ide_disk_release(struct kref *);
static struct ide_disk_obj *ide_disk_get(struct gendisk *disk)
struct ide_disk_obj *idkp = NULL;
mutex_lock(&idedisk_ref_mutex);
- idkp = ide_disk_g(disk);
+ idkp = ide_drv_g(disk, ide_disk_obj);
if (idkp) {
if (ide_device_get(idkp->drive))
idkp = NULL;
if (ata_id_hpa_enabled(id))
idedisk_check_hpa(drive);
}
-}
-
-static sector_t idedisk_capacity(ide_drive_t *drive)
-{
- return drive->capacity64;
-}
-
-#ifdef CONFIG_IDE_PROC_FS
-static int smart_enable(ide_drive_t *drive)
-{
- ide_task_t args;
- struct ide_taskfile *tf = &args.tf;
-
- memset(&args, 0, sizeof(ide_task_t));
- tf->feature = ATA_SMART_ENABLE;
- tf->lbam = ATA_SMART_LBAM_PASS;
- tf->lbah = ATA_SMART_LBAH_PASS;
- tf->command = ATA_CMD_SMART;
- args.tf_flags = IDE_TFLAG_TF | IDE_TFLAG_DEVICE;
- return ide_no_data_taskfile(drive, &args);
-}
-
-static int get_smart_data(ide_drive_t *drive, u8 *buf, u8 sub_cmd)
-{
- ide_task_t args;
- struct ide_taskfile *tf = &args.tf;
-
- memset(&args, 0, sizeof(ide_task_t));
- tf->feature = sub_cmd;
- tf->nsect = 0x01;
- tf->lbam = ATA_SMART_LBAM_PASS;
- tf->lbah = ATA_SMART_LBAH_PASS;
- tf->command = ATA_CMD_SMART;
- args.tf_flags = IDE_TFLAG_TF | IDE_TFLAG_DEVICE;
- args.data_phase = TASKFILE_IN;
- (void) smart_enable(drive);
- return ide_raw_taskfile(drive, &args, buf, 1);
-}
-
-static int proc_idedisk_read_cache
- (char *page, char **start, off_t off, int count, int *eof, void *data)
-{
- ide_drive_t *drive = (ide_drive_t *) data;
- char *out = page;
- int len;
-
- if (drive->dev_flags & IDE_DFLAG_ID_READ)
- len = sprintf(out, "%i\n", drive->id[ATA_ID_BUF_SIZE] / 2);
- else
- len = sprintf(out, "(none)\n");
- PROC_IDE_READ_RETURN(page, start, off, count, eof, len);
-}
-
-static int proc_idedisk_read_capacity
- (char *page, char **start, off_t off, int count, int *eof, void *data)
-{
- ide_drive_t*drive = (ide_drive_t *)data;
- int len;
-
- len = sprintf(page, "%llu\n", (long long)idedisk_capacity(drive));
-
- PROC_IDE_READ_RETURN(page, start, off, count, eof, len);
-}
-
-static int proc_idedisk_read_smart(char *page, char **start, off_t off,
- int count, int *eof, void *data, u8 sub_cmd)
-{
- ide_drive_t *drive = (ide_drive_t *)data;
- int len = 0, i = 0;
-
- if (get_smart_data(drive, page, sub_cmd) == 0) {
- unsigned short *val = (unsigned short *) page;
- char *out = (char *)val + SECTOR_SIZE;
-
- page = out;
- do {
- out += sprintf(out, "%04x%c", le16_to_cpu(*val),
- (++i & 7) ? ' ' : '\n');
- val += 1;
- } while (i < SECTOR_SIZE / 2);
- len = out - page;
+ /* limit drive capacity to 137GB if LBA48 cannot be used */
+ if ((drive->dev_flags & IDE_DFLAG_LBA48) == 0 &&
+ drive->capacity64 > 1ULL << 28) {
+ printk(KERN_WARNING "%s: cannot use LBA48 - full capacity "
+ "%llu sectors (%llu MB)\n",
+ drive->name, (unsigned long long)drive->capacity64,
+ sectors_to_MB(drive->capacity64));
+ drive->capacity64 = 1ULL << 28;
}
- PROC_IDE_READ_RETURN(page, start, off, count, eof, len);
-}
-
-static int proc_idedisk_read_sv
- (char *page, char **start, off_t off, int count, int *eof, void *data)
-{
- return proc_idedisk_read_smart(page, start, off, count, eof, data,
- ATA_SMART_READ_VALUES);
+ if ((drive->hwif->host_flags & IDE_HFLAG_NO_LBA48_DMA) &&
+ (drive->dev_flags & IDE_DFLAG_LBA48)) {
+ if (drive->capacity64 > 1ULL << 28) {
+ printk(KERN_INFO "%s: cannot use LBA48 DMA - PIO mode"
+ " will be used for accessing sectors "
+ "> %u\n", drive->name, 1 << 28);
+ } else
+ drive->dev_flags &= ~IDE_DFLAG_LBA48;
+ }
}
-static int proc_idedisk_read_st
- (char *page, char **start, off_t off, int count, int *eof, void *data)
+sector_t ide_disk_capacity(ide_drive_t *drive)
{
- return proc_idedisk_read_smart(page, start, off, count, eof, data,
- ATA_SMART_READ_THRESHOLDS);
+ return drive->capacity64;
}
-static ide_proc_entry_t idedisk_proc[] = {
- { "cache", S_IFREG|S_IRUGO, proc_idedisk_read_cache, NULL },
- { "capacity", S_IFREG|S_IRUGO, proc_idedisk_read_capacity, NULL },
- { "geometry", S_IFREG|S_IRUGO, proc_ide_read_geometry, NULL },
- { "smart_values", S_IFREG|S_IRUSR, proc_idedisk_read_sv, NULL },
- { "smart_thresholds", S_IFREG|S_IRUSR, proc_idedisk_read_st, NULL },
- { NULL, 0, NULL, NULL }
-};
-#endif /* CONFIG_IDE_PROC_FS */
-
static void idedisk_prepare_flush(struct request_queue *q, struct request *rq)
{
ide_drive_t *drive = q->queuedata;
* time we have trimmed the drive capacity if LBA48 is
* not available so we don't need to recheck that.
*/
- capacity = idedisk_capacity(drive);
+ capacity = ide_disk_capacity(drive);
barrier = ata_id_flush_enabled(id) &&
(drive->dev_flags & IDE_DFLAG_NOFLUSH) == 0 &&
((drive->dev_flags & IDE_DFLAG_LBA48) == 0 ||
return 0;
}
-ide_devset_rw(acoustic, acoustic);
-ide_devset_rw(address, addressing);
-ide_devset_rw(multcount, multcount);
-ide_devset_rw(wcache, wcache);
-
-ide_devset_rw_sync(nowerr, nowerr);
+ide_ext_devset_rw(acoustic, acoustic);
+ide_ext_devset_rw(address, addressing);
+ide_ext_devset_rw(multcount, multcount);
+ide_ext_devset_rw(wcache, wcache);
-#ifdef CONFIG_IDE_PROC_FS
-ide_devset_rw_field(bios_cyl, bios_cyl);
-ide_devset_rw_field(bios_head, bios_head);
-ide_devset_rw_field(bios_sect, bios_sect);
-ide_devset_rw_field(failures, failures);
-ide_devset_rw_field(lun, lun);
-ide_devset_rw_field(max_failures, max_failures);
-
-static const struct ide_proc_devset idedisk_settings[] = {
- IDE_PROC_DEVSET(acoustic, 0, 254),
- IDE_PROC_DEVSET(address, 0, 2),
- IDE_PROC_DEVSET(bios_cyl, 0, 65535),
- IDE_PROC_DEVSET(bios_head, 0, 255),
- IDE_PROC_DEVSET(bios_sect, 0, 63),
- IDE_PROC_DEVSET(failures, 0, 65535),
- IDE_PROC_DEVSET(lun, 0, 7),
- IDE_PROC_DEVSET(max_failures, 0, 65535),
- IDE_PROC_DEVSET(multcount, 0, 16),
- IDE_PROC_DEVSET(nowerr, 0, 1),
- IDE_PROC_DEVSET(wcache, 0, 1),
- { 0 },
-};
-#endif
+ide_ext_devset_rw_sync(nowerr, nowerr);
static void idedisk_setup(ide_drive_t *drive)
{
/* calculate drive capacity, and select LBA if possible */
init_idedisk_capacity(drive);
- /* limit drive capacity to 137GB if LBA48 cannot be used */
- if ((drive->dev_flags & IDE_DFLAG_LBA48) == 0 &&
- drive->capacity64 > 1ULL << 28) {
- printk(KERN_WARNING "%s: cannot use LBA48 - full capacity "
- "%llu sectors (%llu MB)\n",
- drive->name, (unsigned long long)drive->capacity64,
- sectors_to_MB(drive->capacity64));
- drive->capacity64 = 1ULL << 28;
- }
-
- if ((hwif->host_flags & IDE_HFLAG_NO_LBA48_DMA) &&
- (drive->dev_flags & IDE_DFLAG_LBA48)) {
- if (drive->capacity64 > 1ULL << 28) {
- printk(KERN_INFO "%s: cannot use LBA48 DMA - PIO mode"
- " will be used for accessing sectors "
- "> %u\n", drive->name, 1 << 28);
- } else
- drive->dev_flags &= ~IDE_DFLAG_LBA48;
- }
-
/*
* if possible, give fdisk access to more of the drive,
* by correcting bios_cyls:
*/
- capacity = idedisk_capacity(drive);
+ capacity = ide_disk_capacity(drive);
if ((drive->dev_flags & IDE_DFLAG_FORCED_GEOM) == 0) {
if (ata_id_lba48_enabled(drive->id)) {
static void ide_disk_release(struct kref *kref)
{
- struct ide_disk_obj *idkp = to_ide_disk(kref);
+ struct ide_disk_obj *idkp = to_ide_drv(kref, ide_disk_obj);
ide_drive_t *drive = idkp->drive;
struct gendisk *g = idkp->disk;
.end_request = ide_end_request,
.error = __ide_error,
#ifdef CONFIG_IDE_PROC_FS
- .proc = idedisk_proc,
- .settings = idedisk_settings,
+ .proc = ide_disk_proc,
+ .settings = ide_disk_settings,
#endif
};
idkp->openers++;
if ((drive->dev_flags & IDE_DFLAG_REMOVABLE) && idkp->openers == 1) {
- check_disk_change(inode->i_bdev);
/*
* Ignore the return code from door_lock,
* since the open() has already succeeded,
if ((drive->dev_flags & IDE_DFLAG_DOORLOCKING) &&
idedisk_set_doorlock(drive, 1))
drive->dev_flags &= ~IDE_DFLAG_DOORLOCKING;
+ check_disk_change(inode->i_bdev);
}
return 0;
}
static int idedisk_release(struct inode *inode, struct file *filp)
{
struct gendisk *disk = inode->i_bdev->bd_disk;
- struct ide_disk_obj *idkp = ide_disk_g(disk);
+ struct ide_disk_obj *idkp = ide_drv_g(disk, ide_disk_obj);
ide_drive_t *drive = idkp->drive;
if (idkp->openers == 1)
static int idedisk_getgeo(struct block_device *bdev, struct hd_geometry *geo)
{
- struct ide_disk_obj *idkp = ide_disk_g(bdev->bd_disk);
+ struct ide_disk_obj *idkp = ide_drv_g(bdev->bd_disk, ide_disk_obj);
ide_drive_t *drive = idkp->drive;
geo->heads = drive->bios_head;
return 0;
}
-static const struct ide_ioctl_devset ide_disk_ioctl_settings[] = {
-{ HDIO_GET_ADDRESS, HDIO_SET_ADDRESS, &ide_devset_address },
-{ HDIO_GET_MULTCOUNT, HDIO_SET_MULTCOUNT, &ide_devset_multcount },
-{ HDIO_GET_NOWERR, HDIO_SET_NOWERR, &ide_devset_nowerr },
-{ HDIO_GET_WCACHE, HDIO_SET_WCACHE, &ide_devset_wcache },
-{ HDIO_GET_ACOUSTIC, HDIO_SET_ACOUSTIC, &ide_devset_acoustic },
-{ 0 }
-};
-
-static int idedisk_ioctl(struct inode *inode, struct file *file,
- unsigned int cmd, unsigned long arg)
-{
- struct block_device *bdev = inode->i_bdev;
- struct ide_disk_obj *idkp = ide_disk_g(bdev->bd_disk);
- ide_drive_t *drive = idkp->drive;
- int err;
-
- err = ide_setting_ioctl(drive, bdev, cmd, arg, ide_disk_ioctl_settings);
- if (err != -EOPNOTSUPP)
- return err;
-
- return generic_ide_ioctl(drive, file, bdev, cmd, arg);
-}
-
static int idedisk_media_changed(struct gendisk *disk)
{
- struct ide_disk_obj *idkp = ide_disk_g(disk);
+ struct ide_disk_obj *idkp = ide_drv_g(disk, ide_disk_obj);
ide_drive_t *drive = idkp->drive;
/* do not scan partitions twice if this is a removable device */
static int idedisk_revalidate_disk(struct gendisk *disk)
{
- struct ide_disk_obj *idkp = ide_disk_g(disk);
- set_capacity(disk, idedisk_capacity(idkp->drive));
+ struct ide_disk_obj *idkp = ide_drv_g(disk, ide_disk_obj);
+ set_capacity(disk, ide_disk_capacity(idkp->drive));
return 0;
}
.owner = THIS_MODULE,
.open = idedisk_open,
.release = idedisk_release,
- .ioctl = idedisk_ioctl,
+ .ioctl = ide_disk_ioctl,
.getgeo = idedisk_getgeo,
.media_changed = idedisk_media_changed,
.revalidate_disk = idedisk_revalidate_disk
g->flags |= GENHD_FL_EXT_DEVT;
if (drive->dev_flags & IDE_DFLAG_REMOVABLE)
g->flags = GENHD_FL_REMOVABLE;
- set_capacity(g, idedisk_capacity(drive));
+ set_capacity(g, ide_disk_capacity(drive));
g->fops = &idedisk_ops;
add_disk(g);
return 0;
}
MODULE_ALIAS("ide:*m-disk*");
+MODULE_ALIAS("ide-disk");
module_init(idedisk_init);
module_exit(idedisk_exit);
MODULE_LICENSE("GPL");