[SCSI] scsi_dh: Update EMC handler
[safe/jmp/linux-2.6] / include / scsi / scsi_host.h
index 916144b..d3b1e06 100644 (file)
@@ -5,8 +5,12 @@
 #include <linux/list.h>
 #include <linux/types.h>
 #include <linux/workqueue.h>
+#include <linux/mutex.h>
+#include <scsi/scsi.h>
 
+struct request_queue;
 struct block_device;
+struct completion;
 struct module;
 struct scsi_cmnd;
 struct scsi_device;
@@ -14,6 +18,7 @@ struct scsi_target;
 struct Scsi_Host;
 struct scsi_host_cmd_pool;
 struct scsi_transport_template;
+struct blk_queue_tags;
 
 
 /*
@@ -21,13 +26,19 @@ struct scsi_transport_template;
  * NONE: Self evident. Host adapter is not capable of scatter-gather.
  * ALL:         Means that the host adapter module can do scatter-gather,
  *      and that there is no limit to the size of the table to which
- *      we scatter/gather data.
+ *      we scatter/gather data.  The value we set here is the maximum
+ *      single element sglist.  To use chained sglists, the adapter
+ *      has to set a value beyond ALL (and correctly use the chain
+ *      handling API.
  * Anything else:  Indicates the maximum number of chains that can be
  *      used in one scatter-gather request.
  */
 #define SG_NONE 0
-#define SG_ALL 0xff
+#define SG_ALL SCSI_MAX_SG_SEGMENTS
 
+#define MODE_UNKNOWN 0x00
+#define MODE_INITIATOR 0x01
+#define MODE_TARGET 0x02
 
 #define DISABLE_CLUSTERING 0
 #define ENABLE_CLUSTERING 1
@@ -121,6 +132,27 @@ struct scsi_host_template {
                             void (*done)(struct scsi_cmnd *));
 
        /*
+        * The transfer functions are used to queue a scsi command to
+        * the LLD. When the driver is finished processing the command
+        * the done callback is invoked.
+        *
+        * This is called to inform the LLD to transfer
+        * scsi_bufflen(cmd) bytes. scsi_sg_count(cmd) speciefies the
+        * number of scatterlist entried in the command and
+        * scsi_sglist(cmd) returns the scatterlist.
+        *
+        * return values: see queuecommand
+        *
+        * If the LLD accepts the cmd, it should set the result to an
+        * appropriate value when completed before calling the done function.
+        *
+        * STATUS: REQUIRED FOR TARGET DRIVERS
+        */
+       /* TODO: rename */
+       int (* transfer_response)(struct scsi_cmnd *,
+                                 void (*done)(struct scsi_cmnd *));
+
+       /*
         * This is an error handling strategy routine.  You don't need to
         * define one of these if you don't want to - there is a default
         * routine that is present that should work in most cases.  For those
@@ -138,27 +170,13 @@ struct scsi_host_template {
         *
         * Status: REQUIRED     (at least one of them)
         */
-       int (* eh_strategy_handler)(struct Scsi_Host *);
        int (* eh_abort_handler)(struct scsi_cmnd *);
        int (* eh_device_reset_handler)(struct scsi_cmnd *);
