[SCSI] fix for fc transport recursion problem.
[safe/jmp/linux-2.6] / include / scsi / scsi_transport_fc.h
index 70ad163..394f14a 100644 (file)
@@ -28,6 +28,8 @@
 #define SCSI_TRANSPORT_FC_H
 
 #include <linux/config.h>
+#include <linux/sched.h>
+#include <scsi/scsi.h>
 
 struct scsi_transport_template;
 
@@ -77,6 +79,7 @@ enum fc_port_state {
        FC_PORTSTATE_LINKDOWN,
        FC_PORTSTATE_ERROR,
        FC_PORTSTATE_LOOPBACK,
+       FC_PORTSTATE_DELETED,
 };
 
 
@@ -103,8 +106,8 @@ enum fc_port_state {
                                             incapable of reporting */
 #define FC_PORTSPEED_1GBIT             1
 #define FC_PORTSPEED_2GBIT             2
-#define FC_PORTSPEED_10GBIT            4
-#define FC_PORTSPEED_4GBIT             8
+#define FC_PORTSPEED_4GBIT             4
+#define FC_PORTSPEED_10GBIT            8
 #define FC_PORTSPEED_NOT_NEGOTIATED    (1 << 15) /* Speed not established */
 
 /*
@@ -323,8 +326,14 @@ struct fc_host_attrs {
        struct list_head rport_bindings;
        u32 next_rport_number;
        u32 next_target_id;
+       u8 flags;
+       struct work_struct rport_del_work;
 };
 
+/* values for struct fc_host_attrs "flags" field: */
+#define FC_SHOST_RPORT_DEL_SCHEDULED   0x01
+
+
 #define fc_host_node_name(x) \
        (((struct fc_host_attrs *)(x)->shost_data)->node_name)
 #define fc_host_port_name(x)   \
@@ -363,6 +372,10 @@ struct fc_host_attrs {
        (((struct fc_host_attrs *)(x)->shost_data)->next_rport_number)
 #define fc_host_next_target_id(x) \
        (((struct fc_host_attrs *)(x)->shost_data)->next_target_id)
+#define fc_host_flags(x) \
+       (((struct fc_host_attrs *)(x)->shost_data)->flags)
+#define fc_host_rport_del_work(x) \
+       (((struct fc_host_attrs *)(x)->shost_data)->rport_del_work)
 
 
 /* The functions by which the transport class and the driver communicate */
@@ -384,6 +397,8 @@ struct fc_function_template {
        struct fc_host_statistics * (*get_fc_host_stats)(struct Scsi_Host *);
        void    (*reset_fc_host_stats)(struct Scsi_Host *);
 
+       int     (*issue_fc_host_lip)(struct Scsi_Host *);
+
        /* allocation lengths for host-specific data */
        u32                             dd_fcrport_size;
 
@@ -427,6 +442,34 @@ struct fc_function_template {
 };
 
 
+/**
+ * fc_remote_port_chkready - called to validate the remote port state
+ *   prior to initiating io to the port.
+ *
+ * Returns a scsi result code that can be returned by the LLDD.
+ *
+ * @rport:     remote port to be checked
+ **/
+static inline int
+fc_remote_port_chkready(struct fc_rport *rport)
+{
+       int result;
+
+       switch (rport->port_state) {
+       case FC_PORTSTATE_ONLINE:
+               result = 0;
+               break;
+       case FC_PORTSTATE_BLOCKED:
+               result = DID_BUS_BUSY << 16;
+               break;
+       default:
+               result = DID_NO_CONNECT << 16;
+               break;
+       }
+       return result;
+}
+
+
 struct scsi_transport_template *fc_attach_transport(
                        struct fc_function_template *);
 void fc_release_transport(struct scsi_transport_template *);
@@ -435,8 +478,14 @@ struct fc_rport *fc_remote_port_add(struct Scsi_Host *shost,
                        int channel, struct fc_rport_identifiers  *ids);
 void fc_remote_port_delete(struct fc_rport  *rport);
 void fc_remote_port_rolechg(struct fc_rport  *rport, u32 roles);
-int fc_remote_port_block(struct fc_rport *rport);
-void fc_remote_port_unblock(struct fc_rport *rport);
 int scsi_is_fc_rport(const struct device *);
 
+static inline u64 wwn_to_u64(u8 *wwn)
+{
+       return (u64)wwn[0] << 56 | (u64)wwn[1] << 48 |
+           (u64)wwn[2] << 40 | (u64)wwn[3] << 32 |
+           (u64)wwn[4] << 24 | (u64)wwn[5] << 16 |
+           (u64)wwn[6] <<  8 | (u64)wwn[7];
+}
+
 #endif /* SCSI_TRANSPORT_FC_H */