]> www.pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - include/linux/ide.h
ide: add pointer to the current packet command to ide_drive_t
[linux-2.6-omap-h63xx.git] / include / linux / ide.h
index 1bd49784e4da41b9573ba18fbd22aad09716a413..98d29df1ee0472761729bbbbd02672a167b3f1d2 100644 (file)
@@ -133,18 +133,35 @@ struct ide_io_ports {
 /*
  * Timeouts for various operations:
  */
-#define WAIT_DRQ       (HZ/10)         /* 100msec - spec allows up to 20ms */
-#define WAIT_READY     (5*HZ)          /* 5sec - some laptops are very slow */
-#define WAIT_PIDENTIFY (10*HZ) /* 10sec  - should be less than 3ms (?), if all ATAPI CD is closed at boot */
-#define WAIT_WORSTCASE (30*HZ) /* 30sec  - worst case when spinning up */
-#define WAIT_CMD       (10*HZ) /* 10sec  - maximum wait for an IRQ to happen */
-#define WAIT_MIN_SLEEP (2*HZ/100)      /* 20msec - minimum sleep time */
+enum {
+       /* spec allows up to 20ms */
+       WAIT_DRQ        = HZ / 10,      /* 100ms */
+       /* some laptops are very slow */
+       WAIT_READY      = 5 * HZ,       /* 5s */
+       /* should be less than 3ms (?), if all ATAPI CD is closed at boot */
+       WAIT_PIDENTIFY  = 10 * HZ,      /* 10s */
+       /* worst case when spinning up */
+       WAIT_WORSTCASE  = 30 * HZ,      /* 30s */
+       /* maximum wait for an IRQ to happen */
+       WAIT_CMD        = 10 * HZ,      /* 10s */
+       /* Some drives require a longer IRQ timeout. */
+       WAIT_FLOPPY_CMD = 50 * HZ,      /* 50s */
+       /*
+        * Some drives (for example, Seagate STT3401A Travan) require a very
+        * long timeout, because they don't return an interrupt or clear their
+        * BSY bit until after the command completes (even retension commands).
+        */
+       WAIT_TAPE_CMD   = 900 * HZ,     /* 900s */
+       /* minimum sleep time */
+       WAIT_MIN_SLEEP  = HZ / 50,      /* 20ms */
+};
 
 /*
  * Op codes for special requests to be handled by ide_special_rq().
  * Values should be in the range of 0x20 to 0x3f.
  */
 #define REQ_DRIVE_RESET                0x20
+#define REQ_DEVSET_EXEC                0x21
 
 /*
  * Check for an interrupt and acknowledge the interrupt status
@@ -305,6 +322,7 @@ typedef enum {
        ide_started,    /* a drive operation was started, handler was set */
 } ide_startstop_t;
 
+struct ide_atapi_pc;
 struct ide_devset;
 struct ide_driver_s;
 