+       int (* eh_target_reset_handler)(struct scsi_cmnd *);
        int (* eh_bus_reset_handler)(struct scsi_cmnd *);
        int (* eh_host_reset_handler)(struct scsi_cmnd *);
 
        /*
-        * This is an optional routine to notify the host that the scsi
-        * timer just fired.  The returns tell the timer routine what to
-        * do about this:
-        *
-        * EH_HANDLED:          I fixed the error, please complete the command
-        * EH_RESET_TIMER:      I need more time, reset the timer and
-        *                      begin counting again
-        * EH_NOT_HANDLED       Begin normal error recovery
-        *
-        * Status: OPTIONAL
-        */
-       enum scsi_eh_timer_return (* eh_timed_out)(struct scsi_cmnd *);
-
-       /*
         * Before the mid layer attempts to scan for a new device where none
         * currently exists, it will call this entry in your driver.  Should
         * your driver need to allocate any structs or perform any other init
@@ -253,35 +271,59 @@ struct scsi_host_template {
        void (* target_destroy)(struct scsi_target *);
 
        /*
-        * fill in this function to allow the queue depth of this host
-        * to be changeable (on a per device basis).  returns either
+        * If a host has the ability to discover targets on its own instead
+        * of scanning the entire bus, it can fill in this function and
+        * call scsi_scan_host().  This function will be called periodically
+        * until it returns 1 with the scsi_host and the elapsed time of
+        * the scan in jiffies.
+        *
+        * Status: OPTIONAL
+        */
+       int (* scan_finished)(struct Scsi_Host *, unsigned long);
+
+       /*
+        * If the host wants to be called before the scan starts, but
+        * after the midlayer has set up ready for the scan, it can fill
+        * in this function.
+        *
+        * Status: OPTIONAL
+        */
+       void (* scan_start)(struct Scsi_Host *);
+
+       /*
+        * Fill in this function to allow the queue depth of this host
+        * to be changeable (on a per device basis).  Returns either
         * the current queue depth setting (may be different from what
         * was passed in) or an error.  An error should only be
         * returned if the requested depth is legal but the driver was
         * unable to set it.  If the requested depth is illegal, the
         * driver should set and return the closest legal queue depth.
         *
+        * Status: OPTIONAL
         */
        int (* change_queue_depth)(struct scsi_device *, int);
 
        /*
-        * fill in this function to allow the changing of tag types
+        * Fill in this function to allow the changing of tag types
         * (this also allows the enabling/disabling of tag command
         * queueing).  An error should only be returned if something
         * went wrong in the driver while trying to set the tag type.
         * If the driver doesn't support the requested tag type, then
         * it should set the closest type it does support without
         * returning an error.  Returns the actual tag type set.
+        *
+        * Status: OPTIONAL
         */
        int (* change_queue_type)(struct scsi_device *, int);
 
        /*
-        * This function determines the bios parameters for a given
+        * This function determines the BIOS parameters for a given
         * harddisk.  These tend to be numbers that are made up by
         * the host adapter.  Parameters:
         * size, device, list (heads, sectors, cylinders)
         *
-        * Status: OPTIONAL */
+        * Status: OPTIONAL
+        */
        int (* bios_param)(struct scsi_device *, struct block_device *,
                        sector_t, int []);
 
