static int ide_gd_ioctl(struct block_device *bdev, fmode_t mode, unsigned int cmd, unsigned long arg) { struct ide_disk_obj *idkp = ide_drv_g(bdev->bd_disk, ide_disk_obj); ide_drive_t *drive = idkp->drive; return drive->disk_ops->ioctl(drive, bdev, mode, cmd, arg); }
static void ide_gd_unlock_native_capacity(struct gendisk *disk) { struct ide_disk_obj *idkp = ide_drv_g(disk, ide_disk_obj); ide_drive_t *drive = idkp->drive; const struct ide_disk_ops *disk_ops = drive->disk_ops; if (disk_ops->unlock_native_capacity) disk_ops->unlock_native_capacity(drive); }
static int ide_gd_getgeo(struct block_device *bdev, struct hd_geometry *geo) { 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; geo->sectors = drive->bios_sect; geo->cylinders = (u16)drive->bios_cyl; /* truncate */ return 0; }
static int ide_gd_revalidate_disk(struct gendisk *disk) { struct ide_disk_obj *idkp = ide_drv_g(disk, ide_disk_obj); ide_drive_t *drive = idkp->drive; if (ide_gd_media_changed(disk)) drive->disk_ops->get_capacity(drive); set_capacity(disk, ide_gd_capacity(drive)); return 0; }
static unsigned long long ide_gd_set_capacity(struct gendisk *disk, unsigned long long capacity) { struct ide_disk_obj *idkp = ide_drv_g(disk, ide_disk_obj); ide_drive_t *drive = idkp->drive; const struct ide_disk_ops *disk_ops = drive->disk_ops; if (disk_ops->set_capacity) return disk_ops->set_capacity(drive, capacity); return drive->capacity64; }
static struct ide_disk_obj *ide_disk_get(struct gendisk *disk) { struct ide_disk_obj *idkp = NULL; mutex_lock(&ide_disk_ref_mutex); idkp = ide_drv_g(disk, ide_disk_obj); if (idkp) { if (ide_device_get(idkp->drive)) idkp = NULL; else kref_get(&idkp->kref); } mutex_unlock(&ide_disk_ref_mutex); return idkp; }
static struct cdrom_info *ide_cd_get(struct gendisk *disk) { struct cdrom_info *cd = NULL; mutex_lock(&idecd_ref_mutex); cd = ide_drv_g(disk, cdrom_info); if (cd) { if (ide_device_get(cd->drive)) cd = NULL; else get_device(&cd->dev); } mutex_unlock(&idecd_ref_mutex); return cd; }
static int ide_gd_media_changed(struct gendisk *disk) { struct ide_disk_obj *idkp = ide_drv_g(disk, ide_disk_obj); ide_drive_t *drive = idkp->drive; int ret; /* do not scan partitions twice if this is a removable device */ if (drive->dev_flags & IDE_DFLAG_ATTACH) { drive->dev_flags &= ~IDE_DFLAG_ATTACH; return 0; } ret = !!(drive->dev_flags & IDE_DFLAG_MEDIA_CHANGED); drive->dev_flags &= ~IDE_DFLAG_MEDIA_CHANGED; return ret; }
static int ide_gd_media_changed(struct gendisk *disk) { struct ide_disk_obj *idkp = ide_drv_g(disk, ide_disk_obj); ide_drive_t *drive = idkp->drive; int ret; if (drive->dev_flags & IDE_DFLAG_ATTACH) { drive->dev_flags &= ~IDE_DFLAG_ATTACH; return 0; } ret = !!(drive->dev_flags & IDE_DFLAG_MEDIA_CHANGED); drive->dev_flags &= ~IDE_DFLAG_MEDIA_CHANGED; return ret; }
static unsigned int ide_gd_check_events(struct gendisk *disk, unsigned int clearing) { struct ide_disk_obj *idkp = ide_drv_g(disk, ide_disk_obj); ide_drive_t *drive = idkp->drive; bool ret; if (drive->dev_flags & IDE_DFLAG_ATTACH) { drive->dev_flags &= ~IDE_DFLAG_ATTACH; return 0; } ret = drive->dev_flags & IDE_DFLAG_MEDIA_CHANGED; drive->dev_flags &= ~IDE_DFLAG_MEDIA_CHANGED; return ret ? DISK_EVENT_MEDIA_CHANGE : 0; }
static int ide_gd_release(struct gendisk *disk, fmode_t mode) { struct ide_disk_obj *idkp = ide_drv_g(disk, ide_disk_obj); ide_drive_t *drive = idkp->drive; ide_debug_log(IDE_DBG_FUNC, "Call %s\n", __func__); if (idkp->openers == 1) drive->disk_ops->flush(drive); if ((drive->dev_flags & IDE_DFLAG_REMOVABLE) && idkp->openers == 1) { drive->disk_ops->set_doorlock(drive, disk, 0); drive->dev_flags &= ~IDE_DFLAG_FORMAT_IN_PROGRESS; } idkp->openers--; ide_disk_put(idkp); return 0; }
static unsigned int ide_gd_check_events(struct gendisk *disk, unsigned int clearing) { struct ide_disk_obj *idkp = ide_drv_g(disk, ide_disk_obj); ide_drive_t *drive = idkp->drive; bool ret; /* do not scan partitions twice if this is a removable device */ if (drive->dev_flags & IDE_DFLAG_ATTACH) { drive->dev_flags &= ~IDE_DFLAG_ATTACH; return 0; } /* * The following is used to force revalidation on the first open on * removeable devices, and never gets reported to userland as * genhd->events is 0. This is intended as removeable ide disk * can't really detect MEDIA_CHANGE events. */ ret = drive->dev_flags & IDE_DFLAG_MEDIA_CHANGED; drive->dev_flags &= ~IDE_DFLAG_MEDIA_CHANGED; return ret ? DISK_EVENT_MEDIA_CHANGE : 0; }