[SCSI] libsas: fix try_test_sas_gpio_gp_bit() build error
[linux-2.6.git] / include / scsi / libsas.h
index 8d91313..d455fa9 100644 (file)
 #include <linux/timer.h>
 #include <linux/pci.h>
 #include <scsi/sas.h>
+#include <linux/libata.h>
 #include <linux/list.h>
-#include <asm/semaphore.h>
 #include <scsi/scsi_device.h>
 #include <scsi/scsi_cmnd.h>
 #include <scsi/scsi_transport_sas.h>
+#include <linux/scatterlist.h>
+#include <linux/slab.h>
 
 struct block_device;
 
@@ -89,8 +91,6 @@ enum discover_event {
 
 /* ---------- Expander Devices ---------- */
 
-#define ETASK 0xFA
-
 #define to_dom_device(_obj) container_of(_obj, struct domain_device, dev_obj)
 #define to_dev_attr(_attr)  container_of(_attr, struct domain_dev_attribute,\
                                          attr)
@@ -120,8 +120,8 @@ struct ex_phy {
        u8   attached_sata_dev:1;
        u8   attached_sata_ps:1;
 
-       enum sas_proto attached_tproto;
-       enum sas_proto attached_iproto;
+       enum sas_protocol attached_tproto;
+       enum sas_protocol attached_iproto;
 
        u8   attached_sas_addr[SAS_ADDR_SIZE];
        u8   attached_phy_id;
@@ -142,8 +142,11 @@ struct expander_device {
        u16    ex_change_count;
        u16    max_route_indexes;
        u8     num_phys;
+
+       u8     t2t_supp:1;
        u8     configuring:1;
        u8     conf_route_table:1;
+
        u8     enclosure_logical_id[8];
 
        struct ex_phy *ex_phy;
@@ -164,6 +167,13 @@ struct sata_device {
 
         u8     port_no;        /* port number, if this is a PM (Port) */
         struct list_head children; /* PM Ports if this is a PM */
+
+       struct ata_port *ap;
+       struct ata_host ata_host;
+       struct ata_taskfile tf;
+       u32 sstatus;
+       u32 serror;
+       u32 scontrol;
 };
 
 /* ---------- Domain device ---------- */
@@ -182,8 +192,8 @@ struct domain_device {
 
         struct list_head dev_list_node;
 
-        enum sas_proto    iproto;
-        enum sas_proto    tproto;
+        enum sas_protocol    iproto;
+        enum sas_protocol    tproto;
 
         struct sas_rphy *rphy;
 
@@ -198,11 +208,17 @@ struct domain_device {
         };
 
         void *lldd_dev;
+       int gone;
+};
+
+struct sas_discovery_event {
+       struct work_struct work;
+       struct asd_sas_port *port;
 };
 
 struct sas_discovery {
        spinlock_t disc_event_lock;
-       struct work_struct disc_work[DISC_NUM_EVENTS];
+       struct sas_discovery_event disc_work[DISC_NUM_EVENTS];
        unsigned long    pending;
        u8     fanout_sas_addr[8];
        u8     eeds_a[8];
@@ -231,8 +247,8 @@ struct asd_sas_port {
        enum sas_class   class;
        u8               sas_addr[SAS_ADDR_SIZE];
        u8               attached_sas_addr[SAS_ADDR_SIZE];
-       enum sas_proto   iproto;
-       enum sas_proto   tproto;
+       enum sas_protocol   iproto;
+       enum sas_protocol   tproto;
 
        enum sas_oob_mode oob_mode;
 
@@ -248,14 +264,19 @@ struct asd_sas_port {
        void *lldd_port;          /* not touched by the sas class code */
 };
 
+struct asd_sas_event {
+       struct work_struct work;
+       struct asd_sas_phy *phy;
+};
+
 /* The phy pretty much is controlled by the LLDD.
  * The class only reads those fields.
  */
 struct asd_sas_phy {
 /* private: */
        /* protected by ha->event_lock */
-       struct work_struct   port_events[PORT_NUM_EVENTS];
-       struct work_struct   phy_events[PHY_NUM_EVENTS];
+       struct asd_sas_event   port_events[PORT_NUM_EVENTS];
+       struct asd_sas_event   phy_events[PHY_NUM_EVENTS];
 
        unsigned long port_events_pending;
        unsigned long phy_events_pending;
@@ -270,8 +291,8 @@ struct asd_sas_phy {
 
        int            id;        /* must be set */
        enum sas_class class;
-       enum sas_proto iproto;
-       enum sas_proto tproto;
+       enum sas_protocol iproto;
+       enum sas_protocol tproto;
 
        enum sas_phy_type  type;
        enum sas_phy_role  role;
@@ -303,21 +324,33 @@ struct scsi_core {
        struct list_head  task_queue;
        int               task_queue_size;
 
-       struct semaphore  queue_thread_sema;
-       int               queue_thread_kill;
+       struct task_struct *queue_thread;
+};
+
+struct sas_ha_event {
+       struct work_struct work;
+       struct sas_ha_struct *ha;
+};
+
+enum sas_ha_state {
+       SAS_HA_REGISTERED,
+       SAS_HA_UNREGISTERED
 };
 
 struct sas_ha_struct {
 /* private: */
        spinlock_t       event_lock;
-       struct work_struct ha_events[HA_NUM_EVENTS];
+       struct sas_ha_event ha_events[HA_NUM_EVENTS];
        unsigned long    pending;
 
+       enum sas_ha_state state;
+       spinlock_t        state_lock;
+
        struct scsi_core core;
 
 /* public: */
        char *sas_ha_name;
-       struct pci_dev *pcidev;   /* should be set */
+       struct device *dev;       /* should be set */
        struct module *lldd_module; /* should be set */
 
        u8 *sas_addr;             /* must be set */
@@ -331,6 +364,8 @@ struct sas_ha_struct {
        /* The class calls this to send a task for execution. */
        int lldd_max_execute_num;
        int lldd_queue_size;
+       int strict_wide_ports; /* both sas_addr and attached_sas_addr must match
+                               * their siblings when forming wide ports */
 
        /* LLDD calls these to notify the class of an event. */
        void (*notify_ha_event)(struct sas_ha_struct *, enum ha_event);
@@ -338,6 +373,8 @@ struct sas_ha_struct {
        void (*notify_phy_event)(struct asd_sas_phy *, enum phy_event);
 
        void *lldd_ha;            /* not touched by sas class code */
+
+       struct list_head eh_done_q;
 };
 
 #define SHOST_TO_SAS_HA(_shost) (*(struct sas_ha_struct **)(_shost)->hostdata)
@@ -371,6 +408,20 @@ static inline void sas_phy_disconnected(struct asd_sas_phy *phy)
        phy->linkrate = SAS_LINK_RATE_UNKNOWN;
 }
 
+static inline unsigned int to_sas_gpio_od(int device, int bit)
+{
+       return 3 * device + bit;
+}
+
+#ifdef CONFIG_SCSI_SAS_HOST_SMP
+int try_test_sas_gpio_gp_bit(unsigned int od, u8 *data, u8 index, u8 count);
+#else
+static inline int try_test_sas_gpio_gp_bit(unsigned int od, u8 *data, u8 index, u8 count)
+{
+       return -1;
+}
+#endif
+
 /* ---------- Tasks ---------- */
 /*
       service_response |  SAS_TASK_COMPLETE  |  SAS_TASK_UNDELIVERED |
@@ -391,16 +442,7 @@ enum service_response {
 };
 
 enum exec_status {
-       SAM_GOOD         = 0,
-       SAM_CHECK_COND   = 2,
-       SAM_COND_MET     = 4,
-       SAM_BUSY         = 8,
-       SAM_INTERMEDIATE = 0x10,
-       SAM_IM_COND_MET  = 0x12,
-       SAM_RESV_CONFLICT= 0x14,
-       SAM_TASK_SET_FULL= 0x28,
-       SAM_ACA_ACTIVE   = 0x30,
-       SAM_TASK_ABORTED = 0x40,
+       /* The SAM_STAT_.. codes fit in the lower 6 bits */
 
        SAS_DEV_NO_RESPONSE = 0x80,
        SAS_DATA_UNDERRUN,
@@ -504,7 +546,7 @@ struct sas_task {
        spinlock_t   task_state_lock;
        unsigned     task_state_flags;
 
-       enum   sas_proto      task_proto;
+       enum   sas_protocol      task_proto;
 
        /* Used by the discovery code. */
        struct timer_list     timer;
@@ -526,39 +568,18 @@ struct sas_task {
 
        void   *lldd_task;        /* for use by LLDDs */
        void   *uldd_task;
-};
 
+       struct work_struct abort_work;
+};
 
+#define SAS_TASK_STATE_PENDING      1
+#define SAS_TASK_STATE_DONE         2
+#define SAS_TASK_STATE_ABORTED      4
+#define SAS_TASK_NEED_DEV_RESET     8
+#define SAS_TASK_AT_INITIATOR       16
 
-#define SAS_TASK_STATE_PENDING  1
-#define SAS_TASK_STATE_DONE     2
-#define SAS_TASK_STATE_ABORTED  4
-
-static inline struct sas_task *sas_alloc_task(unsigned long flags)
-{
-       extern kmem_cache_t *sas_task_cache;
-       struct sas_task *task = kmem_cache_alloc(sas_task_cache, flags);
-
-       if (task) {
-               memset(task, 0, sizeof(*task));
-               INIT_LIST_HEAD(&task->list);
-               spin_lock_init(&task->task_state_lock);
-               task->task_state_flags = SAS_TASK_STATE_PENDING;
-               init_timer(&task->timer);
-               init_completion(&task->completion);
-       }
-
-       return task;
-}
-
-static inline void sas_free_task(struct sas_task *task)
-{
-       if (task) {
-               extern kmem_cache_t *sas_task_cache;
-               BUG_ON(!list_empty(&task->list));
-               kmem_cache_free(sas_task_cache, task);
-       }
-}
+extern struct sas_task *sas_alloc_task(gfp_t flags);
+extern void sas_free_task(struct sas_task *task);
 
 struct sas_domain_function_template {
        /* The class calls these to notify the LLDD of an event. */
@@ -570,7 +591,7 @@ struct sas_domain_function_template {
        void (*lldd_dev_gone)(struct domain_device *);
 
        int (*lldd_execute_task)(struct sas_task *, int num,
-                                unsigned long gfp_flags);
+                                gfp_t gfp_flags);
 
        /* Task Management Functions. Must be called from process context. */
        int (*lldd_abort_task)(struct sas_task *);
@@ -578,6 +599,7 @@ struct sas_domain_function_template {
        int (*lldd_clear_aca)(struct domain_device *, u8 *lun);
        int (*lldd_clear_task_set)(struct domain_device *, u8 *lun);
        int (*lldd_I_T_nexus_reset)(struct domain_device *);
+       int (*lldd_ata_soft_reset)(struct domain_device *);
        int (*lldd_lu_reset)(struct domain_device *, u8 *lun);
        int (*lldd_query_task)(struct sas_task *);
 
@@ -586,19 +608,28 @@ struct sas_domain_function_template {
        int (*lldd_clear_nexus_ha)(struct sas_ha_struct *);
 
        /* Phy management */
-       int (*lldd_control_phy)(struct asd_sas_phy *, enum phy_func);
+       int (*lldd_control_phy)(struct asd_sas_phy *, enum phy_func, void *);
+
+       /* GPIO support */
+       int (*lldd_write_gpio)(struct sas_ha_struct *, u8 reg_type,
+                              u8 reg_index, u8 reg_count, u8 *write_data);
 };
 
 extern int sas_register_ha(struct sas_ha_struct *);
 extern int sas_unregister_ha(struct sas_ha_struct *);
 
-extern int sas_queuecommand(struct scsi_cmnd *,
-                    void (*scsi_done)(struct scsi_cmnd *));
+int sas_set_phy_speed(struct sas_phy *phy,
+                     struct sas_phy_linkrates *rates);
+int sas_phy_enable(struct sas_phy *phy, int enabled);
+int sas_phy_reset(struct sas_phy *phy, int hard_reset);
+int sas_queue_up(struct sas_task *task);
+extern int sas_queuecommand(struct Scsi_Host * ,struct scsi_cmnd *);
 extern int sas_target_alloc(struct scsi_target *);
 extern int sas_slave_alloc(struct scsi_device *);
 extern int sas_slave_configure(struct scsi_device *);
 extern void sas_slave_destroy(struct scsi_device *);
-extern int sas_change_queue_depth(struct scsi_device *, int new_depth);
+extern int sas_change_queue_depth(struct scsi_device *, int new_depth,
+                                 int reason);
 extern int sas_change_queue_type(struct scsi_device *, int qt);
 extern int sas_bios_param(struct scsi_device *,
                          struct block_device *,
@@ -624,4 +655,22 @@ void sas_unregister_dev(struct domain_device *);
 
 void sas_init_dev(struct domain_device *);
 
+void sas_task_abort(struct sas_task *);
+int __sas_task_abort(struct sas_task *);
+int sas_eh_device_reset_handler(struct scsi_cmnd *cmd);
+int sas_eh_bus_reset_handler(struct scsi_cmnd *cmd);
+
+extern void sas_target_destroy(struct scsi_target *);
+extern int sas_slave_alloc(struct scsi_device *);
+extern int sas_ioctl(struct scsi_device *sdev, int cmd, void __user *arg);
+
+extern int sas_smp_handler(struct Scsi_Host *shost, struct sas_rphy *rphy,
+                          struct request *req);
+
+extern void sas_ssp_task_response(struct device *dev, struct sas_task *task,
+                                 struct ssp_response_iu *iu);
+struct sas_phy *sas_find_local_phy(struct domain_device *dev);
+
+int sas_request_addr(struct Scsi_Host *shost, u8 *addr);
+
 #endif /* _SASLIB_H_ */