ide: remove ->supports_dsc_overlap field from ide_driver_t
[safe/jmp/linux-2.6] / drivers / ide / ide-disk.c
index f1669bc..08f47cb 100644 (file)
 #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>
@@ -101,13 +99,14 @@ static void ide_disk_put(struct ide_disk_obj *idkp)
  */
 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.
@@ -118,10 +117,9 @@ static int lba_capacity_is_ok(u16 *id)
             (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 */
@@ -133,7 +131,7 @@ static int lba_capacity_is_ok(u16 *id)
        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 */
        }
 
@@ -141,18 +139,18 @@ static int lba_capacity_is_ok(u16 *id)
 }
 
 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[] = {
@@ -323,9 +321,9 @@ static u64 idedisk_read_native_max_address(ide_drive_t *drive, int lba48)
        /* 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)
@@ -360,10 +358,10 @@ static u64 idedisk_set_max_address(ide_drive_t *drive, u64 addr_req, int 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;
@@ -386,24 +384,13 @@ static unsigned long long sectors_to_MB(unsigned long long n)
 }
 
 /*
- * 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);
 }
 
 /*
@@ -456,24 +443,23 @@ static void idedisk_check_hpa(ide_drive_t *drive)
 
 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 {
@@ -484,7 +470,7 @@ static void init_idedisk_capacity(ide_drive_t *drive)
 
 static sector_t idedisk_capacity(ide_drive_t *drive)
 {
-       return drive->capacity64 - drive->sect0;
+       return drive->capacity64;
 }
 
 #ifdef CONFIG_IDE_PROC_FS
@@ -494,10 +480,10 @@ static int smart_enable(ide_drive_t *drive)
        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);
 }
@@ -510,9 +496,9 @@ static int get_smart_data(ide_drive_t *drive, u8 *buf, u8 sub_cmd)
        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);
@@ -553,13 +539,14 @@ static int proc_idedisk_read_smart(char *page, char **start, off_t off,
 
        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;
        }
 
@@ -570,14 +557,14 @@ 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,
-                                      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[] = {
@@ -601,9 +588,9 @@ static void idedisk_prepare_flush(struct request_queue *q, struct request *rq)
        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;
@@ -613,6 +600,8 @@ static void idedisk_prepare_flush(struct request_queue *q, struct request *rq)
        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.
@@ -622,7 +611,7 @@ static int set_multcount(ide_drive_t *drive, int arg)
        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)
@@ -639,6 +628,8 @@ static int set_multcount(ide_drive_t *drive, int arg)
        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)
@@ -687,7 +678,9 @@ static void update_ordered(ide_drive_t *drive)
        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;
@@ -698,8 +691,8 @@ static int write_cache(ide_drive_t *drive, int arg)
        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)
@@ -717,13 +710,15 @@ static int do_idedisk_flushcache(ide_drive_t *drive)
 
        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;
@@ -732,15 +727,17 @@ static int set_acoustic(ide_drive_t *drive, int arg)
                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
@@ -764,44 +761,44 @@ static int set_lba_addressing(ide_drive_t *drive, int arg)
 }
 
 #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;
@@ -890,10 +887,10 @@ static void idedisk_setup(ide_drive_t *drive)
                         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)
@@ -940,7 +937,7 @@ static int ide_disk_probe(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);
 }
 
@@ -983,12 +980,12 @@ static ide_driver_t idedisk_driver = {
        .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
 };
 
@@ -997,7 +994,7 @@ static int idedisk_set_doorlock(ide_drive_t *drive, int on)
        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);
@@ -1069,19 +1066,18 @@ static int idedisk_ioctl(struct inode *inode, struct file *file,
        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;
        }
 
@@ -1090,7 +1086,7 @@ static int idedisk_ioctl(struct inode *inode, struct file *file,
 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;
@@ -1151,8 +1147,7 @@ static int ide_disk_probe(ide_drive_t *drive)
        /* 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;
 
@@ -1166,8 +1161,6 @@ static int ide_disk_probe(ide_drive_t *drive)
 
        ide_init_disk(g, drive);
 
-       ide_proc_register_driver(drive, &idedisk_driver);
-
        kref_init(&idkp->kref);
 
        idkp->drive = drive;