@@ -295,9 +337,22 @@ struct scsi_host_template {
        int (*proc_info)(struct Scsi_Host *, char *, char **, off_t, int, int);
 
        /*
+        * This is an optional routine that allows the transport to become
+        * involved when a scsi io timer fires. The return value tells the
+        * timer routine how to finish the io timeout handling:
+        * EH_HANDLED:          I fixed the error, please complete the command
+        * EH_RESET_TIMER:      I need more time, reset the timer and
+        *                      begin counting again
+        * EH_NOT_HANDLED       Begin normal error recovery
+        *
+        * Status: OPTIONAL
+        */
+       enum scsi_eh_timer_return (* eh_timed_out)(struct scsi_cmnd *);
+
+       /*
         * Name of proc directory
         */
-       char *proc_name;
+       const char *proc_name;
 
        /*
         * Used to store the procfs directory if a driver implements the
@@ -307,7 +362,7 @@ struct scsi_host_template {
 
        /*
         * This determines if we will use a non-interrupt driven
-        * or an interrupt driven scheme,  It is set to the maximum number
+        * or an interrupt driven scheme.  It is set to the maximum number
         * of simultaneous commands a given host adapter will accept.
         */
        int can_queue;
@@ -328,12 +383,12 @@ struct scsi_host_template {
        unsigned short sg_tablesize;
 
        /*
-        * If the host adapter has limitations beside segment count
+        * Set this if the host adapter has limitations beside segment count.
         */
        unsigned short max_sectors;
 
        /*
-        * dma scatter gather segment boundary limit. a segment crossing this
+        * DMA scatter gather segment boundary limit. A segment crossing this
         * boundary will be split in two.
         */
        unsigned long dma_boundary;
@@ -342,7 +397,7 @@ struct scsi_host_template {
         * This specifies "machine infinity" for host templates which don't
         * limit the transfer size.  Note this limit represents an absolute
         * maximum, and may be over the transfer limits allowed for
-        * individual devices (e.g. 256 for SCSI-1)
+        * individual devices (e.g. 256 for SCSI-1).
         */
 #define SCSI_DEFAULT_MAX_SECTORS       1024
 
@@ -364,12 +419,17 @@ struct scsi_host_template {
        unsigned char present;
 
        /*
-        * true if this host adapter uses unchecked DMA onto an ISA bus.
+        * This specifies the mode that a LLD supports.
+        */
+       unsigned supported_mode:2;
+
+       /*
+        * True if this host adapter uses unchecked DMA onto an ISA bus.
         */
        unsigned unchecked_isa_dma:1;
 
        /*
-        * true if this host adapter can make good use of clustering.
+        * True if this host adapter can make good use of clustering.
         * I originally thought that if the tablesize was large that it
         * was a waste of CPU cycles to prepare a cluster list, but
         * it works out that the Buslogic is faster if you use a smaller
@@ -379,7 +439,7 @@ struct scsi_host_template {
        unsigned use_clustering:1;
 
        /*
-        * True for emulated SCSI host adapters (e.g. ATAPI)
+        * True for emulated SCSI host adapters (e.g. ATAPI).
         */
        unsigned emulated:1;
 
@@ -389,13 +449,12 @@ struct scsi_host_template {
        unsigned skip_settle_delay:1;
 
        /*
-        * ordered write support
+        * True if we are using ordered write support.
         */
-       unsigned ordered_flush:1;
        unsigned ordered_tag:1;
 
        /*
-        * Countdown for host blocking with no commands outstanding
+        * Countdown for host blocking with no commands outstanding.
         */
        unsigned int max_host_blocked;
 
@@ -411,7 +470,7 @@ struct scsi_host_template {
        /*
         * Pointer to the sysfs class properties for this host, NULL terminated.
         */
-       struct class_device_attribute **shost_attrs;
+       struct device_attribute **shost_attrs;
 
        /*
         * Pointer to the SCSI device properties for this host, NULL terminated.
@@ -439,6 +498,8 @@ enum scsi_host_state {
        SHOST_CANCEL,
        SHOST_DEL,
        SHOST_RECOVERY,
+       SHOST_CANCEL_RECOVERY,
+       SHOST_DEL_RECOVERY,
 };
 
 struct Scsi_Host {
@@ -461,29 +522,32 @@ struct Scsi_Host {
        spinlock_t              default_lock;
        spinlock_t              *host_lock;
 
-       struct semaphore        scan_mutex;/* serialize scanning activity */
+       struct mutex            scan_mutex;/* serialize scanning activity */
 
        struct list_head        eh_cmd_q;
        struct task_struct    * ehandler;  /* Error recovery thread. */
-       struct semaphore      * eh_wait;   /* The error recovery thread waits
-                                             on this. */
-       struct semaphore      * eh_action; /* Wait for specific actions on the
-                                          host. */
-       unsigned int            eh_active:1; /* Indicates the eh thread is awake and active if
-                                          this is true. */
+       struct completion     * eh_action; /* Wait for specific actions on the
+                                             host. */
        wait_queue_head_t       host_wait;
        struct scsi_host_template *hostt;
        struct scsi_transport_template *transportt;
 
        /*
+        * Area to keep a shared tag map (if needed, will be
+        * NULL if not).
+        */
+       struct blk_queue_tag    *bqt;
+
+       /*
         * The following two fields are protected with host_lock;
         * however, eh routines can safely access during eh processing
         * without acquiring the lock.
         */
        unsigned int host_busy;            /* commands actually active on low-level */
        unsigned int host_failed;          /* commands that failed. */
+       unsigned int host_eh_scheduled;    /* EH scheduled without command */
     
-       unsigned short host_no;  /* Used for IOCTL_GET_IDLUN, /proc/scsi et al. */
+       unsigned int host_no;  /* Used for IOCTL_GET_IDLUN, /proc/scsi et al. */
        int resetting; /* if set, it means that last_reset is a valid value */
        unsigned long last_reset;
 
@@ -509,13 +573,11 @@ struct Scsi_Host {
        /*
         * The maximum length of SCSI commands that this host can accept.
         * Probably 12 for most host adapters, but could be 16 for others.
+        * or 260 if the driver supports variable length cdbs.
         * For drivers that don't set this field, a value of 12 is
-        * assumed.  I am leaving this as a number rather than a bit
-        * because you never know what subsequent SCSI standards might do
-        * (i.e. could there be a 20 byte or a 24-byte command a few years
-        * down the road?).  
+        * assumed.
         */
-       unsigned char max_cmd_len;
+       unsigned short max_cmd_len;
 
        int this_id;
        int can_queue;
@@ -527,8 +589,9 @@ struct Scsi_Host {
         * Used to assign serial numbers to the cmds.
         * Protected by the host lock.
         */
-       unsigned long cmd_serial_number, cmd_pid; 
+       unsigned long cmd_serial_number;
        
+       unsigned active_mode:2;
        unsigned unchecked_isa_dma:1;
        unsigned use_clustering:1;
        unsigned use_blk_tcq:1;
@@ -542,20 +605,25 @@ struct Scsi_Host {
        /*
         * Host uses correct SCSI ordering not PC ordering. The bit is
         * set for the minority of drivers whose authors actually read
-        * the spec ;)
+        * the spec ;).
         */
        unsigned reverse_ordering:1;
 
        /*
-        * ordered write support
+        * Ordered write support
         */
-       unsigned ordered_flush:1;
        unsigned ordered_tag:1;
 
+       /* Task mgmt function in progress */
+       unsigned tmf_in_progress:1;
+
+       /* Asynchronous scan in progress */
+       unsigned async_scan:1;
+
        /*
         * Optional work queue to be utilized by the transport
         */
-       char work_q_name[KOBJ_NAME_LEN];
+       char work_q_name[20];
        struct workqueue_struct *work_q;
 
        /*
@@ -568,6 +636,12 @@ struct Scsi_Host {
         */
        unsigned int max_host_blocked;
 
+       /*
+        * q used for scsi_tgt msgs, async events or any other requests that
+        * need to be processed in userspace
+        */
+       struct request_queue *uspace_req_q;
+
        /* legacy crap */
        unsigned long base;
        unsigned long io_port;
@@ -579,8 +653,7 @@ struct Scsi_Host {
        enum scsi_host_state shost_state;
 
        /* ldm bits */
-       struct device           shost_gendev;
-       struct class_device     shost_classdev;
+       struct device           shost_gendev, shost_dev;
 
        /*
         * List of hosts per template.
@@ -607,7 +680,15 @@ struct Scsi_Host {
 };
 
 #define                class_to_shost(d)       \
-       container_of(d, struct Scsi_Host, shost_classdev)
+       container_of(d, struct Scsi_Host, shost_dev)
+
+#define shost_printk(prefix, shost, fmt, a...) \
+       dev_printk(prefix, &(shost)->shost_gendev, fmt, ##a)
+
+static inline void *shost_priv(struct Scsi_Host *shost)
+{
+       return (void *)shost->hostdata;
+}
 
 int scsi_is_host_device(const struct device *);
 
@@ -621,14 +702,20 @@ static inline struct Scsi_Host *dev_to_shost(struct device *dev)
        return container_of(dev, struct Scsi_Host, shost_gendev);
 }
 
+static inline int scsi_host_in_recovery(struct Scsi_Host *shost)
+{
+       return shost->shost_state == SHOST_RECOVERY ||
+               shost->shost_state == SHOST_CANCEL_RECOVERY ||
+               shost->shost_state == SHOST_DEL_RECOVERY ||
+               shost->tmf_in_progress;
+}
+
 extern int scsi_queue_work(struct Scsi_Host *, struct work_struct *);
 extern void scsi_flush_work(struct Scsi_Host *);
 
 extern struct Scsi_Host *scsi_host_alloc(struct scsi_host_template *, int);
 extern int __must_check scsi_add_host(struct Scsi_Host *, struct device *);
 extern void scsi_scan_host(struct Scsi_Host *);
-extern void scsi_scan_single_target(struct Scsi_Host *, unsigned int,
-       unsigned int);
 extern void scsi_rescan_device(struct device *);
 extern void scsi_remove_host(struct Scsi_Host *);
 extern struct Scsi_Host *scsi_host_get(struct Scsi_Host *);
@@ -638,11 +725,6 @@ extern const char *scsi_host_state_name(enum scsi_host_state);
 
 extern u64 scsi_calculate_bounce_limit(struct Scsi_Host *);
 
-static inline void scsi_assign_lock(struct Scsi_Host *shost, spinlock_t *lock)
-{
-       shost->host_lock = lock;
-}
-
 static inline struct device *scsi_get_device(struct Scsi_Host *shost)
 {
         return shost->shost_gendev.parent;
@@ -661,6 +743,9 @@ extern void scsi_unblock_requests(struct Scsi_Host *);
 extern void scsi_block_requests(struct Scsi_Host *);
 
 struct class_container;
+
+extern struct request_queue *__scsi_alloc_queue(struct Scsi_Host *shost,
+                                               void (*) (struct request_queue *));
 /*
  * These two functions are used to allocate and free a pseudo device
  * which will connect to the host adapter itself rather than any