fedora core 6 1.2949 + vserver 2.2.0
[linux-2.6.git] / drivers / s390 / cio / css.h
index b834e6a..3464c5b 100644 (file)
@@ -1,11 +1,14 @@
 #ifndef _CSS_H
 #define _CSS_H
 
+#include <linux/mutex.h>
 #include <linux/wait.h>
 #include <linux/workqueue.h>
 
 #include <asm/cio.h>
 
+#include "schid.h"
+
 /*
  * path grouping stuff
  */
@@ -33,19 +36,25 @@ struct path_state {
        __u8  resvd  : 3;       /* reserved */
 } __attribute__ ((packed));
 
+struct extended_cssid {
+       u8 version;
+       u8 cssid;
+} __attribute__ ((packed));
+
 struct pgid {
        union {
                __u8 fc;        /* SPID function code */
                struct path_state ps;   /* SNID path state */
-       } inf;
-       __u32 cpu_addr  : 16;   /* CPU address */
+       } __attribute__ ((packed)) inf;
+       union {
+               __u32 cpu_addr  : 16;   /* CPU address */
+               struct extended_cssid ext_cssid;
+       } __attribute__ ((packed)) pgid_high;
        __u32 cpu_id    : 24;   /* CPU identification */
        __u32 cpu_model : 16;   /* CPU model */
        __u32 tod_high;         /* high word TOD clock */
 } __attribute__ ((packed));
 
-extern struct pgid global_pgid;
-
 #define MAX_CIWS 8
 
 /*
@@ -64,10 +73,13 @@ struct senseid {
 }  __attribute__ ((packed,aligned(4)));
 
 struct ccw_device_private {
+       struct ccw_device *cdev;
+       struct subchannel *sch;
        int state;              /* device state */
        atomic_t onoff;
-       __u16 devno;            /* device number */
-       __u16 irq;              /* subchannel number */
+       unsigned long registered;
+       struct ccw_dev_id dev_id;       /* device id */
+       struct subchannel_id schid;     /* subchannel number */
        __u8 imask;             /* lpm mask for SNID/SID/SPGID */
        int iretry;             /* retry counter SNID/SID/SPGID */
        struct {
@@ -83,12 +95,14 @@ struct ccw_device_private {
                unsigned int doverify:1;    /* delayed path verification */
                unsigned int donotify:1;    /* call notify function */
                unsigned int recog_done:1;  /* dev. recog. complete */
+               unsigned int fake_irb:1;    /* deliver faked irb */
+               unsigned int intretry:1;    /* retry internal operation */
        } __attribute__((packed)) flags;
        unsigned long intparm;  /* user interruption parameter */
        struct qdio_irq *qdio_data;
        struct irb irb;         /* device status */
        struct senseid senseid; /* SenseID info */
-       struct pgid pgid;       /* path group ID */
+       struct pgid pgid[8];    /* path group IDs per chpid*/
        struct ccw1 iccws[2];   /* ccws for SNID/SID/SPGID commands */
        struct work_struct kick_work;
        wait_queue_head_t wait_q;
@@ -104,6 +118,7 @@ struct ccw_device_private {
  * Currently, we only care about I/O subchannels (type 0), these
  * have a ccw_device connected to them.
  */
+struct subchannel;
 struct css_driver {
        unsigned int subchannel_type;
        struct device_driver drv;
@@ -111,6 +126,9 @@ struct css_driver {
        int (*notify)(struct device *, int);
        void (*verify)(struct device *);
        void (*termination)(struct device *);
+       int (*probe)(struct subchannel *);
+       int (*remove)(struct subchannel *);
+       void (*shutdown)(struct subchannel *);
 };
 
 /*
@@ -119,15 +137,36 @@ struct css_driver {
 extern struct bus_type css_bus_type;
 extern struct css_driver io_subchannel_driver;
 
-int css_probe_device(int irq);
-extern struct subchannel * get_subchannel_by_schid(int irq);
-extern unsigned int highest_subchannel;
+extern int css_probe_device(struct subchannel_id);
+extern int css_sch_device_register(struct subchannel *);
+extern void css_sch_device_unregister(struct subchannel *);
+extern struct subchannel * get_subchannel_by_schid(struct subchannel_id);
 extern int css_init_done;
-
-#define __MAX_SUBCHANNELS 65536
+extern int for_each_subchannel(int(*fn)(struct subchannel_id, void *), void *);
+
+#define __MAX_SUBCHANNEL 65535
+#define __MAX_SSID 3
+#define __MAX_CHPID 255
+#define __MAX_CSSID 0
+
+struct channel_subsystem {
+       u8 cssid;
+       int valid;
+       struct channel_path *chps[__MAX_CHPID + 1];
+       struct device device;
+       struct pgid global_pgid;
+       struct mutex mutex;
+       /* channel measurement related */
+       int cm_enabled;
+       void *cub_addr1;
+       void *cub_addr2;
+       /* for orphaned ccw devices */
+       struct subchannel *pseudo_subchannel;
+};
+#define to_css(dev) container_of(dev, struct channel_subsystem, device)
 
 extern struct bus_type css_bus_type;
-extern struct device css_bus_device;
+extern struct channel_subsystem *css[];
 
 /* Some helper functions for disconnected state. */
 int device_is_disconnected(struct subchannel *);
@@ -135,15 +174,26 @@ void device_set_disconnected(struct subchannel *);
 void device_trigger_reprobe(struct subchannel *);
 
 /* Helper functions for vary on/off. */
-void device_set_waiting(struct subchannel *);
+int device_is_online(struct subchannel *);
+void device_kill_io(struct subchannel *);
+void device_set_intretry(struct subchannel *sch);
+int device_trigger_verify(struct subchannel *sch);
+
+/* Machine check helper function. */
+void device_kill_pending_timer(struct subchannel *);
 
 /* Helper functions to build lists for the slow path. */
-int css_enqueue_subchannel_slow(unsigned long schid);
+extern int css_enqueue_subchannel_slow(struct subchannel_id schid);
 void css_walk_subchannel_slow_list(void (*fn)(unsigned long));
 void css_clear_subchannel_slow_list(void);
 int css_slow_subchannels_exist(void);
 extern int need_rescan;
 
+int sch_is_pseudo_sch(struct subchannel *);
+
 extern struct workqueue_struct *slow_path_wq;
 extern struct work_struct slow_path_work;
+
+int subchannel_add_files (struct device *);
+extern struct attribute_group *subch_attr_groups[];
 #endif