@@ -317,10 +335,10 @@ struct ide_acpi_hwif_link;
 enum {
        IDE_AFLAG_DRQ_INTERRUPT         = (1 << 0),
        IDE_AFLAG_MEDIA_CHANGED         = (1 << 1),
-
-       /* ide-cd */
        /* Drive cannot lock the door. */
        IDE_AFLAG_NO_DOORLOCK           = (1 << 2),
+
+       /* ide-cd */
        /* Drive cannot eject the disc. */
        IDE_AFLAG_NO_EJECT              = (1 << 3),
        /* Drive is a pre ATAPI 1.2 drive. */
@@ -356,21 +374,25 @@ enum {
        IDE_AFLAG_CLIK_DRIVE            = (1 << 19),
        /* Requires BH algorithm for packets */
        IDE_AFLAG_ZIP_DRIVE             = (1 << 20),
+       /* Write protect */
+       IDE_AFLAG_WP                    = (1 << 21),
+       /* Supports format progress report */
+       IDE_AFLAG_SRFP                  = (1 << 22),
 
        /* ide-tape */
-       IDE_AFLAG_IGNORE_DSC            = (1 << 21),
+       IDE_AFLAG_IGNORE_DSC            = (1 << 23),
        /* 0 When the tape position is unknown */
-       IDE_AFLAG_ADDRESS_VALID         = (1 << 22),
+       IDE_AFLAG_ADDRESS_VALID         = (1 << 24),
        /* Device already opened */
-       IDE_AFLAG_BUSY                  = (1 << 23),
+       IDE_AFLAG_BUSY                  = (1 << 25),
        /* Attempt to auto-detect the current user block size */
-       IDE_AFLAG_DETECT_BS             = (1 << 24),
+       IDE_AFLAG_DETECT_BS             = (1 << 26),
        /* Currently on a filemark */
-       IDE_AFLAG_FILEMARK              = (1 << 25),
+       IDE_AFLAG_FILEMARK              = (1 << 27),
        /* 0 = no tape is loaded, so we don't rewind after ejecting */
-       IDE_AFLAG_MEDIUM_PRESENT        = (1 << 26),
+       IDE_AFLAG_MEDIUM_PRESENT        = (1 << 28),
 
-       IDE_AFLAG_NO_AUTOCLOSE          = (1 << 27),
+       IDE_AFLAG_NO_AUTOCLOSE          = (1 << 29),
 };
 
 struct ide_drive_s {
@@ -385,7 +407,7 @@ struct ide_drive_s {
        u16                     *id;    /* identification info */
 #ifdef CONFIG_IDE_PROC_FS
        struct proc_dir_entry *proc;    /* /proc/ide/ directory entry */
-       const struct ide_devset **settings; /* /proc/ide/ drive settings */
+       const struct ide_proc_devset *settings; /* /proc/ide/ drive settings */
 #endif
        struct hwif_s           *hwif;  /* actually (ide_hwif_t *) */
 
@@ -463,8 +485,11 @@ struct ide_drive_s {
        struct device   gendev;
        struct completion gendev_rel_comp;      /* to deal with device release() */
 
+       /* current packet command */
+       struct ide_atapi_pc *pc;
+
        /* callback for packet commands */
-       void (*pc_callback)(struct ide_drive_s *);
+       void (*pc_callback)(struct ide_drive_s *, int);
 
        unsigned long atapi_flags;
 };
@@ -687,29 +712,62 @@ typedef struct ide_driver_s ide_driver_t;
 
 extern struct mutex ide_setting_mtx;
 
-int get_io_32bit(ide_drive_t *);
-int set_io_32bit(ide_drive_t *, int);
-int get_ksettings(ide_drive_t *);
-int set_ksettings(ide_drive_t *, int);
-int set_pio_mode(ide_drive_t *, int);
-int get_unmaskirq(ide_drive_t *);
-int set_unmaskirq(ide_drive_t *, int);
-int get_using_dma(ide_drive_t *);
-int set_using_dma(ide_drive_t *, int);
+/*
+ * configurable drive settings
+ */
+
+#define DS_SYNC        (1 << 0)
+
+struct ide_devset {
+       int             (*get)(ide_drive_t *);
+       int             (*set)(ide_drive_t *, int);
+       unsigned int    flags;
+};
+
+#define __DEVSET(_flags, _get, _set) { \
+       .flags  = _flags, \
+       .get    = _get, \
+       .set    = _set, \
+}
 
 #define ide_devset_get(name, field) \
-int get_##name(ide_drive_t *drive) \
+static int get_##name(ide_drive_t *drive) \
 { \
        return drive->field; \
 }
 
 #define ide_devset_set(name, field) \
-int set_##name(ide_drive_t *drive, int arg) \
+static int set_##name(ide_drive_t *drive, int arg) \
 { \
        drive->field = arg; \
        return 0; \
 }
 
+#define __IDE_DEVSET(_name, _flags, _get, _set) \
+const struct ide_devset ide_devset_##_name = \
+       __DEVSET(_flags, _get, _set)
+
+#define IDE_DEVSET(_name, _flags, _get, _set) \
+static __IDE_DEVSET(_name, _flags, _get, _set)
+
+#define ide_devset_rw(_name, _func) \
+IDE_DEVSET(_name, 0, get_##_func, set_##_func)
+
+#define ide_devset_w(_name, _func) \
+IDE_DEVSET(_name, 0, NULL, set_##_func)
+
+#define ide_devset_rw_sync(_name, _func) \
+IDE_DEVSET(_name, DS_SYNC, get_##_func, set_##_func)
+
+#define ide_decl_devset(_name) \
+extern const struct ide_devset ide_devset_##_name
+
+ide_decl_devset(io_32bit);
+ide_decl_devset(keepsettings);
+ide_decl_devset(pio_mode);
+ide_decl_devset(unmaskirq);
+ide_decl_devset(using_dma);
+
 /* ATAPI packet command flags */
 enum {
        /* set when an error is considered normal - no retry (ide-tape) */
@@ -777,60 +835,34 @@ struct ide_atapi_pc {
 
 #ifdef CONFIG_IDE_PROC_FS
 /*
- * configurable drive settings
+ * /proc/ide interface
  */
 
-#define S_READ         (1 << 0)
-#define S_WRITE                (1 << 1)
-#define S_RW           (S_READ | S_WRITE)
-#define S_NOLOCK       (1 << 2)
-
-struct ide_devset {
-       const char      *name;
-       unsigned int    flags;
-       int             min, max;
-       int             (*get)(ide_drive_t *);
-       int             (*set)(ide_drive_t *, int);
-       int             (*mulf)(ide_drive_t *);
-       int             (*divf)(ide_drive_t *);
+#define ide_devset_rw_field(_name, _field) \
+ide_devset_get(_name, _field); \
+ide_devset_set(_name, _field); \
+IDE_DEVSET(_name, DS_SYNC, get_##_name, set_##_name)
+
+struct ide_proc_devset {
+       const char              *name;
+       const struct ide_devset *setting;
+       int                     min, max;
+       int                     (*mulf)(ide_drive_t *);
+       int                     (*divf)(ide_drive_t *);
 };
 
-#define __DEVSET(_name, _flags, _min, _max, _get, _set, _mulf, _divf) { \
-       .name   = __stringify(_name), \
-       .flags  = _flags, \
-       .min    = _min, \
-       .max    = _max, \
-       .get    = _get, \
-       .set    = _set, \
-       .mulf   = _mulf, \
-       .divf   = _divf, \
+#define __IDE_PROC_DEVSET(_name, _min, _max, _mulf, _divf) { \
+       .name = __stringify(_name), \
+       .setting = &ide_devset_##_name, \
+       .min = _min, \
+       .max = _max, \
+       .mulf = _mulf, \
+       .divf = _divf, \
 }
 
-#define __IDE_DEVSET(_name, _flags, _min, _max, _get, _set, _mulf, _divf) \
-static const struct ide_devset ide_devset_##_name = \
-       __DEVSET(_name, _flags, _min, _max, _get, _set, _mulf, _divf)
-
-#define IDE_DEVSET(_name, _flags, _min, _max, _get, _set) \
-__IDE_DEVSET(_name, _flags, _min, _max, _get, _set, NULL, NULL)
+#define IDE_PROC_DEVSET(_name, _min, _max) \
+__IDE_PROC_DEVSET(_name, _min, _max, NULL, NULL)
 
-#define ide_devset_rw_nolock(_name, _min, _max, _func) \
-IDE_DEVSET(_name, S_RW | S_NOLOCK, _min, _max, get_##_func, set_##_func)
-
-#define ide_devset_w_nolock(_name, _min, _max, _func) \
-IDE_DEVSET(_name, S_WRITE | S_NOLOCK, _min, _max, NULL, set_##_func)
-
-#define ide_devset_rw(_name, _min, _max, _field) \
-static ide_devset_get(_name, _field); \
-static ide_devset_set(_name, _field); \
-IDE_DEVSET(_name, S_RW, _min, _max, get_##_name, set_##_name)
-
-#define ide_devset_r(_name, _min, _max, _field) \
-ide_devset_get(_name, _field) \
-IDE_DEVSET(_name, S_READ, _min, _max, get_##_name, NULL)
-
-/*
- * /proc/ide interface
- */
 typedef struct {
        const char      *name;
        mode_t          mode;
@@ -928,8 +960,8 @@ struct ide_driver_s {
        void            (*resume)(ide_drive_t *);
        void            (*shutdown)(ide_drive_t *);
 #ifdef CONFIG_IDE_PROC_FS
-       ide_proc_entry_t        *proc;
-       const struct ide_devset **settings;
+       ide_proc_entry_t                *proc;
+       const struct ide_proc_devset    *settings;
 #endif
 };
 
@@ -941,9 +973,7 @@ void ide_device_put(ide_drive_t *);
 struct ide_ioctl_devset {
        unsigned int    get_ioctl;
        unsigned int    set_ioctl;
-
-       int             (*get)(ide_drive_t *);
-       int             (*set)(ide_drive_t *, int);
+       const struct ide_devset *setting;
 };
 
 int ide_setting_ioctl(ide_drive_t *, struct block_device *, unsigned int,
@@ -982,6 +1012,9 @@ int ide_wait_stat(ide_startstop_t *, ide_drive_t *, u8, u8, unsigned long);
 
 extern ide_startstop_t ide_do_reset (ide_drive_t *);
 
+extern int ide_devset_execute(ide_drive_t *drive,
+                             const struct ide_devset *setting, int arg);
+
 extern void ide_do_drive_cmd(ide_drive_t *, struct request *);
 
 extern void ide_end_drive_cmd(ide_drive_t *, u8, u8);
@@ -1136,16 +1169,21 @@ enum {
 
 void ide_queue_pc_head(ide_drive_t *, struct gendisk *, struct ide_atapi_pc *,
                       struct request *);
+int ide_queue_pc_tail(ide_drive_t *, struct gendisk *, struct ide_atapi_pc *);
+
+int ide_do_test_unit_ready(ide_drive_t *, struct gendisk *);
+int ide_do_start_stop(ide_drive_t *, struct gendisk *, int);
+int ide_set_media_lock(ide_drive_t *, struct gendisk *, int);
 
-ide_startstop_t ide_pc_intr(ide_drive_t *drive, struct ide_atapi_pc *pc,
+ide_startstop_t ide_pc_intr(ide_drive_t *drive,
        ide_handler_t *handler, unsigned int timeout, ide_expiry_t *expiry,
        void (*update_buffers)(ide_drive_t *, struct ide_atapi_pc *),
-       void (*retry_pc)(ide_drive_t *), void (*dsc_handle)(ide_drive_t *),
+       void (*retry_pc)(ide_drive_t *),
        int (*io_buffers)(ide_drive_t *, struct ide_atapi_pc *, unsigned int,
                           int));
-ide_startstop_t ide_transfer_pc(ide_drive_t *, struct ide_atapi_pc *,
+ide_startstop_t ide_transfer_pc(ide_drive_t *,
                                ide_handler_t *, unsigned int, ide_expiry_t *);
-ide_startstop_t ide_issue_pc(ide_drive_t *, struct ide_atapi_pc *,
+ide_startstop_t ide_issue_pc(ide_drive_t *,
                             ide_handler_t *, unsigned int, ide_expiry_t *);
 
 ide_startstop_t do_rw_taskfile(ide_drive_t *, ide_task_t *);
@@ -1166,7 +1204,6 @@ extern int ide_wait_not_busy(ide_hwif_t *hwif, unsigned long timeout);
 
 extern void ide_stall_queue(ide_drive_t *drive, unsigned long timeout);
 
-extern int ide_spin_wait_hwgroup(ide_drive_t *);
 extern void ide_timer_expiry(unsigned long);
 extern irqreturn_t ide_intr(int irq, void *dev_id);
 extern void do_ide_request(struct request_queue *);