/*
* linux/drivers/ide/ide-disk.c Version 1.18 Mar 05, 2003
*
* Copyright (C) 1994-1998 Linus Torvalds & authors (see below)
* Copyright (C) 1998-2002 Linux ATA Development
* Andre Hedrick <andre@linux-ide.org>
* Copyright (C) 2003 Red Hat <alan@redhat.com>
*/
/*
* Mostly written by Mark Lord <mlord@pobox.com>
* and Gadi Oxman <gadio@netvision.net.il>
* and Andre Hedrick <andre@linux-ide.org>
*
* This is the IDE/ATA disk driver, as evolved from hd.c and ide.c.
*/
#define IDEDISK_VERSION "1.18"
//#define DEBUG
#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/slab.h>
#include <linux/delay.h>
#include <linux/mutex.h>
#include <linux/leds.h>
#define _IDE_DISK
#include <linux/ide.h>
#include <asm/byteorder.h>
#include <asm/irq.h>
#include <asm/uaccess.h>
#include <asm/io.h>
#include <asm/div64.h>
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 */
};
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 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);
if (idkp)
kref_get(&idkp->kref);
mutex_unlock(&idedisk_ref_mutex);
return idkp;
}
static void ide_disk_release(struct kref *);
static void ide_disk_put(struct ide_disk_obj *idkp)
{
mutex_lock(&idedisk_ref_mutex);
kref_put(&idkp->kref, ide_disk_release);
mutex_unlock(&idedisk_ref_mutex);
}
/*
* 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
*
* It is called only once for each drive.
*/
static int lba_capacity_is_ok (struct hd_driveid *id)
{
unsigned long lba_sects, chs_sects, head, tail;
/* No non-LBA info .. so valid! */
if (id->cyls == 0)
return 1;
/*
* The ATA spec tells large drives to return
* C/H/S = 16383/16/63 independent of their size.
* Some drives can be jumpered to use 15 heads instead of 16.
* Some drives can be jumpered to use 4092 cyls instead of 16383.
*/
if ((id->cyls == 16383
|| (id->cyls == 4092 && id->cur_cyls == 16383)) &&
id->sectors == 63 &&
(id->heads == 15 || id->heads == 16) &&
(id->lba_capacity >= 16383*63*id->heads))
return 1;
lba_sects = id->lba_capacity;
chs_sects = id->cyls * id->heads * id->sectors;
/* perform a rough sanity check on lba_sects: within 10% is OK */
if ((lba_sects - chs_sects) < chs_sects/10)
return 1;
/* some drives have the word order reversed */
head = ((lba_sects >> 16) & 0xffff);
tail = (lba_sects & 0xffff);
lba_sects = (head | (tail << 16));
if ((lba_sects - chs_sects) < chs_sects/10) {
id->lba_capacity = lba_sects;
return