#include <linux/delay.h>
#include <linux/mutex.h>
#include <linux/leds.h>
-
-#define _IDE_DISK
-
#include <linux/ide.h>
+#include <linux/hdreg.h>
#include <asm/byteorder.h>
#include <asm/irq.h>
*/
static int lba_capacity_is_ok(u16 *id)
{
- struct hd_driveid *driveid = (struct hd_driveid *)id;
unsigned long lba_sects, chs_sects, head, tail;
/* No non-LBA info .. so valid! */
if (id[ATA_ID_CYLS] == 0)
return 1;
+ lba_sects = ata_id_u32(id, ATA_ID_LBA_CAPACITY);
+
/*
* The ATA spec tells large drives to return
* C/H/S = 16383/16/63 independent of their size.
(id[ATA_ID_CYLS] == 4092 && id[ATA_ID_CUR_CYLS] == 16383)) &&
id[ATA_ID_SECTORS] == 63 &&
(id[ATA_ID_HEADS] == 15 || id[ATA_ID_HEADS] == 16) &&
- (driveid->lba_capacity >= 16383 * 63 * id[ATA_ID_HEADS]))
+ (lba_sects >= 16383 * 63 * id[ATA_ID_HEADS]))
return 1;
- lba_sects = driveid->lba_capacity;
chs_sects = id[ATA_ID_CYLS] * id[ATA_ID_HEADS] * id[ATA_ID_SECTORS];
/* perform a rough sanity check on lba_sects: within 10% is OK */
tail = (lba_sects & 0xffff);
lba_sects = (head | (tail << 16));
if ((lba_sects - chs_sects) < chs_sects/10) {
- driveid->lba_capacity = lba_sects;
+ *(__le32 *)&id[ATA_ID_LBA_CAPACITY] = __cpu_to_le32(lba_sects);
return 1; /* lba_capacity is (now) good */
}
}
static const u8 ide_rw_cmds[] = {
- WIN_MULTREAD,
- WIN_MULTWRITE,
- WIN_MULTREAD_EXT,
- WIN_MULTWRITE_EXT,
- WIN_READ,
- WIN_WRITE,
- WIN_READ_EXT,
- WIN_WRITE_EXT,
- WIN_READDMA,
- WIN_WRITEDMA,
- WIN_READDMA_EXT,
- WIN_WRITEDMA_EXT,
+ ATA_CMD_READ_MULTI,
+ ATA_CMD_WRITE_MULTI,
+ ATA_CMD_READ_MULTI_EXT,
+ ATA_CMD_WRITE_MULTI_EXT,
+ ATA_CMD_PIO_READ,
+ ATA_CMD_PIO_WRITE,
+ ATA_CMD_PIO_READ_EXT,
+ ATA_CMD_PIO_WRITE_EXT,
+ ATA_CMD_READ,
+ ATA_CMD_WRITE,
+ ATA_CMD_READ_EXT,
+ ATA_CMD_WRITE_EXT,
};
static const u8 ide_data_phases[] = {
/* Create IDE/ATA command request structure */
memset(&args, 0, sizeof(ide_task_t));
if (lba48)
- tf->command = WIN_READ_NATIVE_MAX_EXT;
+ tf->command = ATA_CMD_READ_NATIVE_MAX_EXT;
else
- tf->command = WIN_READ_NATIVE_MAX;
+ tf->command = ATA_CMD_READ_NATIVE_MAX;
tf->device = ATA_LBA;
args.tf_flags = IDE_TFLAG_TF | IDE_TFLAG_DEVICE;
if (lba48)
tf->hob_lbal = (addr_req >>= 8) & 0xff;
tf->hob_lbam = (addr_req >>= 8) & 0xff;
tf->hob_lbah = (addr_req >>= 8) & 0xff;
- tf->command = WIN_SET_MAX_EXT;
+ tf->command = ATA_CMD_SET_MAX_EXT;
} else {
tf->device = (addr_req >>= 8) & 0x0f;
- tf->command = WIN_SET_MAX;
+ tf->command = ATA_CMD_SET_MAX;
}
tf->device |= ATA_LBA;
args.tf_flags = IDE_TFLAG_TF | IDE_TFLAG_DEVICE;
}
/*
- * Bits 10 of command_set_1 and cfs_enable_1 must be equal,
- * so on non-buggy drives we need test only one.
- * However, we should also check whether these fields are valid.
- */
-static inline int idedisk_supports_hpa(const u16 *id)
-{
- return (id[ATA_ID_COMMAND_SET_1] & 0x0400) &&
- (id[ATA_ID_CFS_ENABLE_1] & 0x0400);
-}
-
-/*
* The same here.
*/
static inline int idedisk_supports_lba48(const u16 *id)
{
return (id[ATA_ID_COMMAND_SET_2] & 0x0400) &&
(id[ATA_ID_CFS_ENABLE_2] & 0x0400) &&
- ((struct hd_driveid *)id)->lba_capacity_2;
+ ata_id_u64(id, ATA_ID_LBA_CAPACITY_2);
}
/*
static void init_idedisk_capacity(ide_drive_t *drive)
{
- struct hd_driveid *driveid = drive->driveid;
u16 *id = drive->id;
/*
* If this drive supports the Host Protected Area feature set,
* then we may need to change our opinion about the drive's capacity.
*/
- int hpa = idedisk_supports_hpa(id);
+ int hpa = ata_id_hpa_enabled(id);
if (idedisk_supports_lba48(id)) {
/* drive speaks 48-bit LBA */
drive->select.b.lba = 1;
- drive->capacity64 = driveid->lba_capacity_2;
+ drive->capacity64 = ata_id_u64(id, ATA_ID_LBA_CAPACITY_2);
if (hpa)
idedisk_check_hpa(drive);
- } else if ((driveid->capability & 2) && lba_capacity_is_ok(id)) {
+ } else if (ata_id_has_lba(id) && lba_capacity_is_ok(id)) {
/* drive speaks 28-bit LBA */
drive->select.b.lba = 1;
- drive->capacity64 = driveid->lba_capacity;
+ drive->capacity64 = ata_id_u32(id, ATA_ID_LBA_CAPACITY);
if (hpa)
idedisk_check_hpa(drive);
} else {
static sector_t idedisk_capacity(ide_drive_t *drive)
{
- return drive->capacity64 - drive->sect0;
+ return drive->capacity64;
}
#ifdef CONFIG_IDE_PROC_FS
struct ide_taskfile *tf = &args.tf;
memset(&args, 0, sizeof(ide_task_t));
- tf->feature = SMART_ENABLE;
- tf->lbam = SMART_LCYL_PASS;
- tf->lbah = SMART_HCYL_PASS;
- tf->command = WIN_SMART;
+ 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);
}
memset(&args, 0, sizeof(ide_task_t));
tf->feature = sub_cmd;
tf->nsect = 0x01;
- tf->lbam = SMART_LCYL_PASS;
- tf->lbah = SMART_HCYL_PASS;
- tf->command = WIN_SMART;
+ 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);
if (get_smart_data(drive, page, sub_cmd) == 0) {
unsigned short *val = (unsigned short *) page;
- char *out = ((char *)val) + (SECTOR_WORDS * 4);
+ 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_WORDS * 2));
+ } while (i < SECTOR_SIZE / 2);
len = out - page;
}
(char *page, char **start, off_t off, int count, int *eof, void *data)
{
return proc_idedisk_read_smart(page, start, off, count, eof, data,
- SMART_READ_VALUES);
+ ATA_SMART_READ_VALUES);
}
static int proc_idedisk_read_st
(char *page, char **start, off_t off, int count, int *eof, void *data)
{
return proc_idedisk_read_smart(page, start, off, count, eof, data,
- SMART_READ_THRESHOLDS);
+ ATA_SMART_READ_THRESHOLDS);
}
static ide_proc_entry_t idedisk_proc[] = {
memset(task, 0, sizeof(*task));
if (ide_id_has_flush_cache_ext(drive->id) &&
(drive->capacity64 >= (1UL << 28)))
- task->tf.command = WIN_FLUSH_CACHE_EXT;
+ task->tf.command = ATA_CMD_FLUSH_EXT;
else
- task->tf.command = WIN_FLUSH_CACHE;
+ task->tf.command = ATA_CMD_FLUSH;
task->tf_flags = IDE_TFLAG_OUT_TF | IDE_TFLAG_OUT_DEVICE |
IDE_TFLAG_DYN;
task->data_phase = TASKFILE_NO_DATA;
rq->special = task;
}
+ide_devset_get(multcount, mult_count);
+
/*
* This is tightly woven into the driver->do_special can not touch.
* DON'T do it again until a total personality rewrite is committed.
struct request *rq;
int error;
- if (arg < 0 || arg > drive->driveid->max_multsect)
+ if (arg < 0 || arg > (drive->id[ATA_ID_MAX_MULTSECT] & 0xff))
return -EINVAL;
if (drive->special.b.set_multmode)
return (drive->mult_count == arg) ? 0 : -EIO;
}
+ide_devset_get(nowerr, nowerr);
+
static int set_nowerr(ide_drive_t *drive, int arg)
{
if (arg < 0 || arg > 1)
blk_queue_ordered(drive->queue, ordered, prep_fn);
}
-static int write_cache(ide_drive_t *drive, int arg)
+ide_devset_get(wcache, wcache);
+
+static int set_wcache(ide_drive_t *drive, int arg)
{
ide_task_t args;
int err = 1;
if (ide_id_has_flush_cache(drive->id)) {
memset(&args, 0, sizeof(ide_task_t));
args.tf.feature = arg ?
- SETFEATURES_EN_WCACHE : SETFEATURES_DIS_WCACHE;
- args.tf.command = WIN_SETFEATURES;
+ SETFEATURES_WC_ON : SETFEATURES_WC_OFF;
+ args.tf.command = ATA_CMD_SET_FEATURES;
args.tf_flags = IDE_TFLAG_TF | IDE_TFLAG_DEVICE;
err = ide_no_data_taskfile(drive, &args);
if (err == 0)
memset(&args, 0, sizeof(ide_task_t));
if (ide_id_has_flush_cache_ext(drive->id))
- args.tf.command = WIN_FLUSH_CACHE_EXT;
+ args.tf.command = ATA_CMD_FLUSH_EXT;
else
- args.tf.command = WIN_FLUSH_CACHE;
+ args.tf.command = ATA_CMD_FLUSH;
args.tf_flags = IDE_TFLAG_TF | IDE_TFLAG_DEVICE;
return ide_no_data_taskfile(drive, &args);
}
+ide_devset_get(acoustic, acoustic);
+
static int set_acoustic(ide_drive_t *drive, int arg)
{
ide_task_t args;
return -EINVAL;
memset(&args, 0, sizeof(ide_task_t));
- args.tf.feature = arg ? SETFEATURES_EN_AAM : SETFEATURES_DIS_AAM;
+ args.tf.feature = arg ? SETFEATURES_AAM_ON : SETFEATURES_AAM_OFF;
args.tf.nsect = arg;
- args.tf.command = WIN_SETFEATURES;
+ args.tf.command = ATA_CMD_SET_FEATURES;
args.tf_flags = IDE_TFLAG_TF | IDE_TFLAG_DEVICE;
ide_no_data_taskfile(drive, &args);
drive->acoustic = arg;
return 0;
}
+ide_devset_get(lba_addressing, addressing);
+
/*
* drive->addressing:
* 0: 28-bit
}
#ifdef CONFIG_IDE_PROC_FS
-static void idedisk_add_settings(ide_drive_t *drive)
-{
- ide_add_setting(drive, "bios_cyl", SETTING_RW, TYPE_INT, 0, 65535, 1, 1,
- &drive->bios_cyl, NULL);
- ide_add_setting(drive, "bios_head", SETTING_RW, TYPE_BYTE, 0, 255, 1, 1,
- &drive->bios_head, NULL);
- ide_add_setting(drive, "bios_sect", SETTING_RW, TYPE_BYTE, 0, 63, 1, 1,
- &drive->bios_sect, NULL);
- ide_add_setting(drive, "address", SETTING_RW, TYPE_BYTE, 0, 2, 1, 1,
- &drive->addressing, set_lba_addressing);
- ide_add_setting(drive, "multcount", SETTING_RW, TYPE_BYTE, 0,
- drive->driveid->max_multsect, 1, 1, &drive->mult_count,
- set_multcount);
- ide_add_setting(drive, "nowerr", SETTING_RW, TYPE_BYTE, 0, 1, 1, 1,
- &drive->nowerr, set_nowerr);
- ide_add_setting(drive, "lun", SETTING_RW, TYPE_INT, 0, 7, 1, 1,
- &drive->lun, NULL);
- ide_add_setting(drive, "wcache", SETTING_RW, TYPE_BYTE, 0, 1, 1, 1,
- &drive->wcache, write_cache);
- ide_add_setting(drive, "acoustic", SETTING_RW, TYPE_BYTE, 0, 254, 1, 1,
- &drive->acoustic, set_acoustic);
- ide_add_setting(drive, "failures", SETTING_RW, TYPE_INT, 0, 65535, 1, 1,
- &drive->failures, NULL);
- ide_add_setting(drive, "max_failures", SETTING_RW, TYPE_INT, 0, 65535,
- 1, 1, &drive->max_failures, NULL);
-}
-#else
-static inline void idedisk_add_settings(ide_drive_t *drive) { ; }
+ide_devset_rw_nolock(acoustic, 0, 254, acoustic);
+ide_devset_rw_nolock(address, 0, 2, lba_addressing);
+ide_devset_rw_nolock(multcount, 0, 16, multcount);
+ide_devset_rw_nolock(nowerr, 0, 1, nowerr);
+ide_devset_rw_nolock(wcache, 0, 1, wcache);
+
+ide_devset_rw(bios_cyl, 0, 65535, bios_cyl);
+ide_devset_rw(bios_head, 0, 255, bios_head);
+ide_devset_rw(bios_sect, 0, 63, bios_sect);
+ide_devset_rw(failures, 0, 65535, failures);
+ide_devset_rw(lun, 0, 7, lun);
+ide_devset_rw(max_failures, 0, 65535, max_failures);
+
+static const struct ide_devset *idedisk_settings[] = {
+ &ide_devset_acoustic,
+ &ide_devset_address,
+ &ide_devset_bios_cyl,
+ &ide_devset_bios_head,
+ &ide_devset_bios_sect,
+ &ide_devset_failures,
+ &ide_devset_lun,
+ &ide_devset_max_failures,
+ &ide_devset_multcount,
+ &ide_devset_nowerr,
+ &ide_devset_wcache,
+ NULL
+};
#endif
static void idedisk_setup(ide_drive_t *drive)
{
+ struct ide_disk_obj *idkp = drive->driver_data;
ide_hwif_t *hwif = drive->hwif;
u16 *id = drive->id;
char *m = (char *)&id[ATA_ID_PROD];
unsigned long long capacity;
- idedisk_add_settings(drive);
+ ide_proc_register_driver(drive, idkp->driver);
if (drive->id_read == 0)
return;
drive->bios_cyl, drive->bios_head, drive->bios_sect);
/* write cache enabled? */
- if ((id[ATA_ID_CSFO] & 1) || (id[ATA_ID_CFS_ENABLE_1] & (1 << 5)))
+ if ((id[ATA_ID_CSFO] & 1) || ata_id_wcache_enabled(id))
drive->wcache = 1;
- write_cache(drive, 1);
+ set_wcache(drive, 1);
}
static void ide_cacheflush_p(ide_drive_t *drive)
*/
static void ide_disk_resume(ide_drive_t *drive)
{
- if (idedisk_supports_hpa(drive->id))
+ if (ata_id_hpa_enabled(drive->id))
init_idedisk_capacity(drive);
}
.shutdown = ide_device_shutdown,
.version = IDEDISK_VERSION,
.media = ide_disk,
- .supports_dsc_overlap = 0,
.do_request = ide_do_rw_disk,
.end_request = ide_end_request,
.error = __ide_error,
#ifdef CONFIG_IDE_PROC_FS
.proc = idedisk_proc,
+ .settings = idedisk_settings,
#endif
};
ide_task_t task;
memset(&task, 0, sizeof(task));
- task.tf.command = on ? WIN_DOORLOCK : WIN_DOORUNLOCK;
+ task.tf.command = on ? ATA_CMD_MEDIA_LOCK : ATA_CMD_MEDIA_UNLOCK;
task.tf_flags = IDE_TFLAG_TF | IDE_TFLAG_DEVICE;
return ide_no_data_taskfile(drive, &task);
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, (*setfunc)(ide_drive_t *, int);
- u8 *val;
+ int err, (*getfunc)(ide_drive_t *), (*setfunc)(ide_drive_t *, int);
switch (cmd) {
- case HDIO_GET_ADDRESS: val = &drive->addressing; goto read_val;
- case HDIO_GET_MULTCOUNT: val = &drive->mult_count; goto read_val;
- case HDIO_GET_NOWERR: val = &drive->nowerr; goto read_val;
- case HDIO_GET_WCACHE: val = &drive->wcache; goto read_val;
- case HDIO_GET_ACOUSTIC: val = &drive->acoustic; goto read_val;
+ case HDIO_GET_ADDRESS: getfunc = get_lba_addressing; goto read_val;
+ case HDIO_GET_MULTCOUNT: getfunc = get_multcount; goto read_val;
+ case HDIO_GET_NOWERR: getfunc = get_nowerr; goto read_val;
+ case HDIO_GET_WCACHE: getfunc = get_wcache; goto read_val;
+ case HDIO_GET_ACOUSTIC: getfunc = get_acoustic; goto read_val;
case HDIO_SET_ADDRESS: setfunc = set_lba_addressing; goto set_val;
case HDIO_SET_MULTCOUNT: setfunc = set_multcount; goto set_val;
case HDIO_SET_NOWERR: setfunc = set_nowerr; goto set_val;
- case HDIO_SET_WCACHE: setfunc = write_cache; goto set_val;
+ case HDIO_SET_WCACHE: setfunc = set_wcache; goto set_val;
case HDIO_SET_ACOUSTIC: setfunc = set_acoustic; goto set_val;
}
read_val:
mutex_lock(&ide_setting_mtx);
spin_lock_irqsave(&ide_lock, flags);
- err = *val;
+ err = getfunc(drive);
spin_unlock_irqrestore(&ide_lock, flags);
mutex_unlock(&ide_setting_mtx);
return err >= 0 ? put_user(err, (long __user *)arg) : err;
/* strstr("foo", "") is non-NULL */
if (!strstr("ide-disk", drive->driver_req))
goto failed;
- if (!drive->present)
- goto failed;
+
if (drive->media != ide_disk)
goto failed;
ide_init_disk(g, drive);
- ide_proc_register_driver(drive, &idedisk_driver);
-
kref_init(&idkp->kref);
idkp->drive = drive;